Question

I have a simple User class that has first name, last name and email I've marked the email like this

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

I'm 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();
}

I've 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 It 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.

Was it helpful?

Solution

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

OTHER TIPS

I had the same problem. Catching org.hibernate.exception.ConstraintViolationException would catch nothing, eventhough all tests failed because this exception had been thrown - at least that's what the IDE told at the first glance.

What helped me in my case was to catch javax.persistence.PersistenceException instead.

enter image description here

You're failing because you've told junit to expect a ConstraintViolationException and your the methods called in your test aren't throwing it. The test itself has some problems but the above is the reason it is failing ... look at the first line of the stacktrace.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top