]
Madhavi Jasti commented on HHH-5454:
------------------------------------
We recently upgraded to Hibernate 3.3.2 and are encountering the same issue with the
ordering of inserts sent by Hibernate.
We tried by setting hibernate.order_inserts to true but still same error on Oracle -
related to constraint violation exception, parent key not found.
Is there a permanent fix for this? or another workaround?
With hibernate.order_inserts=true Hibernate executes SQL inserts in
wrong order
-------------------------------------------------------------------------------
Key: HHH-5454
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-5454
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.3.0.SP1, 3.3.1, 3.3.2, 3.6.0.Beta2
Environment: Initially occurred with hibernate-core 3.3.1, Oracle 11g.
Reproduced with hibernate-core 3.3.0 SP1 (and later) and HSQLDB 2.0.0
Reporter: Oleg Tsernetsov
Attachments: jpatest.zip
*General:*
With _hibernate.order_inserts_ configuration property set to _true_ Hibernate executes
SQL inserts in wrong order, so that dependent entities are attempted to be inserted before
parent entities. This is a production case, so we had to switch off hibernate insert
ordering to workaround the problem.
*Test case:*
Test case for reproduce is attached (jpatest.zip). It uses hibernate-entitymanager
3.4.0.GA (hibernate-core 3.3.0 SP1), hsqldb 2.0.0. The problem is also reproducible in
later versions of hibernate-core (3.3.1, 3.3.2, 3.6.0.Beta2).
Test case is a typical maven2 project.
In order to run the test case:
- unzip the archive to any folder
- cd jpatest
- mvn test
If change hibernate.order_inserts to _false_ in
/jpatest/src/main/resources/META-INF/persistence.xml, then the test passes.
Mappings are located under \jpatest\src\main\resources\META-INF\mappings.hbm.xml
*Data model:*
[Person] 1 -- * [Phone]
[Person] 1 -- * [Relation] * -- 1 [Person]
*Scenario:*
1) Insert plain person P1.
2) Update person P1,
-- add new phone PH1 to person P1
-- add new relation R1 to person P1. Relation R1 refers to a new person P2 having new
phone PH2 Update of person P1 generates insert for phone PH1 and cascade inserts for P2,
PH2 and R1.
Once inserts are ordered, insert clauses for phones PH1 and PH2 come first. As insert for
PH2 is executed before the insert of its parent entity P2, the whole operation fails due
to parent key not found.
With Oracle DB it results in java.sql.BatchUpdateException: ORA-02291: integrity
constraint (PHONE_PERSON_FK) violated - parent key not found
With HSQLDB - java.sql.BatchUpdateException: integrity constraint violation: foreign key
no parent; PHONE_PERSON_FK table: PHONE
*Problematic code*
org.hibernate.engine.ActionQueue.InsertActionSorter.findBatchNumber(), uses only
_property_ types to determine batch number, but in given case cascade goes through
composite primary key of Phone, so the code should also deep-traverse
action.getPersister().getClassMetadata().getIdentifierType().
*Another problem*
When I tried to change phone collection mapping in Person entity from _<map>_ to
_<set>_ (with hope to workaround the issue), then I got another error:
java.lang.NullPointerException
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:136)
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:144)
at org.hibernate.type.EntityType.getHashCode(EntityType.java:312)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:212)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:126)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:70)
at
org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:184)
at
org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
at
org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
at
org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
at
org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:636)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:628)
at org.hibernate.engine.EJB3CascadingAction$1.cascade(EJB3CascadingAction.java:28)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:319)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:265)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
at
org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:479)
at
org.hibernate.event.def.DefaultPersistEventListener.entityIsPersistent(DefaultPersistEventListener.java:134)
at
org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:107)
at
org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:645)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:619)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:623)
at
org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:220)
at com.test.AppTest.testJPA(AppTest.java:77)
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:597)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at
org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
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)
Please pay attention to it as well.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: