mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#2272 Fix for collection with orphanRemoval (such that equals/hashCode isn't use)
- Changes ModifyHolder to use IdentityHashMap such that equals/hashcode isn't invoked - Change SaveManyBeans such that M2M intersection deletes execute before inserts The SaveManyBeans change is required to pass TestM2MModifyTest. With that test we get a delete/insert pair that we somewhat expect because we clear() the collection. Previously equals/hashCode meant we didn't get that delete/insert pair. The test changes from containsExactly() to containsOnly() as we now can't guarantee the ordering with IdentityHashMap.
This commit is contained in:
@@ -4,7 +4,6 @@ import io.ebean.bean.BeanCollection;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@@ -13,9 +12,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BeanListTest {
|
||||
|
||||
private Object object1 = new Object();
|
||||
private Object object2 = new Object();
|
||||
private Object object3 = new Object();
|
||||
private final Object object1 = new Object();
|
||||
private final Object object2 = new Object();
|
||||
private final Object object3 = new Object();
|
||||
|
||||
private List<Object> all() {
|
||||
List<Object> all = new ArrayList<>();
|
||||
@@ -33,7 +32,7 @@ public class BeanListTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_setModifyListening_null() throws Exception {
|
||||
public void test_setModifyListening_null() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(null);
|
||||
@@ -45,7 +44,7 @@ public class BeanListTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_setModifyListening_none() throws Exception {
|
||||
public void test_setModifyListening_none() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.NONE);
|
||||
@@ -57,28 +56,28 @@ public class BeanListTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws Exception {
|
||||
public void testAdd() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
list.add(object1);
|
||||
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
|
||||
list.add(object1);
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1);
|
||||
|
||||
list.add(object2);
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1, object2);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1, object2);
|
||||
|
||||
list.remove(object1);
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object2);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object2);
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAll_given_emptyStart() throws Exception {
|
||||
public void testAddAll_given_emptyStart() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -86,12 +85,12 @@ public class BeanListTest {
|
||||
// act
|
||||
list.addAll(all());
|
||||
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_removals_DeleteThenAddBack_expect_noChange() throws Exception {
|
||||
public void test_removals_DeleteThenAddBack_expect_noChange() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(some());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.REMOVALS);
|
||||
@@ -106,33 +105,33 @@ public class BeanListTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_sort_whenAll_expect_noChange() throws Exception {
|
||||
public void test_sort_whenAll_expect_noChange() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(all());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
// act
|
||||
Collections.sort(list, Comparator.comparingInt(Object::hashCode));
|
||||
list.sort(Comparator.comparingInt(Object::hashCode));
|
||||
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_sort_whenRemovals_expect_noChange() throws Exception {
|
||||
public void test_sort_whenRemovals_expect_noChange() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(all());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.REMOVALS);
|
||||
|
||||
// act
|
||||
Collections.sort(list, Comparator.comparingInt(Object::hashCode));
|
||||
list.sort(Comparator.comparingInt(Object::hashCode));
|
||||
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd_given_someAlreadyIn() throws Exception {
|
||||
public void testAdd_given_someAlreadyIn() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(some());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -143,12 +142,12 @@ public class BeanListTest {
|
||||
assertThat(list.contains(object2)).isTrue();
|
||||
list.add(object2); // object2 added as List allows duplicates
|
||||
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1, object2);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1, object2);
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddSome_given_someAlreadyIn() throws Exception {
|
||||
public void testAddSome_given_someAlreadyIn() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(some());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -156,43 +155,43 @@ public class BeanListTest {
|
||||
// act
|
||||
list.addAll(all());
|
||||
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove_given_beansInAdditions() throws Exception {
|
||||
public void testRemove_given_beansInAdditions() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
list.addAll(all());
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
list.remove(object2);
|
||||
list.remove(object3);
|
||||
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAll_given_beansInAdditions() throws Exception {
|
||||
public void testRemoveAll_given_beansInAdditions() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
list.addAll(all());
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
list.removeAll(some());
|
||||
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove_given_beansNotInAdditions() throws Exception {
|
||||
public void testRemove_given_beansNotInAdditions() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(all());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -203,11 +202,11 @@ public class BeanListTest {
|
||||
|
||||
// assert
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
assertThat(list.getModifyRemovals()).containsExactly(object2, object3);
|
||||
assertThat(list.getModifyRemovals()).containsOnly(object2, object3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAll_given_beansNotInAdditions() throws Exception {
|
||||
public void testRemoveAll_given_beansNotInAdditions() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(all());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -217,11 +216,11 @@ public class BeanListTest {
|
||||
|
||||
// assert
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
assertThat(list.getModifyRemovals()).containsExactly(object2, object3);
|
||||
assertThat(list.getModifyRemovals()).containsOnly(object2, object3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() throws Exception {
|
||||
public void testClear() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(all());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -230,12 +229,12 @@ public class BeanListTest {
|
||||
list.clear();
|
||||
|
||||
//assert
|
||||
assertThat(list.getModifyRemovals()).containsExactly(object1, object2, object3);
|
||||
assertThat(list.getModifyRemovals()).containsOnly(object1, object2, object3);
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear_given_someBeansInAdditions() throws Exception {
|
||||
public void testClear_given_someBeansInAdditions() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.add(object1);
|
||||
@@ -247,27 +246,27 @@ public class BeanListTest {
|
||||
list.clear();
|
||||
|
||||
//assert
|
||||
assertThat(list.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(list.getModifyRemovals()).containsOnly(object1);
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetainAll_given_beansInAdditions() throws Exception {
|
||||
public void testRetainAll_given_beansInAdditions() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
list.addAll(all());
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
list.retainAll(some());
|
||||
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object2, object3);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object2, object3);
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetainAll_given_someBeansInAdditions() throws Exception {
|
||||
public void testRetainAll_given_someBeansInAdditions() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.add(object1);
|
||||
@@ -278,12 +277,12 @@ public class BeanListTest {
|
||||
// act
|
||||
list.retainAll(some());
|
||||
|
||||
assertThat(list.getModifyAdditions()).containsExactly(object3);
|
||||
assertThat(list.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(list.getModifyAdditions()).containsOnly(object3);
|
||||
assertThat(list.getModifyRemovals()).containsOnly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetainAll_given_noBeansInAdditions() throws Exception {
|
||||
public void testRetainAll_given_noBeansInAdditions() {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(all());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -291,7 +290,7 @@ public class BeanListTest {
|
||||
// act
|
||||
list.retainAll(some());
|
||||
|
||||
assertThat(list.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(list.getModifyRemovals()).containsOnly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -34,30 +34,30 @@ public class BeanMapTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws Exception {
|
||||
public void testAdd() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
map.put("1", object1);
|
||||
map.put("4", null);
|
||||
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(map.getModifyRemovals()).isEmpty();
|
||||
|
||||
map.put("1", object1);
|
||||
map.put("4", null);
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1);
|
||||
|
||||
map.put("2", object2);
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1, object2);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1, object2);
|
||||
|
||||
map.remove("1");
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object2);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object2);
|
||||
assertThat(map.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAll_given_emptyStart() throws Exception {
|
||||
public void testAddAll_given_emptyStart() {
|
||||
|
||||
BeanMap<String, Object> set = new BeanMap<>();
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -65,28 +65,28 @@ public class BeanMapTest {
|
||||
// act
|
||||
set.putAll(all());
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd_given_someAlreadyIn() throws Exception {
|
||||
public void testAdd_given_someAlreadyIn() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>(some());
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
// act
|
||||
assertThat(map.values().contains(object1)).isFalse();
|
||||
assertThat(map.containsValue(object1)).isFalse();
|
||||
map.put("1", object1);
|
||||
assertThat(map.values().contains(object2)).isTrue();
|
||||
assertThat(map.containsValue(object2)).isTrue();
|
||||
map.put("2", object2);
|
||||
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(map.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddSome_given_someAlreadyIn() throws Exception {
|
||||
public void testAddSome_given_someAlreadyIn() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>(some());
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -94,44 +94,44 @@ public class BeanMapTest {
|
||||
// act
|
||||
map.putAll(all());
|
||||
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(map.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove_given_beansInAdditions() throws Exception {
|
||||
public void testRemove_given_beansInAdditions() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
map.putAll(all());
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
map.remove("2");
|
||||
map.remove("3");
|
||||
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(map.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAll_given_beansInAdditions() throws Exception {
|
||||
public void testRemoveAll_given_beansInAdditions() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
map.putAll(all());
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
map.remove("2");
|
||||
map.remove("3");
|
||||
|
||||
assertThat(map.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(map.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(map.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove_given_beansNotInAdditions() throws Exception {
|
||||
public void testRemove_given_beansNotInAdditions() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>(all());
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -142,11 +142,11 @@ public class BeanMapTest {
|
||||
|
||||
// assert
|
||||
assertThat(map.getModifyAdditions()).isEmpty();
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2, object3);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object2, object3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAll_given_beansNotInAdditions() throws Exception {
|
||||
public void testRemoveAll_given_beansNotInAdditions() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>(all());
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -157,11 +157,11 @@ public class BeanMapTest {
|
||||
|
||||
// assert
|
||||
assertThat(map.getModifyAdditions()).isEmpty();
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2, object3);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object2, object3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() throws Exception {
|
||||
public void testClear() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>(all());
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -170,12 +170,12 @@ public class BeanMapTest {
|
||||
map.clear();
|
||||
|
||||
//assert
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1, object2, object3);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object1, object2, object3);
|
||||
assertThat(map.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear_given_someBeansInAdditions() throws Exception {
|
||||
public void testClear_given_someBeansInAdditions() {
|
||||
|
||||
BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
map.put("2", object2);
|
||||
@@ -185,7 +185,7 @@ public class BeanMapTest {
|
||||
map.clear();
|
||||
|
||||
//assert
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object1);
|
||||
assertThat(map.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public class BeanMapTest {
|
||||
assertThat(map).doesNotContainKeys("1");
|
||||
assertThat(map.get("1")).isNull();
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -245,7 +245,7 @@ public class BeanMapTest {
|
||||
assertThat(map).isEmpty();
|
||||
assertThat(keySet).isEmpty();
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1, object2);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object1, object2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -258,20 +258,14 @@ public class BeanMapTest {
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
final Set<String> keySet = map.keySet();
|
||||
final Iterator<String> iterator = keySet.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final String key = iterator.next();
|
||||
if (key.equals("2")) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
keySet.removeIf(key -> key.equals("2"));
|
||||
|
||||
assertThat(map).hasSize(2);
|
||||
assertThat(keySet).hasSize(2);
|
||||
assertThat(keySet).containsExactly("1", "3");
|
||||
assertThat(map).containsKeys("1", "3");
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -294,7 +288,7 @@ public class BeanMapTest {
|
||||
assertThat(keySet).containsExactly("1", "4");
|
||||
assertThat(map).containsKeys("1", "4");
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2, object3, object5);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object2, object3, object5);
|
||||
}
|
||||
|
||||
|
||||
@@ -318,7 +312,7 @@ public class BeanMapTest {
|
||||
assertThat(keySet).containsExactly("2", "3", "5");
|
||||
assertThat(map).containsKeys("2", "3", "5");
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1, object4);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object1, object4);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
@@ -348,7 +342,7 @@ public class BeanMapTest {
|
||||
|
||||
assertThat(entries).isEmpty();
|
||||
assertThat(map).isEmpty();
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -365,7 +359,7 @@ public class BeanMapTest {
|
||||
assertThat(existed22).isFalse();
|
||||
|
||||
assertThat(map).hasSize(4);
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -395,7 +389,7 @@ public class BeanMapTest {
|
||||
}
|
||||
assertThat(map).hasSize(3);
|
||||
assertThat(entries).hasSize(3);
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2, object5);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object2, object5);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -406,7 +400,7 @@ public class BeanMapTest {
|
||||
entries.removeAll(asList(new AbstractMap.SimpleEntry<>("1", object1), new AbstractMap.SimpleEntry<>("3", object4), new AbstractMap.SimpleEntry<>("4", object4)));
|
||||
assertThat(map).hasSize(3);
|
||||
assertThat(entries).hasSize(3);
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1, object4);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object1, object4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -417,7 +411,7 @@ public class BeanMapTest {
|
||||
entries.retainAll(asList(new AbstractMap.SimpleEntry<>("1", object1), new AbstractMap.SimpleEntry<>("3", object4), new AbstractMap.SimpleEntry<>("4", object4)));
|
||||
assertThat(map).hasSize(2);
|
||||
assertThat(entries).hasSize(2);
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2, object3, object5);
|
||||
assertThat(map.getModifyRemovals()).containsOnly(object2, object3, object5);
|
||||
}
|
||||
|
||||
private BeanMap<String, EBasic> newModifyListeningMap() {
|
||||
|
||||
@@ -31,28 +31,28 @@ public class BeanSetTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws Exception {
|
||||
public void testAdd() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
set.add(object1);
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
|
||||
set.add(object1);
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1);
|
||||
|
||||
set.add(object2);
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1, object2);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1, object2);
|
||||
|
||||
set.remove(object1);
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object2);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object2);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAll_given_emptyStart() throws Exception {
|
||||
public void testAddAll_given_emptyStart() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -60,12 +60,12 @@ public class BeanSetTest {
|
||||
// act
|
||||
set.addAll(all());
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd_given_someAlreadyIn() throws Exception {
|
||||
public void testAdd_given_someAlreadyIn() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>(some());
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -76,12 +76,12 @@ public class BeanSetTest {
|
||||
assertThat(set.contains(object2)).isTrue();
|
||||
set.add(object2);
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddSome_given_someAlreadyIn() throws Exception {
|
||||
public void testAddSome_given_someAlreadyIn() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>(some());
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -89,43 +89,43 @@ public class BeanSetTest {
|
||||
// act
|
||||
set.addAll(all());
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove_given_beansInAdditions() throws Exception {
|
||||
public void testRemove_given_beansInAdditions() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
set.addAll(all());
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
set.remove(object2);
|
||||
set.remove(object3);
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAll_given_beansInAdditions() throws Exception {
|
||||
public void testRemoveAll_given_beansInAdditions() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
set.addAll(all());
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
set.removeAll(some());
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemove_given_beansNotInAdditions() throws Exception {
|
||||
public void testRemove_given_beansNotInAdditions() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>(all());
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -136,11 +136,11 @@ public class BeanSetTest {
|
||||
|
||||
// assert
|
||||
assertThat(set.getModifyAdditions()).isEmpty();
|
||||
assertThat(set.getModifyRemovals()).containsExactly(object2, object3);
|
||||
assertThat(set.getModifyRemovals()).containsOnly(object2, object3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAll_given_beansNotInAdditions() throws Exception {
|
||||
public void testRemoveAll_given_beansNotInAdditions() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>(all());
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -150,11 +150,11 @@ public class BeanSetTest {
|
||||
|
||||
// assert
|
||||
assertThat(set.getModifyAdditions()).isEmpty();
|
||||
assertThat(set.getModifyRemovals()).containsExactly(object2, object3);
|
||||
assertThat(set.getModifyRemovals()).containsOnly(object2, object3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() throws Exception {
|
||||
public void testClear() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>(all());
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -163,12 +163,12 @@ public class BeanSetTest {
|
||||
set.clear();
|
||||
|
||||
//assert
|
||||
assertThat(set.getModifyRemovals()).containsExactly(object1, object2, object3);
|
||||
assertThat(set.getModifyRemovals()).containsOnly(object1, object2, object3);
|
||||
assertThat(set.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear_given_someBeansInAdditions() throws Exception {
|
||||
public void testClear_given_someBeansInAdditions() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.add(object1);
|
||||
@@ -180,27 +180,27 @@ public class BeanSetTest {
|
||||
set.clear();
|
||||
|
||||
//assert
|
||||
assertThat(set.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(set.getModifyRemovals()).containsOnly(object1);
|
||||
assertThat(set.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetainAll_given_beansInAdditions() throws Exception {
|
||||
public void testRetainAll_given_beansInAdditions() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
set.addAll(all());
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object1, object2, object3);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object1, object2, object3);
|
||||
|
||||
// act
|
||||
set.retainAll(some());
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object2, object3);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object2, object3);
|
||||
assertThat(set.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetainAll_given_someBeansInAdditions() throws Exception {
|
||||
public void testRetainAll_given_someBeansInAdditions() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>();
|
||||
set.add(object1);
|
||||
@@ -211,12 +211,12 @@ public class BeanSetTest {
|
||||
// act
|
||||
set.retainAll(some());
|
||||
|
||||
assertThat(set.getModifyAdditions()).containsExactly(object3);
|
||||
assertThat(set.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(set.getModifyAdditions()).containsOnly(object3);
|
||||
assertThat(set.getModifyRemovals()).containsOnly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetainAll_given_noBeansInAdditions() throws Exception {
|
||||
public void testRetainAll_given_noBeansInAdditions() {
|
||||
|
||||
BeanSet<Object> set = new BeanSet<>(all());
|
||||
set.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
@@ -224,7 +224,7 @@ public class BeanSetTest {
|
||||
// act
|
||||
set.retainAll(some());
|
||||
|
||||
assertThat(set.getModifyRemovals()).containsExactly(object1);
|
||||
assertThat(set.getModifyRemovals()).containsOnly(object1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.tests.model.orphanremoval;
|
||||
|
||||
import io.ebean.Model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Version;
|
||||
|
||||
@Entity
|
||||
public class OmBeanListChild extends Model {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private final String name;
|
||||
|
||||
@ManyToOne
|
||||
private OmBeanListParent parent;
|
||||
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
public OmBeanListChild(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.tests.model.orphanremoval;
|
||||
|
||||
import io.ebean.Model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Version;
|
||||
import java.util.List;
|
||||
|
||||
import static javax.persistence.CascadeType.ALL;
|
||||
|
||||
@Entity
|
||||
public class OmBeanListParent extends Model {
|
||||
|
||||
@Id
|
||||
private long id;
|
||||
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
@OneToMany(cascade = ALL, mappedBy = "parent", orphanRemoval = true)
|
||||
private List<OmBeanListChild> children;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<OmBeanListChild> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<OmBeanListChild> children) {
|
||||
// So a BeanList is used and overwriting children will replace the table entries
|
||||
this.children.clear();
|
||||
this.children.addAll(children);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package org.tests.model.orphanremoval;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class TestOrphanRemovalOverwrite {
|
||||
|
||||
@Test
|
||||
public void testOverwritingMapping() {
|
||||
OmBeanListParent parent = new OmBeanListParent();
|
||||
parent.save();
|
||||
|
||||
// Refreshing/querying sets the modifyListening flag on the association's BeanList
|
||||
parent.refresh();
|
||||
|
||||
List<OmBeanListChild> childList = singletonList(new OmBeanListChild("child1"));
|
||||
// Adding the children to the BeanList causes _ebean_getIdentity to be invoked before the children have been persisted and
|
||||
// have Ids.
|
||||
parent.setChildren(childList);
|
||||
|
||||
// Give the children Ids
|
||||
parent.save();
|
||||
|
||||
// Refreshing here generates new objects for the associated children that are referred to by the parent.
|
||||
parent.refresh();
|
||||
|
||||
assertNotNull("The children should now have Ids as they are persisted to the db.", childList.get(0).getId());
|
||||
assertEquals("The children should have the same Id as the ones on the parent.",
|
||||
childList.get(0).getId(), parent.getChildren().get(0).getId());
|
||||
assertEquals("The children should therefore equal the children on the parent.", childList, parent.getChildren());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user