【问题标题】:DBUnit Sybase unable to CLEAN_INSERTDBUnit Sybase 无法 CLEAN_INSERT
【发布时间】:2011-11-21 16:21:25
【问题描述】:

根据 DBUnit 文档 link,它应该支持在使用 DatabaseSequenceFilter 时使用 CLEAN_INSERT。

尝试此操作时出现以下异常

com.sybase.jdbc2.jdbc.SybSQLException: Dependent foreign key constraint violation in a referential integrity constraint. dbname =  'my_db', table name = 'tbl_child', constraint name = 'fk_tbl_child_parentid'.

我的表格如下所示:

CREATE TABLE dbo.tbl_parent
(
    parent_id            numeric(19,0) IDENTITY,
    ...
)

CREATE TABLE dbo.tbl_child
(
    child_id            numeric(19,0) IDENTITY,
    parent_id           numeric(19,0) NOT NULL,
    ...
)

ALTER TABLE dbo.tbl_child
    ADD CONSTRAINT fk_tbl_child_parentid
    FOREIGN KEY (parent_id)
    REFERENCES dbo.tbl_parent (parent_id)

我的 DBUnit 数据集如下所示:

<dataset>
  <tbl_parent parent_id="41" ... />

  <tbl_child child_id="1361" parent_id="41"/>
</dataset>

因此,在我有此代码的测试类中,如果数据已存在于数据库中并且由于外键约束而无法删除,则会出现错误

@Before 
public void setUp() throws Exception {
    InsertIdentityOperation.CLEAN_INSERT.execute(getConnection(), getDataSet());
}

有趣的是,一种解决方法是使用 REFRESH 而不是 CLEAN_INSERT,但这并不理想,因为垃圾数据可能驻留在数据库中,从而导致副作用:

@Before 
public void setUp() throws Exception {
    InsertIdentityOperation.REFRESH.execute(getConnection(), getDataSet());
}

有没有人能够让这个 CLEAN_INSERT 与 Sybase 和外键一起使用?从阅读其他帖子来看,MySQL 存在类似的问题,所以这里可能存在一个常见问题(或者我不明白)

[编辑]

在再次遇到相同问题后,我现在添加了自己的解决方法。

我正在使用 Sybase ASE 15 + DBUnit 2.4.8

【问题讨论】:

    标签: constraints sap-ase dbunit


    【解决方案1】:

    在另一个项目中遇到相同问题后,我得出的结论是,这确实是 Sybase + DBUnit 的问题(尽管我使用的是相同的 JAR 文件版本和数据库服务器)。

    我最终确定的解决方法如下

    @Before 
    public void setUp() throws Exception {
        InsertIdentityOperation.TRUNCATE_TABLE.execute(getConnection(), getDataSet());
        InsertIdentityOperation.INSERT.execute(getConnection(), getDataSet());
    }
    

    需要注意的是,当测试运行时,TRUNCATE 显然会清除数据库表中的所有数据,但这是我可以忍受的。至少我确定数据库中有哪些数据,并且我的测试不太可能由于在测试执行之间运行的其他开发人员插入错误记录而失败。可能是您想要一个用于单元 + 集成测试的专用数据库的一个很好的理由。

    【讨论】:

      【解决方案2】:

      只需使用INSERT 操作即可通过 XML 或 DataSet 插入值。 XML或插入脚本应按顺序插入数据,即先父后子,使用DELETE_ALL逆序删除表操作。

      protected DatabaseOperation getSetUpOperation() throws Exception
          {
              return DatabaseOperation.INSERT;
      
          }
      
          protected DatabaseOperation getTearDownOperation() throws Exception
          {  
              return DatabaseOperation.DELETE_ALL;
          }
      

      【讨论】:

      • 从我的问题的底部,我特别感兴趣的是是否有人能够让这个 CLEAN_INSERT 与 Sybase 和外键一起工作?。您的答案不涉及测试用例首次运行时数据库中存在垃圾数据的问题。如果尚未调用 DELETE_ALL 或其他进程在我的测试运行之间将数据插入表中,您的答案将发生这种情况。
      猜你喜欢
      • 2013-11-23
      • 2012-11-14
      • 1970-01-01
      • 2015-07-08
      • 1970-01-01
      • 2014-11-24
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      相关资源
      最近更新 更多