DbUnit无法清理插入:外键约束

时间:2014-09-30 10:14:15

标签: java mysql jpa testng dbunit

我正在询问并回答这个问题以供将来参考,因为我认为我找到了一个解决DbUnit常见问题的合适解决方案。我希望它可以帮助某个人,在某个地方。

我正在使用DbUnit 2.5.0TestNG 6.8.8。我的用例是包含3个实体的数据库的一部分。有一个ServiceUser,其中包含AdministrableUserGroup的外键。

我关注了http://city81.blogspot.com/2011/03/testing-jpa-entities-using-dbunit.html

中的大部分代码示例
public abstract class AbstractDatabaseTest {
    protected EntityManager em; // initialized elsewhere
    private IDatabaseConnection connection;
    private IDataSet dataset;

    @BeforeClass
    private void setupDatabaseResource() throws Exception {
        // using Hibernate
        connection = new DatabaseConnection(((SessionImpl) (em.getDelegate())).connection());
        connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory());

        // full database export
        IDataSet fullDataSet = connection.createDataSet();

        final String datasetPath = String.format("%s%s", RESOURCE_FOLDER, "Testing.xml");
        FlatXmlDataSet.write(fullDataSet, new FileOutputStream(datasetPath));

        FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder();
        flatXmlDataSetBuilder.setColumnSensing(true);
        dataset = flatXmlDataSetBuilder.build(new FileInputStream(datasetPath));
    }

    @AfterMethod
    public void cleanDB() throws Exception {
        em.getTransaction().begin();
        DatabaseOperation.CLEAN_INSERT.execute(connection, dataset);
        em.getTransaction().commit();
    }
}

结果如下XMLDataSet(数据省略):

<dataset>
  <administrable/>
  <serviceuser/>
  <usergroup/>
</dataset>

TestNG执行@AfterMethod时,我会收到以下异常:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException
Cannot delete or update a parent row: a foreign key constraint fails (`testing_db`.`serviceuser`, CONSTRAINT `FK_gyylcfbhpl2ukqs5rm7sq0uy8` FOREIGN KEY (`userGroup_id`) REFERENCES `usergroup` (`id`))

1 个答案:

答案 0 :(得分:12)

问题是我在上面创建的XMLDataSet不知道表中的外键约束,并按字母顺序创建表列表。但是,CLEAN_INSERT操作获取表的列表并以相反的顺序遍历它,并且它要求在引用的实体之前删除外键引用(此处:ServiceUser.userGroup_id)(此处:{{1 }})。

我通过Unitils doesn't workhttp://forum.spring.io/forum/spring-projects/data/12868-dbunit-test-fails-mysql-server-hates-me?p=337672#post337672

找到了这些信息

对DbUnit文档的一些细微挖掘导致了一种创建数据集的更正方法,该方法检查外键依赖关系并尝试正确地对实体进行排序:

UserGroup

结果:

IDataSet fullDataSet = new FilteredDataSet(new DatabaseSequenceFilter(connection), connection.createDataSet());

这将<dataset> <administrable/> <usergroup/> <serviceuser/> </dataset> 正确。

免责声明:我没有遇到循环依赖或自引用外键,我还没有测试过此修复可以处理它们。