DBUnit Sybase unable to CLEAN_INSERT

2019-05-26 16:05发布

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

2条回答
女痞
2楼-- · 2019-05-26 16:17

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;
    }
查看更多
beautiful°
3楼-- · 2019-05-26 16:35

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.

查看更多
登录 后发表回答