diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index 73765d43d..09851725f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -226,7 +226,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc implements ST */ @Override public void addBeanToCollectionWithCreate(EntityBean parentBean, EntityBean detailBean, boolean withCheck) { - BeanCollection bc = (BeanCollection) super.getValue(parentBean); + BeanCollection bc = beanCollection(parentBean); if (bc == null) { bc = help.createEmpty(parentBean); setValue(parentBean, bc); @@ -234,6 +234,15 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc implements ST help.add(bc, detailBean, withCheck); } + private BeanCollection beanCollection(EntityBean parentBean) { + try { + return (BeanCollection) super.getValue(parentBean); + } catch (ClassCastException e) { + // fetching element collection, ok for now + return null; + } + } + /** * Return true if this is considered 'empty' from a save perspective. */ diff --git a/ebean-test/src/test/java/org/tests/model/elementcollection/EcblPerson2.java b/ebean-test/src/test/java/org/tests/model/elementcollection/EcblPerson2.java new file mode 100644 index 000000000..7ce82c393 --- /dev/null +++ b/ebean-test/src/test/java/org/tests/model/elementcollection/EcblPerson2.java @@ -0,0 +1,61 @@ +package org.tests.model.elementcollection; + +import io.ebean.annotation.Cache; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Cache +@Entity +public class EcblPerson2 { + + @Id + long id; + + String name; + + @ElementCollection + @CollectionTable(joinColumns = @JoinColumn(name = "person_id")) + List phoneNumbers = new ArrayList<>(); + + @Version + long version; + + @Override + public String toString() { + return "person id:" + id + " name:" + name + " phs:" + phoneNumbers; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } +} diff --git a/ebean-test/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedListCache.java b/ebean-test/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedListCache.java index f3ec4b24b..80e2d9bd1 100644 --- a/ebean-test/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedListCache.java +++ b/ebean-test/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedListCache.java @@ -9,10 +9,10 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -public class TestElementCollectionEmbeddedListCache extends BaseTestCase { +class TestElementCollectionEmbeddedListCache extends BaseTestCase { @Test - public void test() { + void test() { EcblPerson person = new EcblPerson("CacheL"); person.getPhoneNumbers().add(new EcPhone("64", "021","1234")); @@ -86,12 +86,10 @@ public class TestElementCollectionEmbeddedListCache extends BaseTestCase { assertThat(four.getPhoneNumbers().toString()).contains("61-07-11"); assertThat(four.getPhoneNumbers()).hasSize(1); - DB.delete(four); sql = LoggedSql.collect(); assertThat(sql).hasSize(2); - LoggedSql.stop(); } } diff --git a/ebean-test/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedListCache2.java b/ebean-test/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedListCache2.java new file mode 100644 index 000000000..1a361c33b --- /dev/null +++ b/ebean-test/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedListCache2.java @@ -0,0 +1,99 @@ +package org.tests.model.elementcollection; + +import io.ebean.BaseTestCase; +import io.ebean.DB; +import io.ebean.test.LoggedSql; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class TestElementCollectionEmbeddedListCache2 extends BaseTestCase { + + @Test + void test() { + + EcblPerson2 person = new EcblPerson2(); + person.setName("CacheL"); + person.getPhoneNumbers().add(new EcPhone("64", "021","1234")); + person.getPhoneNumbers().add(new EcPhone("64","021","4321")); + DB.save(person); + + EcblPerson2 one = DB.find(EcblPerson2.class) + .setId(person.getId()) + .fetch("phoneNumbers") + .findOne(); + + LoggedSql.start(); + + one.getPhoneNumbers().size(); + + List sql = LoggedSql.collect(); + assertThat(sql).isEmpty(); + + EcblPerson2 two = DB.find(EcblPerson2.class ) + .setId(person.getId()) + .findOne(); + + two.getPhoneNumbers().size(); + assertThat(two.getPhoneNumbers().toString()).contains("64-021-1234", "64-021-4321"); + + sql = LoggedSql.collect(); + assertThat(sql).isEmpty(); // cache hit + + two.getPhoneNumbers().add(new EcPhone("61", "07", "11")); + two.getPhoneNumbers().remove(1); + + DB.save(two); + + sql = LoggedSql.collect(); + if (isPersistBatchOnCascade()) { + assertThat(sql).hasSize(5); // update of collection only + assertSql(sql.get(0)).contains("delete from ecbl_person2_phone_numbers where person_id=?"); + assertSqlBind(sql.get(1)); + assertSql(sql.get(2)).contains("insert into ecbl_person2_phone_numbers (person_id,country_code,area,phnum) values (?,?,?,?)"); + assertSqlBind(sql, 3, 4); + } else { + assertThat(sql).hasSize(3); // update of collection only + assertSql(sql.get(0)).contains("delete from ecbl_person2_phone_numbers where person_id=?"); + assertSql(sql.get(1)).contains("insert into ecbl_person2_phone_numbers (person_id,country_code,area,phnum) values (?,?,?,?)"); + assertSql(sql.get(2)).contains("insert into ecbl_person2_phone_numbers (person_id,country_code,area,phnum) values (?,?,?,?)"); + } + + EcblPerson2 three = DB.find(EcblPerson2.class ) + .setId(person.getId()) + .findOne(); + + assertThat(three.getPhoneNumbers().toString()).contains("61-07-11", "64-021-1234"); + assertThat(three.getPhoneNumbers()).hasSize(2); + + sql = LoggedSql.collect(); + assertThat(sql).isEmpty(); // cache hit + + + three.setName("mod-3"); + three.getPhoneNumbers().remove(0); + + DB.save(three); + + sql = LoggedSql.collect(); + assertThat(sql).hasSize(5); + + EcblPerson2 four = DB.find(EcblPerson2.class ) + .setId(person.getId()) + .findOne(); + + assertThat(four.getPhoneNumbers().toString()).contains("61-07-11"); + assertThat(four.getPhoneNumbers()).hasSize(1); + + + DB.delete(four); + sql = LoggedSql.collect(); + assertThat(sql).hasSize(2); + + + LoggedSql.stop(); + } +}