2010-04-21 16 views
9

मैं डेटा परत एकीकरण परीक्षण के लिए एचएसक्यूएलडीबी का उपयोग कर रहा हूं, जो कि बढ़िया है। हालांकि, मुझे लगता है कि मेरी विदेशी कुंजी बाधाएं मेरे परीक्षणों के रास्ते में हो रही हैं। उदाहरण के लिए, एक टेबल पर एक साधारण चयन का परीक्षण करने के लिए, मुझे डमी डेटा को पांच अतिरिक्त तालिकाओं में डालना होगा। यह मुझे चीजों को फेंकना चाहता है।एचएसक्यूएलडीबी के साथ टीडीडी - विदेशी कुंजी को हटाने

मेरे पास हमारे मॉडल कोड में जेपीए एनोटेशन हैं, और कॉन्फ़िगरेशन में स्कीमा (hbm2ddl.create-drop) को फिर से बनाने के लिए हाइबरनेट को कॉन्फ़िगर किया है। तालिकाओं को उत्पन्न होने पर विदेशी कुंजी बाधाओं के रूप में जोड़ों का सही ढंग से व्याख्या किया जा रहा है।

  1. नहीं विदेशी कुंजी शुरू में बनाने (आदर्श, साफ), या
  2. एक तरह से प्रोग्राम के रूप में डेटाबेस में सभी विदेशी कुंजी ड्रॉप करने का पता लगाएं (थोड़े:

    मैं चाहता क्या या तो करने के लिए है हैकी लेकिन काम पूरा हो जाएगा)

यदि यह सहायक है, तो मैं इन परीक्षणों को स्वचालित करने के लिए वसंत का उपयोग कर रहा हूं। प्रश्न में परीक्षण AbstractTransactionalJUnit4SpringContextTests से प्राप्त होते हैं।

आपको क्या लगता है? क्या यह किया जा सकता है?

उत्तर

8

आप नीचे दिए गए निर्देश के साथ FK बाधाओं को निष्क्रिय कर सकते हैं:

SET REFERENTIAL_INTEGRITY FALSE; 

आप एक JDBC Statement के माध्यम से इसे अमल कर सकता है आपके परीक्षण तरीकों से पहले (और इसे वापस सेट TRUE के बाद)।

+1

धन्यवाद !!! आप सिर्फ मेरी टेस्ट क्लास को आधा हाथ में कटौती करते हैं। दिलचस्प बात यह भी रूट करना आसान बनाता है जहां हाइबरनेट अनावश्यक आंतरिक जुड़ता है। । ' – roufamatic

+0

AbstractTransactionalJUnit4SpringContextTests ... का उपयोग कर किसी के लिए जादू इस है। – roufamatic

+0

@roufamatic खुशी है कि आप इसे उपयोगी पाते; ' simpleJdbcTemplate.getJdbcOperations() पर अमल ("REFERENTIAL_INTEGRITY गलत पर सेट है,"): –

0

मैं कुछ फिक्स्चर बनाने पर कुछ समय बिताने पर विचार करता हूं, संभवतः डीबीयूनीट के साथ, जिसे आप @ पहले कहते हैं।

Btw, AbstractTransactionalJUnit4Test वसंत में हटा दिया गया है 3.0

+0

पुन: पदावनत ... मैं "AbstractTransactionalJUnit4SpringContextTests" जो मैं ऊपर ठीक किया था। एफडब्ल्यूआईडब्ल्यू हम वसंत 2.5 का उपयोग कर रहे हैं। – roufamatic

8

फ्लैट एक्सएमएल डेटासेट के साथ मेरे डीएओ का परीक्षण करने की कोशिश करते समय मुझे एक ही समस्या का सामना करना पड़ा। कॉन्फ़िग DBunit + HSQLDB 2.2.8 + JUnit4 + स्प्रिंग + JPA-> सब एक साथ

java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no parent; FK13EE6CE6F09A6AAC table: **** 

के लिए अग्रणी मैं एक श्रोता AbstractTestExecutionListener विस्तार को लागू करने से एक अच्छा वैकल्पिक हल मिल गया है। आप हमारे परीक्षण में, विदेशी कुंजी बाधाओं को अक्षम करने, प्रत्येक परीक्षण से पहले किए जाने वाले कार्यों के प्रकार को निर्दिष्ट करेंगे। नोट: सिंटैक्स एचएसक्यूएलडीबी के संस्करण के आधार पर भिन्न हो सकता है।

public class ForeignKeyDisabling extends AbstractTestExecutionListener {  
    @Override 
    public void beforeTestClass(TestContext testContext) throws Exception { 
     IDatabaseConnection dbConn = new DatabaseDataSourceConnection(
       testContext.getApplicationContext().getBean(DataSource.class) 
       ); 
     dbConn.getConnection().prepareStatement("SET DATABASE REFERENTIAL INTEGRITY FALSE").execute(); 

    } 
} 

फिर आप केवल इस श्रोता अपने परीक्षण में जगह में पहले से ही संग्रह में जोड़ने की जरूरत:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"applicationContext-test.xml"}) 
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DataSetTestExecutionListener.class, ForeignKeyDisabling.class}) 
+0

