Hello all together,
I have a Java class Person, which has a list of addresses.
In the hbm-file for the person, I added a generated id, which is the primary key for this table.
Every address for the person should have a primary key, which is composition of the id of the person and a per user incremented number.
On save the given exception occurs.
The only constraint regarding to the modulation is that the address table should contain a composite key containing of the id of the person and a incremented number per Person.
The incremented number should be generated by hibernate. I tried using a generator, but failed.
Any help is welcome.
Hibernate version:
hibernate-core: 3.3.1-GA
Mapping documents:
Code:
<hibernate-mapping>
<class name="testproject.Person" table="person">
<id name="personId" column="personId">
<generator class="identity" />
</id>
<list name="addresses" table="address" cascade="all-delete-orphan" inverse="true" >
<key column="personId" />
<index column="incNumber" />
<one-to-many class="testproject.Address" />
</list>
<property name="name" type="string">
<column name="name" length="45" />
</property>
</class>
</hibernate-mapping>
Code:
<hibernate-mapping>
<class name="testproject.Address" table="address">
<composite-id>
<key-property name="personId" access="field"/>
<key-property name="incNumber" column="incNumber" />
</composite-id>
<property name="street" type="string">
<column name="street" length="45" />
</property>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
Person p1 = new Person("Person1");
Person p2 = new Person("Person2");
p2.addAddress(new Address("Street Number 1"));
p1.addAddress(new Address("Street Number 2"));
Serializable id1 = session.save(p1);
Serializable id2 = session.save(p2);
Full stack trace of any exception that occurs:Code:
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeInserts(ActionQueue.java:158)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:268)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:562)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:550)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:546)
at testproject.DBPersonTest.testSaveLoadPerson(DBPersonTest.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
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.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
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.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: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`minipilot_test/address`, CONSTRAINT `FKBB979BF4E8B5E82C` FOREIGN KEY (`personId`) REFERENCES `person` (`personId`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1666)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1082)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 38 more
The generated SQL (show_sql=true):Code:
Hibernate: insert into person (name) values (?)
Hibernate: select address_.personId, address_.incNumber, address_.street from address address_ where address_.personId=? and address_.incNumber=? and address_.street=?
Hibernate: insert into address (personId, incNumber, street) values (?, ?, ?)