From 442f24124cab70f31800641f88e16d2f4fc0aff5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 17 Nov 2016 17:15:14 +1300 Subject: [PATCH] #879 - Ebean not fetching complete list of attribute beans when equals(Object o) is implemented --- .../java/com/avaje/ebean/common/BeanList.java | 14 +++++- .../com/avaje/ebean/common/BeanListTest.java | 49 ++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/avaje/ebean/common/BeanList.java b/src/main/java/com/avaje/ebean/common/BeanList.java index 37fd9c309..c5616a1e2 100644 --- a/src/main/java/com/avaje/ebean/common/BeanList.java +++ b/src/main/java/com/avaje/ebean/common/BeanList.java @@ -85,11 +85,23 @@ public final class BeanList extends AbstractBeanCollection implements List @Override public void internalAddWithCheck(Object bean) { - if (list == null || !list.contains(bean)) { + if (list == null || !containsInstance(bean)) { internalAdd(bean); } } + /** + * Contains using instance equality for List (specifically not .equals() based). + */ + private boolean containsInstance(Object bean) { + for (Object element : list) { + if (element == bean) { + return true; + } + } + return false; + } + public boolean checkEmptyLazyLoad() { if (list == null) { list = new ArrayList<>(); diff --git a/src/test/java/com/avaje/ebean/common/BeanListTest.java b/src/test/java/com/avaje/ebean/common/BeanListTest.java index 712c5b7ad..6dca3d9ec 100644 --- a/src/test/java/com/avaje/ebean/common/BeanListTest.java +++ b/src/test/java/com/avaje/ebean/common/BeanListTest.java @@ -230,4 +230,51 @@ public class BeanListTest { assertThat(list.getModifyRemovals()).containsExactly(object1); } -} \ No newline at end of file + @Test + public void internalAddWithCheck_when_interestingEquals_usesInstanceEquality() { + + BeanList list = new BeanList<>(); + assertThat(list).hasSize(0); + + SomeBean a = new SomeBean("A"); + list.internalAddWithCheck(a); + list.internalAddWithCheck(a); + assertThat(list).hasSize(1); + + // expect to ignore equals and add as it is a diff instance (aka don't use equals()) + list.internalAddWithCheck(new SomeBean("A")); + assertThat(list).hasSize(2); + + list.internalAddWithCheck(new SomeBean("B")); + assertThat(list).hasSize(3); + } + + /** + * A entity bean with interesting equals implementation. + */ + private static class SomeBean { + + final String val; + + SomeBean(String val) { + this.val = val; + } + + public int hashCode() { + return 42; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other instanceof SomeBean) { + return this.val.equals(((SomeBean)other).val); + } else { + return false; + } + } + } + +}