Fixes to only allow m2m intersection save from one direction based on

beanName.  Supports BUG 429 : Pull Request: jroper - Fixing ManyToMany
association saving bug
This commit is contained in:
rbygrave
2012-10-02 14:59:27 +13:00
parent 21d63c7424
commit bca787b54d
4 changed files with 41 additions and 3 deletions
@@ -181,4 +181,9 @@ public interface SpiTransaction extends Transaction {
* </p>
*/
public Connection getInternalConnection();
/**
* Return true if the manyToMany intersection should be persisted for this particular relationship direction.
*/
public boolean isSaveAssocManyIntersection(String intersectionTable, String beanName);
}
@@ -719,6 +719,10 @@ public final class DefaultPersister implements Persister {
this.deleteMissingChildren = false;
this.updateNullProperties = false;
}
public boolean isSaveIntersection() {
return t.isSaveAssocManyIntersection(many.getIntersectionTableJoin().getTable(), many.getBeanDescriptor().getName());
}
private Object getValue() {
return many.getValue(parentBean);
@@ -764,14 +768,19 @@ public final class DefaultPersister implements Persister {
private void saveMany(SaveManyPropRequest saveMany) {
if (saveMany.getMany().isManyToMany()) {
// save the beans that are in the manyToMany
// check if we can save the m2m intersection in this direction
boolean saveIntersectionFromThisDirection = saveMany.isSaveIntersection();
if (saveMany.isCascade()) {
// Need explicit Cascade to save the beans on other side
saveAssocManyDetails(saveMany, false, saveMany.isUpdateNullProperties());
}
// for ManyToMany save the 'relationship' via inserts/deletes
// into/from the intersection table
saveAssocManyIntersection(saveMany, saveMany.isDeleteMissingChildren());
if (saveIntersectionFromThisDirection) {
// only allowed on one direction of a m2m based on beanName
saveAssocManyIntersection(saveMany, saveMany.isDeleteMissingChildren());
}
} else {
if (saveMany.isCascade()) {
saveAssocManyDetails(saveMany, saveMany.isDeleteMissingChildren(), saveMany.isUpdateNullProperties());
@@ -117,6 +117,7 @@ public class JdbcTransaction implements SpiTransaction {
HashSet<Object> persistingBeans = new HashSet<Object>();
HashSet<Integer> deletingBeansHash;
HashMap<String,String> m2mIntersectionSave;
TransactionLogBuffer logBuffer;
@@ -223,6 +224,30 @@ public class JdbcTransaction implements SpiTransaction {
return !persistingBeans.add(bean);
}
/**
* Return true if the m2m intersection save is allowed from a given bean direction.
* This is to stop m2m intersection management via both directions of a m2m.
*/
@Override
public boolean isSaveAssocManyIntersection(String intersectionTable, String beanName) {
if (m2mIntersectionSave == null) {
// first attempt so yes allow this m2m intersection direction
m2mIntersectionSave = new HashMap<String, String>();
m2mIntersectionSave.put(intersectionTable, beanName);
return true;
}
String existingBean = m2mIntersectionSave.get(intersectionTable);
if (existingBean == null) {
// first time into this intersection table so allow
m2mIntersectionSave.put(intersectionTable, beanName);
return true;
}
// only allow if save coming from the same bean type
// to stop saves coming from both directions of m2m
return existingBean.equals(beanName);
}
/**
* Return the depth of the current persist request plus the diff. This has the
* effect of changing the current depth and returning the new value. Pass