Merge pull request #2491 from ebean-orm/feature/2476-elementCollectionConstructor

#2476 - Fix for element collection on bean with default constructor
This commit is contained in:
Rob Bygrave
2022-01-17 15:41:33 +13:00
committed by GitHub
4 changed files with 172 additions and 5 deletions
@@ -226,7 +226,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> 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<T> extends BeanPropertyAssoc<T> 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.
*/
@@ -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<EcPhone> 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<EcPhone> getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(List<EcPhone> phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
}
@@ -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();
}
}
@@ -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<String> 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();
}
}