mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user