Hi there,
I've been using Hibernate with SQL Server 8 for some time now, and have seen very odd behavior from an extremely simple schema. Normally, saving and loading this object via Hibernate (using version 2.1) works just fine, but every once in a blue moon, I get a foreign key constraint.
The mapping looks like this:
Code:
<hibernate-mapping>
<class name="audit.AuditEvent" table="audit_event" >
<id name="id" type="long" column="event_id" unsaved-value="0">
<generator class="identity"/>
</id>
<property name="timestamp" column="timestamp" type="timestamp" />
<property name="application" column="application" type="string" length="32" />
<property name="context" column="context" type="string" length="64"/>
<property name="actor" column="actor" type="string" length="10" />
<property name="message" column="message" type="string" length="255" />
<set name="orderIds" table="audit_event_orders" cascade="all">
<key column="event_id"/>
<element column="order_id" type="string" length="10"/>
</set>
</class>
</hibernate-mapping>
So, the related table for orders simply has a foreign key to AuditEvent (event_id) and an order ID. The following is the exception that I (rarely) see:
Code:
could not insert collection: [audit.AuditEvent.orderIds#0]
net.sf.hibernate.JDBCException: could not insert collection: [audit.AuditEvent.orderIds#0]
at net.sf.hibernate.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:557)
at net.sf.hibernate.impl.ScheduledCollectionRecreate.execute(ScheduledCollectionRecreate.java:23)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2308)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2265)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2187)
at sql.HibernateAction.execute(HibernateAction.java:68)
at sql.HibernateService.save(HibernateService.java:115)
at audit.AuditServiceImpl.handleEvent(AuditServiceImpl.java:192)
at audit.AuditServiceImpl$AuditListener.onMessage(AuditServiceImpl.java:288)
at messaging.tibrv.TibrvReceiver.onMsg(TibrvReceiver.java:117)
at com.tibco.tibrv.TibrvEvent.invoke(TibrvEvent.java:160)
at com.tibco.tibrv.TibrvImplQueueC.natDispatch(Native Method)
at com.tibco.tibrv.TibrvImplQueueC.dispatch(TibrvImplQueueC.java:44)
at com.tibco.tibrv.TibrvQueue.dispatch(TibrvQueue.java:301)
at reuters.RvBase.run(RvBase.java:83)
at java.lang.Thread.run(Thread.java:534)
Caused by: com.inet.tds.SQLException: Msg 547, Level 16, State 0, Line 1, Sqlstate 23000
[GCMBOS001SQL]INSERT statement conflicted with COLUMN FOREIGN KEY constraint 'FK852E647D1093C0E0'. The conflict occurred in database 'test', table 'audit_event', column 'event_id'.
at com.inet.tds.a.a(Unknown Source)
at com.inet.tds.a.a(Unknown Source)
at com.inet.tds.c.new(Unknown Source)
at com.inet.tds.c.executeUpdate(Unknown Source)
at com.inet.pool.b.executeUpdate(Unknown Source)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:538)
... 15 more
It seems to me that the only way I could get a foreign key constraint in this situation were if the event_id on an object in the set were not properly assigned (i.e. was referring to an id in the audit event table that did not exist). However, I don't need to do anything fancy like set the parent reference of each object in the set because each object is just a simple String, so Hibernate should take care of this for me.
If I need to send along the Hibernate log it might take me a while, as this error is pretty rare. However, if anyone can pick up on either a subtle or egregious mistake here, I would greatly appreciate it.
Thank you in advance.
Sincerely,
Adam Rice