mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Bug - OneToMany orphanRemoval = true, replace collection adding back original collection entry
- Adding back a bean from the original collection - Expect that bean to exist in the final result but, it's missing Fix here is in SaveManyBeans to add a insertAllChildren and use ebi.setNew(); for beans to force them to insert for this case.
This commit is contained in:
@@ -35,6 +35,7 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
private final boolean untouchedBeanCollection;
|
||||
private final Collection<?> collection;
|
||||
private int sortOrder;
|
||||
private boolean insertAllChildren;
|
||||
|
||||
SaveManyBeans(DefaultPersister persister, boolean insertedParent, BeanPropertyAssocMany<?> many, EntityBean parentBean, PersistRequestBean<?> request) {
|
||||
super(persister, insertedParent, many, parentBean, request);
|
||||
@@ -176,8 +177,11 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
skipSavingThisBean = false;
|
||||
// set the parent bean to detailBean
|
||||
many.setJoinValuesToChild(parentBean, detail, mapKeyValue);
|
||||
} else if (insertAllChildren) {
|
||||
ebi.setNew();
|
||||
skipSavingThisBean = false;
|
||||
many.setJoinValuesToChild(parentBean, detail, mapKeyValue);
|
||||
} else {
|
||||
// unmodified so skip depending on prop.isSaveRecurseSkippable();
|
||||
skipSavingThisBean = saveRecurseSkippable;
|
||||
}
|
||||
}
|
||||
@@ -342,6 +346,7 @@ public final class SaveManyBeans extends SaveManyBase {
|
||||
if (!(value instanceof BeanCollection<?>)) {
|
||||
if (!insertedParent && cascade && isChangedProperty()) {
|
||||
persister.addToFlushQueue(many.deleteByParentId(request.beanId(), null), transaction, 0);
|
||||
insertAllChildren = true;
|
||||
}
|
||||
} else {
|
||||
BeanCollection<?> c = (BeanCollection<?>) value;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.tests.cascade;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.xtest.BaseTestCase;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class TestOrphanCollectionReplacement extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
void replaceCollection_whenOrphan_expect_forcedInsert() {
|
||||
long parentId;
|
||||
{ // setup
|
||||
List<COOneMany> children = new ArrayList<>();
|
||||
children.add(new COOneMany("c0"));
|
||||
children.add(new COOneMany("c1"));
|
||||
|
||||
COOne parent = new COOne("p0");
|
||||
parent.setChildren(children);
|
||||
|
||||
DB.save(parent);
|
||||
parentId = parent.getId();
|
||||
}
|
||||
|
||||
{ // act
|
||||
COOne fetchedParent = DB.find(COOne.class, parentId);
|
||||
assert fetchedParent != null;
|
||||
|
||||
COOneMany role = new COOneMany("c2");
|
||||
|
||||
List<COOneMany> filtered = fetchedParent.getChildren().stream().filter(r -> "c0".equals(r.getName())).collect(Collectors.toList());
|
||||
|
||||
List<COOneMany> updatedRoles = new ArrayList<>();
|
||||
updatedRoles.addAll(filtered);
|
||||
updatedRoles.addAll(List.of(role));
|
||||
fetchedParent.setChildren(updatedRoles);
|
||||
|
||||
DB.save(fetchedParent);
|
||||
}
|
||||
|
||||
COOne fetchedUser2 = DB.find(COOne.class, parentId);
|
||||
requireNonNull(fetchedUser2);
|
||||
assertEquals(2, fetchedUser2.getChildren().size());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user