Fix for #149 - OneToMany with nested ManyToMany deletion bug

This commit is contained in:
Rob Bygrave
2014-06-23 23:34:22 +12:00
parent 8fe1f32e78
commit df526b8f3c
6 changed files with 379 additions and 3 deletions
@@ -413,14 +413,14 @@ public final class DefaultPersister implements Persister {
if (t.isPersistCascade()) {
// OneToOne exported side with delete cascade
BeanPropertyAssocOne<?>[] expOnes = descriptor.propertiesOneExportedDelete();
for (int i = 0; i < expOnes.length; i++) {
for (int i = 0; i < expOnes.length; i++) {
BeanDescriptor<?> targetDesc = expOnes[i].getTargetDescriptor();
if (targetDesc.isDeleteRecurseSkippable() && !targetDesc.isBeanCaching()) {
SqlUpdate sqlDelete = expOnes[i].deleteByParentId(id, idList);
executeSqlUpdate(sqlDelete, t);
} else {
List<Object> childIds = expOnes[i].findIdsByParentId(id, idList, t);
delete(targetDesc, null, childIds, t);
deleteChildrenById(t, targetDesc, childIds);
}
}
@@ -1057,12 +1057,33 @@ public final class DefaultPersister implements Persister {
Object parentId = desc.getId(parentBean);
List<Object> idsByParentId = many.findIdsByParentId(parentId, null, t, excludeDetailIds);
if (!idsByParentId.isEmpty()) {
delete(targetDesc, null, idsByParentId, t);
deleteChildrenById(t, targetDesc, idsByParentId);
}
}
}
}
/**
* Cascade delete child entities by Id.
* <p>
* Will use delete by object if the child entity has manyToMany relationships.
*/
private void deleteChildrenById(SpiTransaction t, BeanDescriptor<?> targetDesc, List<Object> childIds) {
if (targetDesc.propertiesManyToMany().length > 0) {
// convert into a list of reference objects and perform delete by object
List<Object> refList = new ArrayList<Object>(childIds.size());
for (Object id : childIds) {
refList.add(targetDesc.createReference(null, id));
}
deleteList(refList, t);
} else {
// perform delete by statement if possible
delete(targetDesc, null, childIds, t);
}
}
/**
* Save any associated one beans.
*/