Reputation: 5488
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
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