mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 22:41:35 +00:00
#2127 - Fix for - Adding a new list of children to @OneToMany with orphanRemoval true does not delete existing orphans
Modifies EntityBeanIntercept preSetterMany to set the changed state on the many property and use this in SaveManyBeans to detect when the existing beans need orphan removal
This commit is contained in:
1 parent
dd080c5933
commit
d57657c209
4 files changed
+79
-20
No files matched your search
@@ -210,18 +210,6 @@ public class SaveManyBeans extends SaveManyBase {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasNewOrDirtyBeans() {
|
||||
if (collection == null) {
|
||||
return false;
|
||||
}
|
||||
for (Object bean : collection) {
|
||||
if (bean instanceof EntityBean && ((EntityBean) bean)._ebean_getIntercept().isNewOrDirty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the Id values of the details to remove 'missing children' for stateless updates.
|
||||
*/
|
||||
@@ -344,14 +332,18 @@ public class SaveManyBeans extends SaveManyBase {
|
||||
transaction.depth(-1);
|
||||
}
|
||||
|
||||
private boolean isChangedProperty() {
|
||||
return parentBean._ebean_getIntercept().isChangedProperty(many.getPropertyIndex());
|
||||
}
|
||||
|
||||
private void removeAssocManyOrphans() {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (!(value instanceof BeanCollection<?>)) {
|
||||
// if (!insertedParent && cascade && hasNewOrDirtyBeans()) {
|
||||
// persister.addToFlushQueue(many.deleteByParentId(request.getBeanId(), null), transaction, 0);
|
||||
// }
|
||||
if (!insertedParent && cascade && isChangedProperty()) {
|
||||
persister.addToFlushQueue(many.deleteByParentId(request.getBeanId(), null), transaction, 0);
|
||||
}
|
||||
} else {
|
||||
BeanCollection<?> c = (BeanCollection<?>) value;
|
||||
Set<?> modifyRemovals = c.getModifyRemovals();
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.junit.Test;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -70,4 +71,67 @@ public class TestBeanState extends BaseTestCase {
|
||||
beanState.setDisableLazyLoad(true);
|
||||
assertNull(customer.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getChangedProps_when_setManyProperty() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Customer customer = DB.find(Customer.class).order("id").setMaxRows(1).findOne();
|
||||
|
||||
BeanState beanState = DB.getBeanState(customer);
|
||||
assertThat(beanState.getChangedProps()).isEmpty();
|
||||
|
||||
customer.setContacts(new ArrayList<>());
|
||||
assertThat(beanState.getChangedProps()).containsOnly("contacts");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getChangedProps_when_setManyProperty_onNewBean() {
|
||||
|
||||
Customer customer = new Customer();
|
||||
|
||||
BeanState beanState = DB.getBeanState(customer);
|
||||
assertThat(beanState.getChangedProps()).isEmpty();
|
||||
|
||||
// when new state, then loaded
|
||||
customer.setContacts(new ArrayList<>());
|
||||
assertThat(beanState.getChangedProps()).isEmpty();
|
||||
assertThat(beanState.getLoadedProps()).containsOnly("contacts");
|
||||
|
||||
// set loaded state, then marked as changed
|
||||
beanState.setLoaded();
|
||||
customer.setContacts(new ArrayList<>());
|
||||
assertThat(beanState.getLoadedProps()).containsOnly("contacts");
|
||||
assertThat(beanState.getChangedProps()).containsOnly("contacts");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void readOnly_when_setManyProperty() {
|
||||
|
||||
Customer customer = new Customer();
|
||||
customer.setContacts(new ArrayList<>());
|
||||
|
||||
BeanState beanState = DB.getBeanState(customer);
|
||||
beanState.setLoaded();
|
||||
beanState.setReadOnly(true);
|
||||
|
||||
// act, try to mutate read only bean
|
||||
customer.setContacts(new ArrayList<>());
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void readOnly_when_setProperty() {
|
||||
|
||||
Customer customer = new Customer();
|
||||
customer.setName("a");
|
||||
|
||||
BeanState beanState = DB.getBeanState(customer);
|
||||
beanState.setLoaded();
|
||||
beanState.setReadOnly(true);
|
||||
|
||||
// act, try to mutate read only bean
|
||||
customer.setName("b");
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,7 @@ public class TestDeleteO2MOrphans extends BaseTestCase {
|
||||
|
||||
// assert
|
||||
COOne check = findById(id);
|
||||
//FIXME #2127 #2141: assertThat(check.getChildren()).hasSize(2);
|
||||
assertThat(check.getChildren()).hasSize(4);
|
||||
assertThat(check.getChildren()).hasSize(2);
|
||||
DB.delete(check);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user