Reputation: 94499
I have two entitys Person and Order being managed by JPA/Hibernate Entity Manager. I have attempted to create a Bidirectional one to many relationship between the two entitys by annotating them as follows:
Person:
@Id
@Column(name="PERSON_ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PERSON_SEQ")
@SequenceGenerator(name = "PERSON_SEQ", sequenceName = "PERSON_SEQ")
private Integer personId;
@OneToMany(mappedBy="person", cascade=CascadeType.ALL)
private List<Order> orders = new ArrayList<Order>();
public void addOrder(Order o)
{
getOrders().add(o);
o.setPerson(this);
}
Order:
@ManyToOne
@JoinColumn(name="PERSON_ID")
private Person person;
I then test the code:
@Test
@Transactional
@Rollback(value=false)
public void populateTable() {
WatchUtil.startTask("Persist Person");
for (int i = 0; i < 25; i++) {
Person tmpPerson= new Person();
tmpPerson.setName("Person1");
Order order = new Order();
order.setOrderNumber("Order1");
tmpPerson.addOrder(order);
dao.persist(tmpPerson); //calls entitymanager.persist(); does not call flush
}
WatchUtil.endTask();
}
This gives me a constraint exception:
2011-04-19 06:25:12,713 INFO [org.springframework.test.context.transaction.TransactionalTestExecutionListener] - <Began transaction (9): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@1f488f1]; rollback [false]>
2011-04-19 06:25:12,713 DEBUG [org.hibernate.SQL] - <insert into PERSON (PERSON_ID, NAME) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)>
2011-04-19 06:25:12,775 DEBUG [org.hibernate.SQL] - <insert into ORDER (ORDER_NUMBER PERSON_ID, ORDER_ID) values (?, ?, ?, ?, ?, ?)>
2011-04-19 06:25:12,947 WARN [org.hibernate.util.JDBCExceptionReporter] - <SQL Error: 2291, SQLState: 23000>
2011-04-19 06:25:12,947 ERROR [org.hibernate.util.JDBCExceptionReporter] - <ORA-02291: integrity constraint (BLUE_SITE.FKE2BCFD5374D88D96) violated - parent key not found>
2011-04-19 06:25:12,947 WARN [org.hibernate.util.JDBCExceptionReporter] - <SQL Error: 2291, SQLState: 23000>
2011-04-19 06:25:12,947 ERROR [org.hibernate.util.JDBCExceptionReporter] - <ORA-02291: integrity constraint (BLUE_SITE.FKE2BCFD5374D88D96) violated - parent key not found>
2011-04-19 06:25:12,947 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] - <Could not synchronize database state with session>
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.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304)
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 org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy32.flush(Unknown Source)
at test.JpaDao.persist(JpaDao.java:37)
at test.PersonJpaDaoTests.populateTable(MemberJpaDaoTests.java:156)
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 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.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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)
Caused by: java.sql.BatchUpdateException: ORA-02291: integrity constraint (BLUE_SITE.FKE2BCFD5374D88D96) violated - parent key not found
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:367)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:9119)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 44 more
StopWatch '-- DEBUGGING --': running time (millis) = 0
After receiving this error I removed the constraint from the database. Both tables populated however the keys between the parent and the child were misaligned. Can anyone steer me in the right direction? I've looked over a bunch of posts and they claim that creating a method like my Person.addOrder(Order o) should handle things.
It may also be important to note that I am using an Oracle Sequence to generate my Ids. I have also created hashCode and Equals Methods for each class.
Upvotes: 1
Views: 7074
Reputation: 94499
I found the problem after looking at the objects in the database. During the initial setup of my project I was not using Sequences, however I had auto-generate DDL turned on. This created a trigger in the database.
After sometime I decided to use a sequence. The new configuration that included the sequence was conflicting with the old triggers, producing the constraint error. Once I deleted these triggers the exception went away.
Upvotes: 2