]
Joe Rossi commented on HHH-2801:
--------------------------------
I think I hit a similar problem (though not sure it's exactly the same), but I'll
describe it here as it may be affecting others:
I have an object which has a bunch of detail entities and where operations are cascaded to
those detail entities. The hibernate mapping for the detail is as follows:
<set name="objectLinks" fetch="join" lazy="false"
cascade="all,delete-orphan" inverse="true">
<key column="POL_PI_ID" />
<one-to-many class="ProcessObjectLink"/>
</set>
My application then invoked a series of merge operations each of which involved a new
addition to the detail collection (objectLinks above). The first of the merge operations
succeeded, but the second failed with a duplicate key error at the database level.
On investigation it appeared that the original object which was passed into the first
merge() call was not updated with the new detail row
key value. When a new detail object was added to the objectLinks collection ad a second
merge() call was invoked then Hibernate
thought it needed to reinsert the detail row from the first merge call (as it had no key
value and, hence, looked like another new row). Because I have a unique key on the table
that contains the objectLinks collection then the second merge() caused a duplicate key
error.
The merge() call returns the updated object. The workaround is to use this returned object
for the next merge() call. (Of course, if I had read the doc properly I would have
realized this!)
I'm using Hibernate version 3.0.5
wrong insert/delete order when updating record-set
--------------------------------------------------
Key: HHH-2801
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2801
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.4.sp1
Environment: hibernate-3.2.4.sp1, hibernate-annotations-3.3.0.GA,
hibernate-entitymanager-3.3.1.GA, Oracle 10g Express Edition
Reporter: Christoph Mayerhofer
Assignee: Gail Badner
Attachments: manytomanywithassocclass.tar.gz, manytomanywithassocclassbug.tar.gz,
model.zip, test-pro.tar.gz
Overview: I have a record with a OneToMany association. From this associated record-set a
record is removed and added again, both records identified with the same key. When doing a
merge, I get a Unique constraint violation, because Hibernate first tries to insert the
new record. Hibernate should first delete the old record, and after this insert the new
record, avoiding the unique constraint violation.
Detailed description: I have the following entities: Patient, SocialInsurance,
PatientSocialInsurance. A patient could have several social insurances assigned to it. A
social insurance could be assigned several times to a patient, we have a m:n relation
between Patient and SocialInsurance. The relation-table has the name
PatientSocialInsurance, with a unique constraint over patient_id and social_insurance_id.
Each POJO inherits from a Base-POJO, which holds the id and the insert- and
update-timestamps and userstamps.
Base ---> PatientEntity ---> Patient
Base ---> SocialInsuranceEntity ---> SocialInsurance
Base ---> PatientSocialInsuranceEntity ---> PatientSocialInsurance
Note: All *Entity model objects are generated with Hibernate-Tools from the db-schema,
assuming that there are no wrong annotations, no wrong fields or wrong
getter-/setter-methods in these model-classes.
(I have enclosed all model-classes within an zipped attachment.)
Now I try to delete an existing social insurance from a patient and add the same social
insurance to the patient again:
public void deleteSocialInsurance(Patient p, PatientSocialInsurance s) {
if (p == null || s == null) {
throw new IllegalArgumentException();
}
s.setSocialInsurance(null);
s.setPatient(null);
p.getPatientSocialInsurances().remove(s);
}
public void addPatientSocialInsurance(Patient p, PatientSocialInsurance s)
throws DuplicatePatientSocInsException {
if (p == null || s == null) {
throw new IllegalArgumentException();
}
s.setPatient(p);
p.getPatientSocialInsurances().add(s);
}
After doing a merge on the patient object, I get the following error:
DEBUG - persisting patient...
DEBUG - transaction org.hibernate.ejb.TransactionImpl@44ac6a started
DEBUG - update timestamp and userstamp for base record set
DEBUG - update timestamp and userstamp for base record set
DEBUG - update timestamp and userstamp for base record set
DEBUG - update timestamp and userstamp for base record set
DEBUG - update timestamp and userstamp for base record set
DEBUG - select rawtohex(sys_guid()) from dual
DEBUG - insert timestamp and userstamp for base record set
DEBUG - insert into dseas.PATIENT_SOCIAL_INSURANCE (TIME_CRE, TIME_UPD, USER_CRE,
USER_UPD, CODE_MEMBERSHIP_NO, CODE_TYPE_DEFAULT, PATIENT_ID, SOC_INS_ID, ID) values (?, ?,
?, ?, ?, ?, ?, ?, ?)
ERROR - ORA-00001: Unique Constraint (DSEAS.PATIENT_SOCIAL_INSURANCE_UK) verletzt
ERROR - ORA-00001: Unique Constraint (DSEAS.PATIENT_SOCIAL_INSURANCE_UK) verletzt
ERROR - 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:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:253)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:237)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
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 org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
at org.dseas.base.hibernate.EntityManagerFacade.commit(EntityManagerFacade.java:78)
at
org.dseas.business.service.maindata.PatientEditorService.save(PatientEditorService.java:112)
at
org.dseas.ui.rcp.editor.patient.PatientEditorPart.doSave(PatientEditorPart.java:1298)
at org.eclipse.ui.internal.SaveableHelper$1.run(SaveableHelper.java:143)
at org.eclipse.ui.internal.SaveableHelper$4.run(SaveableHelper.java:266)
at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:369)
at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:313)
at org.eclipse.jface.window.ApplicationWindow$1.run(ApplicationWindow.java:758)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
at org.eclipse.jface.window.ApplicationWindow.run(ApplicationWindow.java:755)
at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2451)
at
org.eclipse.ui.internal.SaveableHelper.runProgressMonitorOperation(SaveableHelper.java:274)
at
org.eclipse.ui.internal.SaveableHelper.runProgressMonitorOperation(SaveableHelper.java:253)
at org.eclipse.ui.internal.SaveableHelper.savePart(SaveableHelper.java:148)
at org.eclipse.ui.internal.EditorManager.savePart(EditorManager.java:1345)
at org.eclipse.ui.internal.WorkbenchPage.savePart(WorkbenchPage.java:3184)
at org.eclipse.ui.internal.WorkbenchPage.saveEditor(WorkbenchPage.java:3197)
at org.eclipse.ui.internal.SaveAction.run(SaveAction.java:73)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
at
org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:545)
at
org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:490)
at
org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:443)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:938)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3682)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3293)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2389)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2353)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2219)
at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:466)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:461)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.dseas.ui.rcp.Application.start(Application.java:22)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:153)
at
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
at
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:504)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:443)
at org.eclipse.equinox.launcher.Main.run(Main.java:1169)
at org.eclipse.equinox.launcher.Main.main(Main.java:1144)
Caused by: java.sql.BatchUpdateException: ORA-00001: Unique Constraint
(DSEAS.PATIENT_SOCIAL_INSURANCE_UK) verletzt
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343)
at
oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10657)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:246)
... 55 more
ERROR - Error while commiting the transaction
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: