naoru naoru - 1 month ago 7
Java Question

Unable to pass junit test for uniqueConstraintException with hibernate

i have a simple User class that has first name, last name and email
ive marked the email like this

@Column(name="email",unique=true)
@NotNull
@Email
private String email;


im running the following junit test but its failing

@Test(expected = org.hibernate.exception.ConstraintViolationException.class)
public void testUniqueEmail() throws DaoException{
User uri = new User("uri","naor","a@b.com");
userDao.saveUser(uri);
//Session session = sessionFactory.getCurrentSession();
//session.save(uri);
//session.flush();
User clone = new User("clone","wars","a@b.com");
userDao.saveUser(clone);
//session.save(clone);
//session.flush();
}


ive tried using the userDao or using the session directly so i can flush
either way junit fails saying


java.lang.AssertionError: Expected exception: org.hibernate.exception.ConstraintViolationException
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:32)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:72)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:62)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3124)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3587)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:103)


how can i make this test pass

*EDIT
seems that my question was not very clear
my model has a field called email which is unique, so i expect that when i insert an object that has the same email, the DB should reject it.

to test it, i made a simple test that persist an object with email "a@b.com" and than created another object with the same email. the problem is with JUNIT as the test fails due to ConstraintViolationException as expected yet the test is RED

Answer

ok so i managed to pass the test here is the code snippet the key is to catch this exception, clear the session and then rethrow it

@Test(expected = org.hibernate.exception.ConstraintViolationException.class)  
public void testUniqueEmail() throws DaoException{
    User uri = new User("uri","naor","a@b.com");
    userDao.saveUser(uri);
    User clone = new User("clone","wars","a@b.com");
    userDao.saveUser(clone);
    try{
        sessionFactory.getCurrentSession().flush();
    }catch(org.hibernate.exception.ConstraintViolationException ex){
        sessionFactory.getCurrentSession().clear();
        SQLException ex1= new SQLException();
        throw new ConstraintViolationException("Could not insert",ex1,"what else");
    }
}

hope it helps somebody

Comments