I get a org.hibernate.exception.ConstraintViolationException in an integration test.
I have two tables, one is contact_referer and another one is contact.
The contact has an external key pointing to the primary key of contact_referer.
If a contact_referer is being used by a contact then the contact_referer should not be deletable.
And indeed it is not deletable.
I would like to check for this correct behavior in an integration test.
And so I came up with the following test:
Code:
@Test
public void testDelete() {
contactReferer0 = contactRefererDao.saveOrUpdate(contactReferer0);
contactReferer1 = contactRefererDao.saveOrUpdate(contactReferer1);
long count = contactRefererDao.countAllRows();
assertEquals(2, count);
contactRefererDao.delete(contactReferer0);
count = contactRefererDao.countAllRows();
assertEquals(1, count);
contact = new Contact();
contact.setEmail("email");
contact.setMessage("message");
DateTime contactDateTime = new DateTime();
contact.setContactDateTime(contactDateTime);
contact.setContactReferer(contactReferer1);
contact = contactDao.saveOrUpdate(contact);
try {
contactRefererDao.delete(contactReferer1);
fail(); // line 69
} catch (ConstraintViolationException e) {
}
count = contactRefererDao.countAllRows(); // line 72
assertEquals(1, count);
contact.setContactReferer(null);
contactRefererDao.delete(contactReferer1);
count = contactRefererDao.countAllRows();
assertEquals(0, count);
}
But the fail() is executed as the test gives the following exception:
Code:
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 7.694 sec <<< FAILURE!
testDelete(com.thalasoft.learnintouch.core.dao.ContactRefererDaoTest) Time elapsed: 0.189 sec <<< FAILURE!
java.lang.AssertionError:
at org.junit.Assert.fail(Assert.java:74)
at org.junit.Assert.fail(Assert.java:81)
at com.thalasoft.learnintouch.core.dao.ContactRefererDaoTest.testDelete(ContactRefererDaoTest.java:69)
with the line 69 being the line:
Code:
fail();
You can also see some comments in the code with the line numbers.
And so, I commented out the fail() statement, and got the following exception:
Quote:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 7.581 sec <<< FAILURE!
testDelete(com.thalasoft.learnintouch.core.dao.ContactRefererDaoTest) Time elapsed: 0.215 sec <<< ERROR!
org.hibernate.exception.ConstraintViolationException: could not delete: [com.thalasoft.learnintouch.core.domain.ContactReferer#203]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2536)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2692)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:77)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:172)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:41)
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:970)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1563)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
at com.thalasoft.learnintouch.core.dao.hibernate.GenericHibernateDao.countAllRows(GenericHibernateDao.java:88)
at com.thalasoft.learnintouch.core.dao.ContactRefererDaoTest.testDelete(ContactRefererDaoTest.java:72)
As you can see, it seems like the statement
Code:
count = contactRefererDao.countAllRows();
right after the try catch block, triggers the delete.
So I tried to trigger the delete sooner, that is, in the try block, with a flush() statement as in
Code:
try {
contactRefererDao.delete(contactReferer1);
contactRefererDao.getSession().flush();
fail();
} catch (ConstraintViolationException e) {
}
But it still gives me the same exception:
Quote:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 7.476 sec <<< FAILURE!
testDelete(com.thalasoft.learnintouch.core.dao.ContactRefererDaoTest) Time elapsed: 0.246 sec <<< ERROR!
org.hibernate.exception.ConstraintViolationException: could not delete: [com.thalasoft.learnintouch.core.domain.ContactReferer#205]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2536)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2692)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:77)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:172)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:41)
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:970)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1563)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
at com.thalasoft.learnintouch.core.dao.hibernate.GenericHibernateDao.countAllRows(GenericHibernateDao.java:88)
at com.thalasoft.learnintouch.core.dao.ContactRefererDaoTest.testDelete(ContactRefererDaoTest.java:73)
with the line 73 still being the line:
Code:
count = contactRefererDao.countAllRows();
And so, I decided to have that line in the try block, right after the delete, to see if it would trigger the delete, as the flush seemed not to do it, and had a test that looked like:
Code:
@Test
public void testDelete() {
contactReferer0 = contactRefererDao.saveOrUpdate(contactReferer0);
contactReferer1 = contactRefererDao.saveOrUpdate(contactReferer1);
long count = contactRefererDao.countAllRows();
assertEquals(2, count);
contactRefererDao.delete(contactReferer0);
count = contactRefererDao.countAllRows();
assertEquals(1, count);
contact = new Contact();
contact.setEmail("email");
contact.setMessage("message");
DateTime contactDateTime = new DateTime();
contact.setContactDateTime(contactDateTime);
contact.setContactReferer(contactReferer1);
contact = contactDao.saveOrUpdate(contact);
try {
contactRefererDao.delete(contactReferer1);
count = contactRefererDao.countAllRows();
fail();
} catch (ConstraintViolationException e) {
}
count = contactRefererDao.countAllRows();
assertEquals(1, count);
contact.setContactReferer(null);
contactRefererDao.delete(contactReferer1);
count = contactRefererDao.countAllRows();
assertEquals(0, count);
}
But it still gives me the exception:
Quote:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 7.674 sec <<< FAILURE!
testDelete(com.thalasoft.learnintouch.core.dao.ContactRefererDaoTest) Time elapsed: 0.21 sec <<< ERROR!
org.hibernate.exception.ConstraintViolationException: could not delete: [com.thalasoft.learnintouch.core.domain.ContactReferer#207]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2536)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2692)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:77)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:172)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:41)
at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:970)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1563)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
at com.thalasoft.learnintouch.core.dao.hibernate.GenericHibernateDao.countAllRows(GenericHibernateDao.java:88)
at com.thalasoft.learnintouch.core.dao.ContactRefererDaoTest.testDelete(ContactRefererDaoTest.java:73)
Why is it that the exception does not show the line 69, the one containing the statement
Code:
count = contactRefererDao.countAllRows();
in the try block, instead of the same statement after the catch block ?
I guess there is something that escapes me here..
Any clue ?