mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge pull request #2235 from ebean-orm/feature/2223
#2223 #2224 Support BeanMap modification via entrySet() and keySet()
This commit is contained in:
@@ -2,18 +2,21 @@ package io.ebean.common;
|
||||
|
||||
import io.ebean.bean.BeanCollection;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.EBasic;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class BeanMapTest {
|
||||
|
||||
Object object1 = new Object();
|
||||
Object object2 = new Object();
|
||||
Object object3 = new Object();
|
||||
private final EBasic object1 = new EBasic("o1");
|
||||
private final EBasic object2 = new EBasic("o2");
|
||||
private final EBasic object3 = new EBasic("o3");
|
||||
private final EBasic object4 = new EBasic("o4");
|
||||
private final EBasic object5 = new EBasic("o5");
|
||||
|
||||
private Map<String, Object> all() {
|
||||
Map<String, Object> all = new LinkedHashMap<>();
|
||||
@@ -174,9 +177,7 @@ public class BeanMapTest {
|
||||
@Test
|
||||
public void testClear_given_someBeansInAdditions() throws Exception {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
map.put("2", object2);
|
||||
map.put("3", object3);
|
||||
|
||||
@@ -188,4 +189,252 @@ public class BeanMapTest {
|
||||
assertThat(map.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void keySet_add_whenModifyListening() {
|
||||
BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
map.keySet().add("3");
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void keySet_add() {
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.keySet().add("3");
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void keySet_addAll_whenModifyListening() {
|
||||
BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
map.keySet().addAll(asList("3", "4"));
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void keySet_addAll() {
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.keySet().addAll(asList("3", "4"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keySet_remove() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.put("2", object2);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
final Set<String> keySet = map.keySet();
|
||||
keySet.remove("1");
|
||||
|
||||
assertThat(keySet.contains("1")).isFalse();
|
||||
assertThat(map).doesNotContainKeys("1");
|
||||
assertThat(map.get("1")).isNull();
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keySet_clear() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.put("2", object2);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
final Set<String> keySet = map.keySet();
|
||||
keySet.clear();
|
||||
|
||||
assertThat(map).isEmpty();
|
||||
assertThat(keySet).isEmpty();
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1, object2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keySet_iterator_remove() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.put("2", object2);
|
||||
map.put("3", object3);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(map).hasSize(2);
|
||||
assertThat(keySet).hasSize(2);
|
||||
assertThat(keySet).containsExactly("1", "3");
|
||||
assertThat(map).containsKeys("1", "3");
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void keySet_removeAll() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.put("2", object2);
|
||||
map.put("3", object3);
|
||||
map.put("4", object4);
|
||||
map.put("5", object5);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
final Set<String> keySet = map.keySet();
|
||||
final boolean changed = keySet.removeAll(asList("2", "3", "5"));
|
||||
|
||||
assertThat(changed).isTrue();
|
||||
assertThat(map).hasSize(2);
|
||||
assertThat(keySet).hasSize(2);
|
||||
assertThat(keySet).containsExactly("1", "4");
|
||||
assertThat(map).containsKeys("1", "4");
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2, object3, object5);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void keySet_retainAll() {
|
||||
|
||||
BeanMap<String, Object> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.put("2", object2);
|
||||
map.put("3", object3);
|
||||
map.put("4", object4);
|
||||
map.put("5", object5);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
final Set<String> keySet = map.keySet();
|
||||
final boolean changed = keySet.retainAll(asList("2", "3", "5"));
|
||||
|
||||
assertThat(changed).isTrue();
|
||||
assertThat(map).hasSize(3);
|
||||
assertThat(keySet).hasSize(3);
|
||||
assertThat(keySet).containsExactly("2", "3", "5");
|
||||
assertThat(map).containsKeys("2", "3", "5");
|
||||
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1, object4);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void values_add() {
|
||||
BeanMap<String, EBasic> map = new BeanMap<>();
|
||||
map.values().add(object3);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void values_addAll() {
|
||||
BeanMap<String, EBasic> map = new BeanMap<>();
|
||||
map.values().addAll(asList(object3, object5));
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void entrySet_add() {
|
||||
newModifyListeningMap()
|
||||
.entrySet()
|
||||
.add(new AbstractMap.SimpleEntry<>("3", object3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entrySet_clear() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
entries.clear();
|
||||
|
||||
assertThat(entries).isEmpty();
|
||||
assertThat(map).isEmpty();
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entrySet_remove() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
|
||||
assertThat(map).hasSize(5);
|
||||
|
||||
final boolean existed1 = entries.remove(new AbstractMap.SimpleEntry<>("1", object1));
|
||||
assertThat(existed1).isTrue();
|
||||
|
||||
final boolean existed22 = entries.remove(new AbstractMap.SimpleEntry<>("22", object1));
|
||||
assertThat(existed22).isFalse();
|
||||
|
||||
assertThat(map).hasSize(4);
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entrySet_remove_whenNotEqualValue() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
|
||||
assertThat(map).hasSize(5);
|
||||
|
||||
final boolean modified = entries.remove(new AbstractMap.SimpleEntry<>("1", object2));
|
||||
assertThat(modified).isFalse();
|
||||
|
||||
assertThat(map).hasSize(5);
|
||||
assertThat(map.getModifyRemovals()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entrySet_iterator_remove() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
final Iterator<Map.Entry<String, EBasic>> iterator = entries.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final Map.Entry<String, EBasic> entry = iterator.next();
|
||||
if (entry.getKey().equals("2") || entry.getKey().equals("5")) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
assertThat(map).hasSize(3);
|
||||
assertThat(entries).hasSize(3);
|
||||
assertThat(map.getModifyRemovals()).containsExactly(object2, object5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entrySet_removeAll() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void entrySet_retainAll() {
|
||||
final BeanMap<String, EBasic> map = newModifyListeningMap5();
|
||||
final Set<Map.Entry<String, EBasic>> entries = map.entrySet();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private BeanMap<String, EBasic> newModifyListeningMap() {
|
||||
BeanMap<String, EBasic> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
return map;
|
||||
}
|
||||
|
||||
private BeanMap<String, EBasic> newModifyListeningMap5() {
|
||||
BeanMap<String, EBasic> map = new BeanMap<>();
|
||||
map.put("1", object1);
|
||||
map.put("2", object2);
|
||||
map.put("3", object3);
|
||||
map.put("4", object4);
|
||||
map.put("5", object5);
|
||||
map.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.tests.model.map;
|
||||
|
||||
import io.ebean.DB;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class BeanMapOrphanRemovalTest {
|
||||
|
||||
@Test
|
||||
public void keySet_retainAll() {
|
||||
|
||||
MpUser user = new MpUser();
|
||||
user.setName("u1");
|
||||
addRoles(user, "r1", "r2", "r3", "r4");
|
||||
DB.save(user);
|
||||
|
||||
final MpUser user1 = DB.find(MpUser.class, user.getId());
|
||||
final Map<String, MpRole> roles = user1.getRoles();
|
||||
assertThat(roles).hasSize(4);
|
||||
|
||||
|
||||
final Set<String> keySet = roles.keySet();
|
||||
keySet.retainAll(Arrays.asList("r2", "r3"));
|
||||
|
||||
DB.save(user1);
|
||||
|
||||
final MpUser user2 = DB.find(MpUser.class, user.getId());
|
||||
final Map<String, MpRole> roles2 = user2.getRoles();
|
||||
assertThat(roles2).hasSize(2);
|
||||
}
|
||||
|
||||
private void addRoles(MpUser user, String... roles){
|
||||
for (String code : roles) {
|
||||
MpRole role = newRole(code);
|
||||
user.getRoles().put(role.getCode(), role);
|
||||
}
|
||||
}
|
||||
|
||||
private MpRole newRole(String code) {
|
||||
MpRole role = new MpRole();
|
||||
role.setCode(code);
|
||||
return role;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
package org.tests.model.map;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MapKey;
|
||||
import javax.persistence.OneToMany;
|
||||
import java.util.HashMap;
|
||||
import javax.persistence.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Entity
|
||||
@@ -16,9 +12,9 @@ public class MpUser {
|
||||
|
||||
private String name;
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL)
|
||||
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
@MapKey(name = "code")
|
||||
public Map<String, MpRole> roles = new HashMap<>();
|
||||
private Map<String, MpRole> roles = new LinkedHashMap<>();
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
|
||||
Reference in New Issue
Block a user