Hibernate version:3.2.1
Hi all,
I have a ManyToMany Relation between DataStrip and CouplingInformation.
I am testing next scenario:
1. new DS1
2. add new CI to DS1
3. persist DS1
4. new DS2
5. get CI from DS1 and add it to DS2
6. persist DS2
7. delete DS1
--> purpose is that since CI is still being referred to DS2, only in-between-table is being updated (not CI itself)
8. now delete DS2
--> purpose is now that also CI is being deleted.
Mapping documents:
DataStrip
Code:
@ManyToMany(
fetch = FetchType.LAZY,
targetEntity=CouplingInformation.class,
cascade={CascadeType.PERSIST,CascadeType.MERGE, CascadeType.REFRESH}
)
@JoinTable(
name="datastrip_coupling",
joinColumns={@JoinColumn(name="datastrip_id")},
inverseJoinColumns={@JoinColumn(name="couplinginformation_id")}
)
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE)
public Collection<CouplingInformation> getCouplingInformationList() {
return couplingInformationList;
}
CouplingInformationCode:
@ManyToMany(
fetch = FetchType.LAZY,
targetEntity=DataStrip.class,
cascade={CascadeType.PERSIST,CascadeType.MERGE, CascadeType.REFRESH}
)
@JoinTable(
name="datastrip_coupling",
joinColumns={@JoinColumn(name="couplinginformation_id")},
inverseJoinColumns={@JoinColumn(name="datastrip_id")}
)
public Collection<DataStrip> getDataStripList() {
return dataStripList;
}
Test Code:Code:
// Add DS1
DataStrip ds1 = DataStripFactory.getDataStrip();
DataStripFactory.setCouplingInformation(ds1);
dataStripFacade.insertDataStrip(ds1);
Collection<CouplingInformation> ci1List = ds1.getCouplingInformationList();
Integer ciId = ((CouplingInformation)ci1List.iterator().next()).getCouplingInformationId();
assertNotNull("ciId not null",ciId);
//Add DS2
DataStrip ds2 = DataStripFactory.getDataStrip();
CouplingInformation ci = couplingInformationFacade.getCouplingInformation(ciId);
Collection<CouplingInformation> ci2List = new ArrayList<CouplingInformation>();
ci2List.add(ci);
ds2.setCouplingInformationList(ci2List);
dataStripFacade.insertDataStrip(ds2);
//Now remove DS1
dataStripFacade.delete(ds1);
dataStripFacade.flush();
//Verify CI does still exist
ci = couplingInformationFacade.getCouplingInformation(ciId);
assertNotNull("CI not null", ci);
//Check Orphan behaviour
dataStripFacade.delete(ds2);
dataStripFacade.flush();
ci = couplingInformationFacade.getCouplingInformation(ciId);
assertNull("CI is null", ci);
The problem:The problem is everything works fine until 7.
at point 8, DS2 is deleted, but not the orphan CouplingInformation object.
So I thought I found the solution and add CascadeType.DELETE_ORPHAN to the DataStrip object:
Code:
@ManyToMany(
fetch = FetchType.LAZY,
targetEntity=CouplingInformation.class,
cascade={CascadeType.PERSIST,CascadeType.MERGE, CascadeType.REFRESH}
)
@JoinTable(
name="datastrip_coupling",
joinColumns={@JoinColumn(name="datastrip_id")},
inverseJoinColumns={@JoinColumn(name="couplinginformation_id")}
)
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
public Collection<CouplingInformation> getCouplingInformationList() {
return couplingInformationList;
}
What happens now: hibernate refuses deleting the first object.
So the tests stop when flushing after 'dataStripFacade.delete(ds1);'
(pt 7 in the scenario)
Reason:Code:
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [phr.ipu.cat.data.metadata.coupling.CouplingInformation#139]
at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1014)
So with the DELETE_ORPHAN I can't do a partial delete ; without I have orphans.
Anyone an idea of having the both behaviours working ??
Many Thanks in advance !