Hi,
I've created an Entity 'User', which holds a property "cookie". "cookie" has to be stored in the database lowercase. I want to outsouce this functionality in a class "Data".
Code:
@Entity
@Table(name = "USERS")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq")
@SequenceGenerator(name = "user_id_seq", sequenceName = "user_id_seq")
private long id;
@Column(length = 50, nullable = false, unique = true)
private String email;
@Column(length = 50, nullable = false)
private String firstName;
@Column(length = 50, nullable = false)
private String lastName;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public User() {
}
public User(String email, String firstName, String lastName) {
this.email = email;
this.firstName = firstName;
this.lastName = lastName;
}
@Embeddable
public static class Data {
@Column(length = 50, unique = true)
private String data;
public Data(String data) {
setData(data);
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data.toLowerCase();
}
}
@Embedded
private Data cookie;
public Data getData() {
return cookie;
}
public void setData(Data cookie) {
this.cookie = cookie;
}
}
If I save the entity without assigning a value to "cookie" it works.
Code:
@Test
public void thisWorks() {
USER = new User(EMAIL, FIRSTNAME, LASTNAME);
daoUnderTest.save(USER);
}
Code:
2009-06-29 13:21:54,953 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - Running hbm2ddl schema export
2009-06-29 13:21:54,968 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - exporting generated schema to database
2009-06-29 13:21:54,984 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - schema export complete
2009-06-29 13:21:55,187 [main] INFO org.springframework.test.context.transaction.TransactionalTestExecutionListener - Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransactionManager@15c97e4]; rollback [true]
2009-06-29 13:21:55,187 [main] DEBUG org.hibernate.SQL - call next value for user_id_seq
2009-06-29 13:21:55,218 [main] DEBUG org.hibernate.SQL - insert into USERS (data, email, firstName, lastName, id) values (?, ?, ?, ?, ?)
2009-06-29 13:21:55,234 [main] INFO org.springframework.test.context.transaction.TransactionalTestExecutionListener - Rolled back transaction after test execution for test context [[TestContext@1be8711 testClass = UserDaoImplTestCase, locations = array<String>['classpath:applicationContext-test.xml', 'classpath:daoBeans.xml'], testInstance = com.bytekugel.bienenstock.model.dao.impl.UserDaoImplTestCase@1958cc2, testMethod = playground@UserDaoImplTestCase, testException = [null]]]
BUT if I set "cookie" to some data, something goes wrong. Hibernate is creating an UPDATE instead of an INSERT statemeant. I'm using Spring HibernateDaoSupport which calls em.save(entity)
Code:
@Test
public void problemHere() {
USER = new User(EMAIL, FIRSTNAME, LASTNAME);
USER.setData(new User.Data("joh"));
daoUnderTest.save(USER);
}
Code:
2009-06-29 13:23:55,718 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - Running hbm2ddl schema export
2009-06-29 13:23:55,718 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - exporting generated schema to database
2009-06-29 13:23:55,734 [main] INFO org.hibernate.tool.hbm2ddl.SchemaExport - schema export complete
2009-06-29 13:23:55,937 [main] INFO org.springframework.test.context.transaction.TransactionalTestExecutionListener - Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransactionManager@1478a2d]; rollback [true]
2009-06-29 13:23:55,937 [main] DEBUG org.hibernate.SQL - call next value for user_id_seq
2009-06-29 13:23:55,984 [main] DEBUG org.hibernate.SQL - update USERS set data=?, email=?, firstName=?, lastName=? where id=?
2009-06-29 13:23:55,984 [main] ERROR org.hibernate.jdbc.AbstractBatcher - Exception executing batch:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject.flush(HibernateTransactionManager.java:891)
at org.springframework.transaction.support.DefaultTransactionStatus.flush(DefaultTransactionStatus.java:165)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:501)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:277)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:170)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:364)
at org.springframework.test.context.junit4.statements.RunSpringTestContextAfters.evaluate(RunSpringTestContextAfters.java:90)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:210)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
2009-06-29 13:23:55,984 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject.flush(HibernateTransactionManager.java:891)
at org.springframework.transaction.support.DefaultTransactionStatus.flush(DefaultTransactionStatus.java:165)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:501)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:277)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:170)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:364)
at org.springframework.test.context.junit4.statements.RunSpringTestContextAfters.evaluate(RunSpringTestContextAfters.java:90)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:210)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
2009-06-29 13:23:55,984 [main] WARN org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@c1a0eb] to process 'after' execution for test: method [public void com.bytekugel.bienenstock.model.dao.impl.UserDaoImplTestCase.playground()], instance [com.bytekugel.bienenstock.model.dao.impl.UserDaoImplTestCase@2bccb2], exception [org.springframework.orm.hibernate3.HibernateSystemException: No default constructor for entity: com.bytekugel.bienenstock.model.User$Data; nested exception is org.hibernate.InstantiationException: No default constructor for entity: com.bytekugel.bienenstock.model.User$Data]
org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:670)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
at org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject.flush(HibernateTransactionManager.java:894)
at org.springframework.transaction.support.DefaultTransactionStatus.flush(DefaultTransactionStatus.java:165)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:501)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:277)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:170)
at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:364)
at org.springframework.test.context.junit4.statements.RunSpringTestContextAfters.evaluate(RunSpringTestContextAfters.java:90)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:210)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject.flush(HibernateTransactionManager.java:891)
... 22 more
Environment:
Spring: 2.5.6
Hibernate: 3.3.1.GA
Hibernate-Annotations: 3.4.0.GA
Any ideas?
Thanks, johbar