Cesar
Cesar

Reputation: 5488

How to properly test for constraint violation in hibernate?

I'm trying to test Hibernate mappings, specifically a unique constraint. My POJO is mapped as follows:

<property name="name" type="string" unique="true" not-null="true" />

What I want to do is to test that I can't persist two entities with the same name:

public class ExpertiseAreaDAOTest{
    private ExpertiseAreaDAO ead;
    static Connection c;
    private static SessionFactory sessionFactory;

    static {
        Configuration config = new Configuration().configure("resources/exp/hibernate-test.cfg.xml");
        sessionFactory = config.buildSessionFactory();
    }

    @Test(expected=ConstraintViolationException.class)
    public void testPersistTwoExpertiseAreasWithTheSameNameIsNotAllowed(){
        ExpertiseArea ea = new ExpertiseArea("Design");
        ExpertiseArea otherEA = new ExpertiseArea("Design");

        ead.setSession(getSessionFactory().getCurrentSession());
        ead.getSession().beginTransaction();
        ead.makePersistent(ea);
        ead.makePersistent(otherEA);
        ead.getSession().getTransaction().commit(); 
    }

    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }
}
//Other methods ommited

On commiting the current transaction, I can see in the logs that a ConstraintViolationException is thrown:

16:08:47,571 DEBUG SQL:111 - insert into ExpertiseArea (VERSION, name, id) values (?, ?, ?)
Hibernate: insert into ExpertiseArea (VERSION, name, id) values (?, ?, ?)
16:08:47,571 DEBUG SQL:111 - insert into ExpertiseArea (VERSION, name, id) values (?, ?, ?)
Hibernate: insert into ExpertiseArea (VERSION, name, id) values (?, ?, ?)
16:08:47,572  WARN JDBCExceptionReporter:100 - SQL Error: -104, SQLState: 23505
16:08:47,572 ERROR JDBCExceptionReporter:101 - integrity constraint violation: unique constraint or index violation; SYS_CT_10036 table: EXPERTISEAREA
16:08:47,573 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

So I would expect the test to pass, since the expected ConstraintViolationException is thrown. However, the test never completes (neither pass nor fails) and I have to manually kill the test runner.

What's the correct way to test this?

Upvotes: 1

Views: 3125

Answers (1)

Binil Thomas
Binil Thomas

Reputation: 13779

Shouldn't you run the creates in two transactions, expecting the first one to succeed and the second to fail?

public void testPersistTwoExpertiseAreasWithTheSameNameIsNotAllowed(){
    ExpertiseArea ea = new ExpertiseArea("Design");
    ExpertiseArea otherEA = new ExpertiseArea("Design");

    SessionFactory sf = getSessionFactory();
    Session session = sf.openSession();
    Transaction txn = session.beginTransaction();
    try {
        ead.setSession(session);
        ead.makePersistent(ea);
        // no ExpertiseArea by this name in DB, this should commit
        txn.commit(); 
    } catch (HibernateException ex) {
        txn.rollback();
        fail("Unexpected exception " + ex);
    } finally {
        session.close();
        ead.setSession(null);
    }
    session = sf.openSession();
    txn = session.beginTransaction();
    try {
        ead.setSession(session);
        ead.makePersistent(otherEA);
        // this should fail 'cos there is already an ExpertiseArea with
        // the same name in DB
        txn.commit();
        fail("Expected constraint violation exception");
    } finally {
        session.close();
        ead.setSession(null);
    }
}

Upvotes: 2

Related Questions