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?
Shouldn’t you run the creates in two transactions, expecting the first one to succeed and the second to fail?