DbUnitのMavenプラグインの実行中に発生した外部キー制約違反エラーを解決する方法
UbUnitを使用したユニットテストで発生した場合
この問題は、DbUnitのMavenプラグインでデータベースを操作する場合だけでなく、DbUnitベースのユニットテストでも発生します.一般的な処理方法は、接続を取得するたびに「set@@session.foreign_key_checks=0」のstatementを実行して、外部キー制約チェックを行わないことを保証します.以下は、DbUnitベースのユニットテストベースクラスです.59行目は、外部キー制約チェックの禁止に関する設定です.(注:この例で使用するデータベースはMySql)
DbUnitのMavenプラグインを使用している場合
また、MavenのDbUnitプラグインを使用して、コマンドラインでデータインポート作業を行う場合は、データベース接続のurlからしか手がつけられません.方法も簡単ですが、元のプラグインの構成にforeign_を追加することですkey_checks=0という変数は、以下の例で、14行目タグの部分:${jdbc.url}&sessionVariables=foreign_key_checks=0 は、標準urlの後に変数foreign_を追加します.key_checksの設定.
コメント:
mysqlでは、変数の役割ドメインには2つのsessionとglobalがあり、変数値を変更する方法は次のとおりです.
GLOBAL変数の値を設定するには、次の構文を使用します.
mysql> SET GLOBAL sort_buffer_size=value;mysql> SET @@global.sort_buffer_size=value;
SESSION変数の値を設定するには、次の構文を使用します.
mysql> SET SESSION sort_buffer_size=value;mysql> SET @@session.sort_buffer_size=value;mysql> SET sort_buffer_size=value;
この問題は、DbUnitのMavenプラグインでデータベースを操作する場合だけでなく、DbUnitベースのユニットテストでも発生します.一般的な処理方法は、接続を取得するたびに「set@@session.foreign_key_checks=0」のstatementを実行して、外部キー制約チェックを行わないことを保証します.以下は、DbUnitベースのユニットテストベースクラスです.59行目は、外部キー制約チェックの禁止に関する設定です.(注:この例で使用するデータベースはMySql)
package oobbs.domainmodel;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.dbunit.DataSourceDatabaseTester;
import org.dbunit.DefaultOperationListener;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.xml.XmlDataSet;
import org.dbunit.ext.mysql.MySqlDataTypeFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import testutil.ApplicationContextSupport;
/**
* This base class does not extends any DBTestCase of dbunit,or use any Tester,Their's implement is not good and flexible.
* Here,we prepare and set connection manully!
*
* @author Laurence Geng
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/applicationContext-infrastructure.xml",
"classpath:/applicationContext-domainModel.xml",
"classpath:/applicationContext-test.xml"})
public abstract class DbBasedTest{
/** The data source. */
@Autowired
protected DataSource dataSource;
/** The dbunitTestUtil can fill test data from xml into test db before testing. */
protected DataSourceDatabaseTester dbunitTestUtil;
/**
* Inits dbunitTestUtil.
* The connectionRetrieved method is called back when setUp() executes.
* At this time,we should set connection-specific setting: set foreign key check disabled
* so as dbunit can invert test data, and set data type factory be MySqlDataTypeFactory so as
* dbunit can convert correct type when invert data to mysql.
*
* @throws Exception the exception
*/
protected void initDbunitTestUtil() throws Exception{
dbunitTestUtil = new DataSourceDatabaseTester(dataSource);
dbunitTestUtil.setDataSet(new XmlDataSet(new ClassPathResource("dbunit-test-data.xml").getInputStream()));
dbunitTestUtil.setOperationListener( new DefaultOperationListener(){
public void connectionRetrieved(IDatabaseConnection connection) {
try {
//Disable foreign key check!
connection.getConnection().prepareStatement("set @@session.foreign_key_checks = 0").execute();
// When a new connection has been created then invoke the setUp method
// so that user defined DatabaseConfig parameters can be set.
connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory());
} catch (SQLException e) {
e.printStackTrace();
}
}});
}
/**
* Before test method.
*
* @throws Exception the exception
*/
@Before
public void beforeTestMethod() throws Exception {
initDbunitTestUtil();
dbunitTestUtil.onSetup();
}
/**
* After test method.
*
* @throws Exception the exception
*/
@After
public void afterTestMethod() throws Exception {
dbunitTestUtil.onTearDown();
}
}
DbUnitのMavenプラグインを使用している場合
また、MavenのDbUnitプラグインを使用して、コマンドラインでデータインポート作業を行う場合は、データベース接続のurlからしか手がつけられません.方法も簡単ですが、元のプラグインの構成にforeign_を追加することですkey_checks=0という変数は、以下の例で、14行目
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>dbunit-maven-plugin</artifactId>
<version>1.0-beta-3</version>
<dependencies>
<dependency>
<groupId>${jdbc.groupId}</groupId>
<artifactId>${jdbc.artifactId}</artifactId>
<version>${jdbc.version}</version>
</dependency>
</dependencies>
<configuration>
<driver>${jdbc.driverClassName}</driver>
<url>${jdbc.url}&sessionVariables=foreign_key_checks=0</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
</configuration>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>operation</goal>
</goals>
<configuration>
<type>CLEAN_INSERT</type>
<src>src/test/resources/dbunit-test-data.xml</src>
<dataTypeFactoryName>org.dbunit.ext.mysql.MySqlDataTypeFactory</dataTypeFactoryName>
<transaction>true</transaction>
</configuration>
</execution>
</executions>
</plugin>
コメント:
mysqlでは、変数の役割ドメインには2つのsessionとglobalがあり、変数値を変更する方法は次のとおりです.
GLOBAL変数の値を設定するには、次の構文を使用します.
mysql> SET GLOBAL sort_buffer_size=value;mysql> SET @@global.sort_buffer_size=value;
SESSION変数の値を設定するには、次の構文を使用します.
mysql> SET SESSION sort_buffer_size=value;mysql> SET @@session.sort_buffer_size=value;mysql> SET sort_buffer_size=value;