Dear Readers,
I am trying to get what should be a simple association working. I have a parent class that has a set of children. I am using an existing schema that correctly models this with a FK in the child table. I want to save a new parent and a new child in one transaction and have the FK set correctly. I've tried and tried but can't get it to work, either get StaleStateExceptions or the FK remains 0.
Here's the parent SQL table:
Code:
mysql> describe TravelTimeSegment;
+------------------+---------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------------------+------+-----+---------------------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| ARSEServerNodeId | bigint(20) unsigned | NO | MUL | NULL | |
| listenPort | int(10) unsigned | NO | | NULL | |
| minZoomLevel | int(10) unsigned | NO | | NULL | |
| maxZoomLevel | int(10) unsigned | NO | | NULL | |
| labelOffsetX | int(11) | NO | | NULL | |
| labelOffsetY | int(11) | NO | | NULL | |
| classification | varchar(32) | NO | | NULL | |
| segmentName | varchar(64) | NO | | NULL | |
| isDead | tinyint(3) unsigned | NO | | NULL | |
| modifyTime | timestamp | NO | | 0000-00-00 00:00:00 | |
+------------------+---------------------+------+-----+---------------------+----------------+
Here's the child table:
Code:
+---------------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| travelTimeSegmentId | bigint(20) unsigned | NO | MUL | NULL | |
| latitude | double | NO | | NULL | |
| longitude | double | NO | | NULL | |
| sequenceNumber | int(10) unsigned | NO | | NULL | |
+---------------------+---------------------+------+-----+---------+----------------+
Here's the mapping file for the parent:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Feb 2, 2010 10:29:09 AM by Hibernate Tools 3.2.0.beta8 -->
<hibernate-mapping>
<class name="com.xxx.orm.TravelTimeSegment" table="TravelTimeSegment" catalog="snaps">
<comment>
</comment>
<id name="id" type="long">
<column name="id" />
<generator class="assigned" />
</id>
<property name="arseserverNodeId" type="long">
<column name="ARSEServerNodeId" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="listenPort" type="int">
<column name="listenPort" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="minZoomLevel" type="int">
<column name="minZoomLevel" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="maxZoomLevel" type="int">
<column name="maxZoomLevel" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="labelOffsetX" type="int">
<column name="labelOffsetX" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="labelOffsetY" type="int">
<column name="labelOffsetY" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="classification" type="string">
<column name="classification" length="32" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="segmentName" type="string">
<column name="segmentName" length="64" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="isDead" type="byte">
<column name="isDead" not-null="true">
<comment>
</comment>
</column>
</property>
<property name="modifyTime" type="timestamp">
<column name="modifyTime" length="19" not-null="true">
<comment>
</comment>
</column>
</property>
<set name="travelTimeLinks" table="TravelTimeLink">
<key column="travelTimeSegmentId"/>
<one-to-many class="com.xxx.orm.TravelTimeLink"/>
</set>
<set name="travelTimeGPSPoints" table="TravelTimeGPSPoints" cascade="all">
<key column="travelTimeSegmentId"/>
<one-to-many class="com.xxx.orm.TravelTimeGPSPoints"/>
</set>
</class>
</hibernate-mapping>
Here's the mapping file for the child:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Jan 18, 2010 3:23:48 PM by Hibernate Tools 3.2.0.beta8 -->
<hibernate-mapping>
<class name="com.xxx.orm.TravelTimeGPSPoints" table="TravelTimeGPSPoints" catalog="snaps">
<comment>
</comment>
<id name="id" type="long">
<column name="id" />
<generator class="assigned" />
</id>
<property name="latitude" type="double">
<column name="latitude" precision="22" scale="0" />
</property>
<property name="longitude" type="double">
<column name="longitude" precision="22" scale="0" />
</property>
<property name="sequenceNumber" type="int">
<column name="sequenceNumber" />
</property>
<many-to-one name="segment" column="travelTimeSegmentId" class="com.xxx.orm.TravelTimeSegment">
</many-to-one>
</class>
</hibernate-mapping>
Here's my code that tries to save the new objects, all I am trying to do is create a new parent and a new child and set the relationship between them so the FK in the child table is correct. This code below throws the exception shown below when run but does insert a new row into each appropriate table. The only problem is that the FK in the child is left as 0 (and the id of the parent is not 0).
If anyone can work out why this isn't working I'd be EXTREMELY grateful.
Thank you all.
Code:
public class TestHibernate {
@SuppressWarnings("unchecked")
@Test
public void testAddSegment() throws Exception {
TravelTimeSegment seg;
TravelTimeGPSPoints p1;
try {
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
seg = new TravelTimeSegment(0, 2, 10000, 1, 10, 0, 0, "classif", "unit test segment", (byte)0, new Date(), new HashSet<TravelTimeLink>(), new HashSet<TravelTimeGPSPoints>());
p1 = new TravelTimeGPSPoints(0, 11, 22, 1, seg);
seg.getTravelTimeGPSPoints().add(p1);
HibernateUtil.getSessionFactory().getCurrentSession().save(seg);
HibernateUtil.getSessionFactory().getCurrentSession().save(p1);
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
}
catch (Exception ex) {
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().rollback();
throw ex;
}
}
}
Code:
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:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:145)
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.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.xxx.orm.TestHibernate.testAddSegment(TestHibernate.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
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.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
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)