यह करने का एक शानदार तरीका है। – roufamatic

+1

क्या आप इसे "सेट डेटाबेस संदर्भित सत्य सत्य" के साथ प्रत्येक परीक्षण (डीबी स्थापित करने के बाद) की शुरुआत में वापस सेट नहीं करना चाहिए? – wannabeartist

+0

सेटअप में ऐसे कोड को सेट करना आपकी आवश्यकताओं को भी फिट कर सकता है। मेरे मामले में पूरा परीक्षण सूट इस संरचना संशोधन पर निर्भर था। लेकिन परिणाम वही होना चाहिए। –

0

क्या यह तेजी से:

SET REFERENTIAL_INTEGRITY FALSE; में import.sql फ़ाइल अपने परीक्षण संसाधन निर्देशिका में ।

समस्या तेजी से और अच्छी तरह से हल हो :)

यहाँ इस सूत्र में प्रेरणा पर कुछ जानकारी के बारे में import.sqlhttp://christopherlakey.com/articles/import-sql.html

1

बेस कर रहे हैं, मैं इस समस्या के लिए कुछ हद तक और अधिक मजबूत समाधान बना लिया है। मुद्दा यह था कि परीक्षण चलाने के दौरान मुझे वास्तव में बाधाएं पसंद हैं और अन्य सभी समाधानों ने इसे अक्षम रखा है। यह कोड उन्हें केवल डेटासेट आयात की अवधि के लिए अक्षम कर देगा और फिर उन्हें पुनः सक्षम करेगा। और आसानी से एक और डीबी इंजन का समर्थन करने के लिए बढ़ाया जा सकता:

import com.github.springtestdbunit.DbUnitTestExecutionListener; 
import org.apache.log4j.Logger; 
import org.dbunit.database.DatabaseDataSourceConnection; 
import org.dbunit.database.IDatabaseConnection; 
import org.springframework.test.context.TestContext; 

import javax.sql.DataSource; 
import java.sql.Connection; 
import java.sql.SQLException; 

/** 
* Class DisableForeignKeysDbUnitTestExecutionListener 
* Simple wrapper class around DbUnitTestExecutionListener, which - for the time of importing the database - 
* disables Foreign Key Constraints checks. 
* This class can be extended by simply overriding toggleForeignKeysConstraintsForDbEngine(Connection, String, boolean); 
* subclasses should always call super-implementation for default case. 
*/ 
public class DisableForeignKeysDbUnitTestExecutionListener 
    extends DbUnitTestExecutionListener 
{ 
    private static final Logger logger = Logger.getLogger(DisableForeignKeysDbUnitTestExecutionListener.class); 
    private Connection cachedDbConnection; 

    @Override 
    public void beforeTestMethod(TestContext testContext) 
     throws Exception 
    { 
     this.toggleForeignKeysConstraints(testContext, false); 
     super.beforeTestMethod(testContext); 
     this.toggleForeignKeysConstraints(testContext, true); 
    } 

    /** 
    * Method should perform query to disable foreign keys constraints or return false, 
    * if it is not able to perform such query (e.g. unknown database engine) 
    * 
    * @param connection Database connection 
    * @param dbProductName Name of the database product (as reported by connection metadata) 
    * @param enabled  Expected state of foreign keys after the call 
    * 
    * @return True, if there was suitable statement for specified engine, otherwise false 
    * 
    * @throws SQLException 
    */ 
    protected boolean toggleForeignKeysConstraintsForDbEngine(Connection connection, String dbProductName, boolean enabled) 
     throws SQLException 
    { 
     switch (dbProductName) 
     { 
      case "HSQL Database Engine": 
       connection.prepareStatement("SET DATABASE REFERENTIAL INTEGRITY " + (enabled ? "TRUE" : "FALSE")) 
          .execute(); 
       return (true); 
     } 
     return (false); 
    } 

    private void toggleForeignKeysConstraints(TestContext testContext, boolean enabled) 
    { 
     try 
     { 
      Connection connection = this.getDatabaseConnection(testContext); 
      String databaseProductName = connection.getMetaData().getDatabaseProductName(); 
      if (!this.toggleForeignKeysConstraintsForDbEngine(connection, databaseProductName, enabled)) 
      { 
       throw new IllegalStateException("Unknown database engine '" + databaseProductName + 
                "'. Unable to toggle foreign keys constraints."); 
      } 
     } 
     catch (Throwable throwable) 
     { 
      logger.error("Unable to toggle Foreign keys constraints: " + throwable.getLocalizedMessage()); 
     } 
    } 

    synchronized private Connection getDatabaseConnection(TestContext testContext) 
     throws SQLException 
    { 
     if (this.cachedDbConnection == null) 
     { 
      DataSource dataSource = testContext.getApplicationContext().getBean(DataSource.class); 
      if (dataSource == null) 
      { 
       throw new IllegalStateException("Unable to obtain DataSource from ApplicationContext. " + 
                "Foreign constraints will not be disabled."); 
      } 

      IDatabaseConnection dsConnection = new DatabaseDataSourceConnection(dataSource); 
      this.cachedDbConnection = dsConnection.getConnection(); 
     } 

     return (this.cachedDbConnection); 
    } 
} 
संबंधित मुद्दे