Reset sequence in DBUnit?
Asked Answered
H

3

8

I want to reset the Database AND sequences after each test in Java+DBUnit/.

I've seen this question but doesn't have the code solution I am struggling to get. How to use Oracle Sequence Numbers in DBUnit?

Holguin answered 16/12, 2013 at 9:47 Comment(2)
What database are you using ?Richellericher
I am multidatabase, so I have to support Oracle, Posgres and Derby.Holguin
H
12

I've found the answer, it was in the Official Documentation. It was as easy as in the dataset you are using to prepare the database, add a reset_sequences attribute with a list of the ones you want to reset.

 <?xml version='1.0' encoding='UTF-8'?>
    <dataset reset_sequences="emp_seq, dept_seq">
        <emp empno="1" ename="Scott" deptno="10" job="project manager" />
        ....
    </dataset>

This solution is not working perfectly, as it didn't really reset the sequence, only simulates the reset on the inserted rows. If you want to effectively reset it, you should execute some commands. I've extended the DatabaseOperation for that purpose with this class.

public static final DatabaseOperation SEQUENCE_RESETTER_POSTGRES = new DatabaseOperation() {
    @Override
    public void execute(IDatabaseConnection connection, IDataSet dataSet)
            throws DatabaseUnitException, SQLException {
        String[] tables = dataSet.getTableNames();
        Statement statement = connection.getConnection().createStatement();
        for (String table : tables) {
            int startWith = dataSet.getTable(table).getRowCount() + 1;
            statement.execute("alter sequence " + table + "_PK_SEQ RESTART WITH "+ startWith);

        }
    }
};

public static final DatabaseOperation SEQUENCE_RESETTER_ORACLE = new DatabaseOperation() {
    @Override
    public void execute(IDatabaseConnection connection, IDataSet dataSet)
            throws DatabaseUnitException, SQLException {
        String[] tables = dataSet.getTableNames();
        Statement statement = connection.getConnection().createStatement();
        for (String table : tables) {
            int startWith = dataSet.getTable(table).getRowCount() + 1;
            statement.execute("drop sequence " + table + "_PK_SEQ if exists");
            statement.execute("create sequence " + table + "_PK_SEQ START WITH " + startWith);
        }
    }
};
Holguin answered 16/12, 2013 at 10:31 Comment(0)
C
4

I've tested the solution provided by @Chexpir, and here is an improved/cleaner way (PostgreSQL implementation) - Also note that the sequence is reset to 1 (instead of retrieving the row count)

public class ResetSequenceOperationDecorator extends DatabaseOperation {

    private DatabaseOperation decoree;

    public ResetSequenceOperationDecorator(DatabaseOperation decoree) {
         this.decoree = decoree;
     }

     @Override
     public void execute(IDatabaseConnection connection, IDataSet dataSet) throws DatabaseUnitException, SQLException {
         String[] tables = dataSet.getTableNames();
         Statement statement = connection.getConnection().createStatement();
         for (String table : tables) {
             try {
                 statement.execute("ALTER SEQUENCE " + table + "_id_seq RESTART WITH 1");
             }
             // Don't care because the sequence does not appear to exist (but catch it silently)
             catch(SQLException ex) {
             }
         }
         decoree.execute(connection, dataSet);
     }
}

And in your DatabaseTestCase:

public abstract class AbstractDBTestCase extends DataSourceBasedDBTestCase {

    @Override
    protected DatabaseOperation getTearDownOperation() throws Exception {
        return new ResetSequenceOperationDecorator(DatabaseOperation.DELETE_ALL);
    }
}
Calces answered 29/1, 2015 at 13:34 Comment(0)
R
0

Can you please check the below link if anyway it helps you.

How to revert the database back to the initial state using dbUnit?

Richellericher answered 16/12, 2013 at 10:22 Comment(1)
Thank you, but using CLEAN_INSERT wasn't helping me, the answer I've put is the good one :-)Holguin

© 2022 - 2024 — McMap. All rights reserved.