Hallo,
ich habe ein Entity Benutzer, welches eine Eigenschaft "cookie" besitzen soll. Das Feld "cookie" soll jedoch immer in Kleinbuchstaben in die Datenbank gespeichert werden. Um dies sauber zu kapseln und später um es später wieder verwenden zu können, will ich dies in eine Klasse auslagern.
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;
}
}
Speichere ich nun das Entity ab, ohne dem Feld "cookie" einen Wert zuzuweisen, funktioniert es.
Code:
@Test
public void thisWorks() {
USER = new User(EMAIL, FIRSTNAME, LASTNAME);
daoUnderTest.save(USER);
}
Wie gesagt, funktioniert:
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]]]
Wenn ich nun dem Feld "cookie" einen Wert zuweise, dann generiert Hibernate kein INSERT mehr, sondern ein UPDATE. Hinweis: Die Datenbank ist leer und es wird em.save(entitiy) aufgerufen.
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
*/
Hat jemand eine Idee?
Gruß, johbar