DBUnit Sybase 无法 CLEAN_INSERT

发布于 2024-12-17 09:38:22 字数 1638 浏览 0 评论 0原文

根据DBUnit文档链接,它应该支持在使用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

According to the DBUnit docs link it should support using a CLEAN_INSERT when using a DatabaseSequenceFilter.

I get the following exception when attempting this

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'.

My tables look like this:

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)

And my DBUnit dataset looks like this:

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

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

So within my test class where I have this code I get the error if data already exists in the database and it cannot be removed because of the foreign key constraints

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

Interestingly a work around is to use REFRESH instead of CLEAN_INSERT but this is less than ideal because junk data could reside in the database causing side effects:

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

Has anyone been able to get this CLEAN_INSERT to work with Sybase and foreign keys? From reading other posts similar issues exist for MySQL so maybe there is a common issue here (or me not understanding something)

[EDIT]

I have now added my own workaround answer after running into the same problem again.

I am using Sybase ASE 15 + DBUnit 2.4.8

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘿哥们儿 2024-12-24 09:38:23

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

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

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

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

I have come to the conclusion that this is indeed a problem with Sybase + DBUnit after hitting the same issues on another project (although I am using the same JAR file versions and database server).

The workaround I finally settled on was the following

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

The caveat is that the TRUNCATE will obviously blow away all data in the database tables when the test runs, but this is something I can live with. At least I know for certain what data is in the database and my tests are less likely to fail due to erroneous records being inserted by other developers running in between test executions. Probably a good reason why you want a dedicated database for unit + integration tests.

℡寂寞咖啡 2024-12-24 09:38:23

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

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

    }

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

Simply use INSERT Operation for inserting Values through XML or DataSet. The XML or inserting script should insert the data in order i.e parent first and then child, use DELETE_ALL Operation for Deleting the Tables in reverse order.

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

    }

    protected DatabaseOperation getTearDownOperation() throws Exception
    {  
        return DatabaseOperation.DELETE_ALL;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文