From 85c43854985c1ec3e4b4e5526e58506f696a52c5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Tue, 20 Mar 2018 17:24:35 +1300 Subject: [PATCH] #115 - Mapping - Add support for @ElementCollection enhancement Initial support - add simple Set support and Json support for simple List and Set. --- .../deploy/BeanCollectionHelpFactory.java | 13 ++-- .../server/deploy/BeanDescriptor.java | 10 ++- .../server/deploy/BeanDescriptorElement.java | 47 ++++++++++++- .../server/deploy/BeanDescriptorManager.java | 15 +++- .../server/deploy/BeanListHelpElement.java | 9 +-- .../server/deploy/BeanPropertyAssocMany.java | 27 ++++++++ .../deploy/BeanPropertyAssocManyJsonHelp.java | 20 +----- .../deploy/BeanPropertySimpleCollection.java | 27 ++++++++ .../server/deploy/BeanSetHelp.java | 2 +- .../server/deploy/BeanSetHelpElement.java | 30 ++++++++ .../server/deploy/ElementCollector.java | 17 +++++ .../server/deploy/ElementHelp.java | 13 ++++ .../server/deploy/ElementHelpList.java | 27 ++++++++ .../server/deploy/ElementHelpMap.java | 28 ++++++++ .../server/deploy/ElementHelpSet.java | 27 ++++++++ .../deploy/parse/AnnotationAssocManys.java | 21 ++++-- .../model/elementcollection/EcsPerson.java | 68 +++++++++++++++++++ .../TestElementCollectionBasic.java | 10 ++- .../TestElementCollectionBasicSet.java | 59 ++++++++++++++++ 19 files changed, 422 insertions(+), 48 deletions(-) create mode 100644 src/main/java/io/ebeaninternal/server/deploy/BeanSetHelpElement.java create mode 100644 src/main/java/io/ebeaninternal/server/deploy/ElementCollector.java create mode 100644 src/main/java/io/ebeaninternal/server/deploy/ElementHelp.java create mode 100644 src/main/java/io/ebeaninternal/server/deploy/ElementHelpList.java create mode 100644 src/main/java/io/ebeaninternal/server/deploy/ElementHelpMap.java create mode 100644 src/main/java/io/ebeaninternal/server/deploy/ElementHelpSet.java create mode 100644 src/test/java/org/tests/model/elementcollection/EcsPerson.java create mode 100644 src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicSet.java diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionHelpFactory.java b/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionHelpFactory.java index f74a67243..86dd30126 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionHelpFactory.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionHelpFactory.java @@ -18,18 +18,17 @@ public class BeanCollectionHelpFactory { /** * Create the helper based on the many property. */ - public static BeanCollectionHelp create(BeanPropertyAssocMany manyProperty) { + public static BeanCollectionHelp create(BeanPropertyAssocMany many) { - boolean elementCollection = manyProperty.isElementCollection(); - - ManyType manyType = manyProperty.getManyType(); + boolean elementCollection = many.isElementCollection(); + ManyType manyType = many.getManyType(); switch (manyType) { case LIST: - return elementCollection ? new BeanListHelpElement<>(manyProperty) : new BeanListHelp<>(manyProperty); + return elementCollection ? new BeanListHelpElement<>(many) : new BeanListHelp<>(many); case SET: - return new BeanSetHelp<>(manyProperty); + return elementCollection ? new BeanSetHelpElement<>(many) : new BeanSetHelp<>(many); case MAP: - return new BeanMapHelp<>(manyProperty); + return new BeanMapHelp<>(many); default: throw new RuntimeException("Invalid type " + manyType); } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index a7614cbba..6f31713a0 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -406,7 +406,7 @@ public class BeanDescriptor implements BeanType, STreeType { private final BeanDescriptorDraftHelp draftHelp; private final BeanDescriptorCacheHelp cacheHelp; - private final BeanDescriptorJsonHelp jsonHelp; + final BeanDescriptorJsonHelp jsonHelp; private DocStoreBeanAdapter docStoreAdapter; private DocumentMapping docMapping; private boolean docStoreEmbeddedInvalidation; @@ -3330,6 +3330,14 @@ public class BeanDescriptor implements BeanType, STreeType { jsonHelp.jsonWriteDirtyProperties(writeJson, bean, dirtyProps); } + public void jsonWriteElement(SpiJsonWriter ctx, Object element) { + throw new IllegalStateException("Unexpected - expect Element override"); + } + + public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException { + throw new IllegalStateException("Unexpected - expect Element override"); + } + public void jsonWrite(SpiJsonWriter writeJson, EntityBean bean) throws IOException { jsonHelp.jsonWrite(writeJson, bean, null); } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElement.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElement.java index dd793505c..a9c6fa057 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElement.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElement.java @@ -1,15 +1,34 @@ package io.ebeaninternal.server.deploy; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import io.ebean.PersistenceIOException; import io.ebean.bean.EntityBean; import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor; +import io.ebeaninternal.server.text.json.ReadJson; +import io.ebeaninternal.server.text.json.SpiJsonWriter; +import io.ebeaninternal.server.type.ScalarType; + +import java.io.IOException; /** * Bean descriptor used with ElementCollection (where we don't have a mapped type/class). */ -public class BeanDescriptorElement extends BeanDescriptor { +class BeanDescriptorElement extends BeanDescriptor { - public BeanDescriptorElement(BeanDescriptorMap owner, DeployBeanDescriptor deploy) { + private final ScalarType scalarType; + private final ElementHelp elementHelp; + + BeanDescriptorElement(BeanDescriptorMap owner, DeployBeanDescriptor deploy, ElementHelp elementHelp) { super(owner, deploy); + this.elementHelp = elementHelp; + + BeanProperty[] props = propertiesNonTransient(); + if (props.length == 1) { + this.scalarType = props[0].getScalarType(); + } else { + this.scalarType = null; + } } public boolean isElementType() { @@ -21,4 +40,28 @@ public class BeanDescriptorElement extends BeanDescriptor { return new ElementEntityBean(properties); } + public void jsonWriteElement(SpiJsonWriter ctx, Object element) { + try { + scalarType.jsonWrite(ctx.gen(), element); + } catch (IOException e) { + throw new PersistenceIOException(e); + } + } + + public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException { + + JsonParser parser = readJson.getParser(); + ElementCollector add = elementHelp.createCollector(); + do { + JsonToken token = parser.nextToken(); + if (JsonToken.VALUE_NULL == token || JsonToken.END_ARRAY == token) { + break; + } + Object element = scalarType.jsonRead(parser); + add.addElement(element); + } while (true); + + return add.collection(); + } + } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java index 5824612bd..1fbb6a15c 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java @@ -1658,8 +1658,19 @@ public class BeanDescriptorManager implements BeanDescriptorMap { /** * Create a BeanDescriptor for an ElementCollection target. */ - public BeanDescriptor createElementDescriptor(DeployBeanDescriptor elementDescriptor) { - return new BeanDescriptorElement<>(this, elementDescriptor); + public BeanDescriptor createElementDescriptor(DeployBeanDescriptor elementDescriptor, ManyType manyType) { + + return new BeanDescriptorElement<>(this, elementDescriptor, elementHelper(manyType)); + } + + private ElementHelp elementHelper(ManyType manyType) { + switch (manyType) { + case LIST: return new ElementHelpList(); + case SET: return new ElementHelpSet(); + case MAP: return new ElementHelpMap(); + default: + throw new IllegalStateException("manyType unexpected "+manyType); + } } public void visitMetrics(MetricVisitor visitor) { diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanListHelpElement.java b/src/main/java/io/ebeaninternal/server/deploy/BeanListHelpElement.java index 2a0b4de96..8191bd0c6 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanListHelpElement.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanListHelpElement.java @@ -1,7 +1,6 @@ package io.ebeaninternal.server.deploy; import io.ebean.bean.BeanCollection; -import io.ebean.bean.BeanCollectionAdd; import io.ebean.bean.EntityBean; import io.ebeaninternal.server.text.json.SpiJsonWriter; @@ -24,14 +23,8 @@ public class BeanListHelpElement extends BeanListHelp { } } - @Override - public BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey) { - return super.getBeanCollectionAdd(bc, mapKey); - } - @Override void jsonWriteElement(SpiJsonWriter ctx, Object element) { - many.jsonWriteValue(ctx, element); - //targetDescriptor.jsonWrite(ctx, (EntityBean) element); + many.jsonWriteElementValue(ctx, element); } } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index 42d3e0667..392e24e33 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -881,4 +881,31 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc implements ST public BeanCollectionHelp getHelp() { return help; } + + public void jsonWriteElementValue(SpiJsonWriter ctx, Object element) { + throw new IllegalStateException("Never Expected"); + } + + /** + * Read the collection (JSON Array) containing entity beans. + */ + public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException { + BeanCollection collection = createEmpty(parentBean); + BeanCollectionAdd add = getBeanCollectionAdd(collection, null); + do { + EntityBean detailBean = (EntityBean) targetDescriptor.jsonRead(readJson, name); + if (detailBean == null) { + // read the entire array + break; + } + add.addEntityBean(detailBean); + + if (parentBean != null && childMasterProperty != null) { + // bind detail bean back to master via mappedBy property + childMasterProperty.setValue(detailBean, parentBean); + } + } while (true); + + return collection; + } } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java index faa77fb49..b4962a9e6 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java @@ -3,8 +3,6 @@ package io.ebeaninternal.server.deploy; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import io.ebean.bean.BeanCollection; -import io.ebean.bean.BeanCollectionAdd; import io.ebean.bean.EntityBean; import io.ebeaninternal.server.text.json.ReadJson; @@ -57,23 +55,7 @@ class BeanPropertyAssocManyJsonHelp { return; } - BeanCollection collection = many.createEmpty(parentBean); - BeanCollectionAdd add = many.getBeanCollectionAdd(collection, null); - do { - EntityBean detailBean = (EntityBean) many.targetDescriptor.jsonRead(readJson, many.name); - if (detailBean == null) { - // read the entire array - break; - } - add.addEntityBean(detailBean); - - if (parentBean != null && many.childMasterProperty != null) { - // bind detail bean back to master via mappedBy property - many.childMasterProperty.setValue(detailBean, parentBean); - } - } while (true); - - many.setValue(parentBean, collection); + many.setValue(parentBean, many.jsonReadCollection(readJson, parentBean)); } /** diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertySimpleCollection.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertySimpleCollection.java index 69f79bd1c..639f6782a 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertySimpleCollection.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertySimpleCollection.java @@ -1,6 +1,12 @@ package io.ebeaninternal.server.deploy; +import io.ebean.PersistenceIOException; +import io.ebean.bean.EntityBean; import io.ebeaninternal.server.deploy.meta.DeployBeanPropertySimpleCollection; +import io.ebeaninternal.server.text.json.ReadJson; +import io.ebeaninternal.server.text.json.SpiJsonWriter; + +import java.io.IOException; public class BeanPropertySimpleCollection extends BeanPropertyAssocMany { @@ -27,4 +33,25 @@ public class BeanPropertySimpleCollection extends BeanPropertyAssocMany { targetDescriptor = descriptor.getBeanDescriptor(targetType); } } + + /** + * Json write scalar value. + */ + @Override + public void jsonWriteValue(SpiJsonWriter writeJson, Object value) { + try { + scalarType.jsonWrite(writeJson.gen(), value); + } catch (IOException e) { + throw new PersistenceIOException(e); + } + } + + public void jsonWriteElementValue(SpiJsonWriter ctx, Object element) { + elementDescriptor.jsonWriteElement(ctx, element); + } + + @Override + public Object jsonReadCollection(ReadJson readJson, EntityBean parentBean) throws IOException { + return elementDescriptor.jsonReadCollection(readJson, parentBean); + } } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelp.java b/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelp.java index 450ed659a..197cbae0a 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelp.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelp.java @@ -16,7 +16,7 @@ import java.util.Set; /** * Helper specifically for dealing with Sets. */ -public final class BeanSetHelp extends BaseCollectionHelp { +public class BeanSetHelp extends BaseCollectionHelp { /** * When attached to a specific many property. diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelpElement.java b/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelpElement.java new file mode 100644 index 000000000..c490c76e1 --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelpElement.java @@ -0,0 +1,30 @@ +package io.ebeaninternal.server.deploy; + +import io.ebean.bean.BeanCollection; +import io.ebean.bean.EntityBean; +import io.ebeaninternal.server.text.json.SpiJsonWriter; + +/** + * Helper for element collection List. + */ +public class BeanSetHelpElement extends BeanSetHelp { + + BeanSetHelpElement(BeanPropertyAssocMany many) { + super(many); + } + + @Override + public void add(BeanCollection collection, EntityBean bean, boolean withCheck) { + Object elementValue = bean._ebean_getField(0); + if (withCheck) { + collection.internalAddWithCheck(elementValue); + } else { + collection.internalAdd(elementValue); + } + } + + @Override + void jsonWriteElement(SpiJsonWriter ctx, Object element) { + many.jsonWriteElementValue(ctx, element); + } +} diff --git a/src/main/java/io/ebeaninternal/server/deploy/ElementCollector.java b/src/main/java/io/ebeaninternal/server/deploy/ElementCollector.java new file mode 100644 index 000000000..c75cfff80 --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/deploy/ElementCollector.java @@ -0,0 +1,17 @@ +package io.ebeaninternal.server.deploy; + +/** + * Collects (List/Set/Map) of elements. + */ +public interface ElementCollector { + + /** + * Add an element. + */ + void addElement(Object element); + + /** + * Return the populated collection/map. + */ + Object collection(); +} diff --git a/src/main/java/io/ebeaninternal/server/deploy/ElementHelp.java b/src/main/java/io/ebeaninternal/server/deploy/ElementHelp.java new file mode 100644 index 000000000..e73a2eb89 --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/deploy/ElementHelp.java @@ -0,0 +1,13 @@ +package io.ebeaninternal.server.deploy; + +/** + * Helper for handling ElementCollection. + */ +interface ElementHelp { + + /** + * Return a new collector. + */ + ElementCollector createCollector(); + +} diff --git a/src/main/java/io/ebeaninternal/server/deploy/ElementHelpList.java b/src/main/java/io/ebeaninternal/server/deploy/ElementHelpList.java new file mode 100644 index 000000000..6e3f46c34 --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/deploy/ElementHelpList.java @@ -0,0 +1,27 @@ +package io.ebeaninternal.server.deploy; + +import java.util.ArrayList; +import java.util.List; + +class ElementHelpList implements ElementHelp { + + @Override + public ElementCollector createCollector() { + return new Collector(); + } + + private static class Collector implements ElementCollector { + + private List list = new ArrayList<>(); + + @Override + public void addElement(Object element) { + list.add(element); + } + + @Override + public Object collection() { + return list; + } + } +} diff --git a/src/main/java/io/ebeaninternal/server/deploy/ElementHelpMap.java b/src/main/java/io/ebeaninternal/server/deploy/ElementHelpMap.java new file mode 100644 index 000000000..1d8869cfd --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/deploy/ElementHelpMap.java @@ -0,0 +1,28 @@ +package io.ebeaninternal.server.deploy; + +import java.util.LinkedHashMap; +import java.util.Map; + +class ElementHelpMap implements ElementHelp { + + @Override + public ElementCollector createCollector() { + return new Collector(); + } + + private static class Collector implements ElementCollector { + + private Map map = new LinkedHashMap<>(); + + @Override + public void addElement(Object element) { + throw new RuntimeException("asd"); + //map.put() + } + + @Override + public Object collection() { + return map; + } + } +} diff --git a/src/main/java/io/ebeaninternal/server/deploy/ElementHelpSet.java b/src/main/java/io/ebeaninternal/server/deploy/ElementHelpSet.java new file mode 100644 index 000000000..d104b1d31 --- /dev/null +++ b/src/main/java/io/ebeaninternal/server/deploy/ElementHelpSet.java @@ -0,0 +1,27 @@ +package io.ebeaninternal.server.deploy; + +import java.util.LinkedHashSet; +import java.util.Set; + +class ElementHelpSet implements ElementHelp { + + @Override + public ElementCollector createCollector() { + return new Collector(); + } + + private static class Collector implements ElementCollector { + + private Set set = new LinkedHashSet<>(); + + @Override + public void addElement(Object element) { + set.add(element); + } + + @Override + public Object collection() { + return set; + } + } +} diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java index 460901474..eba9a4fbb 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java +++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java @@ -189,14 +189,23 @@ class AnnotationAssocManys extends AnnotationParser { if (fullTableName == null) { fullTableName = descriptor.getBaseTable()+"_"+ CamelCaseHelper.toUnderscoreFromCamel(prop.getName()); } - //namingConvention. + + BeanTable localTable = factory.getBeanTable(descriptor.getBeanType()); + if (collectionTable != null) { + prop.getTableJoin().addJoinColumn(true, collectionTable.joinColumns(), localTable); + } + if (!prop.getTableJoin().hasJoinColumns()) { + BeanProperty localId = localTable.getIdProperty(); + if (localId != null) { + // add foreign key based on convention + String fkColName = namingConvention.getForeignKey(descriptor.getBaseTable(), localId.getName()); + prop.getTableJoin().addJoinColumn(new DeployTableJoinColumn(localId.getDbColumn(), fkColName)); + } + } + BeanTable beanTable = factory.getCollectionBeanTable(fullTableName, prop.getTargetType()); prop.setBeanTable(beanTable); - if (collectionTable != null) { - prop.getTableJoin().addJoinColumn(true, collectionTable.joinColumns(), beanTable); - } - Class elementType = prop.getTargetType(); DeployBeanDescriptor elementDescriptor = factory.createDeployDescriptor(elementType); @@ -220,7 +229,7 @@ class AnnotationAssocManys extends AnnotationParser { Class owningType = prop.getOwningType(); factory.createUnidirectional(elementDescriptor, owningType, beanTable, prop.getTableJoin()); - prop.setElementDescriptor(factory.createElementDescriptor(elementDescriptor)); + prop.setElementDescriptor(factory.createElementDescriptor(elementDescriptor, prop.getManyType())); } /** diff --git a/src/test/java/org/tests/model/elementcollection/EcsPerson.java b/src/test/java/org/tests/model/elementcollection/EcsPerson.java new file mode 100644 index 000000000..f0c854db7 --- /dev/null +++ b/src/test/java/org/tests/model/elementcollection/EcsPerson.java @@ -0,0 +1,68 @@ +package org.tests.model.elementcollection; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Version; +import java.util.LinkedHashSet; +import java.util.Set; + +@Entity +public class EcsPerson { + + @Id + long id; + + String name; + + @ElementCollection + @CollectionTable(name = "ecs_person_phone") + @Column(name = "phone") + Set phoneNumbers = new LinkedHashSet<>(); + + @Version + long version; + + public EcsPerson(String name) { + this.name = name; + } + + @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 Set getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(Set phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } +} diff --git a/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasic.java b/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasic.java index dd5ea2bc3..54ef094cb 100644 --- a/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasic.java +++ b/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasic.java @@ -28,7 +28,7 @@ public class TestElementCollectionBasic extends BaseTestCase { Ebean.find(EcPerson.class).where() .startsWith("name", "Fiona0") .order().asc("id") - .findList(); + .findList(); List phoneNumbers0 = found.get(0).getPhoneNumbers(); List phoneNumbers1 = found.get(1).getPhoneNumbers(); @@ -46,6 +46,12 @@ public class TestElementCollectionBasic extends BaseTestCase { .order().asc("id") .findList(); - System.out.println(found2); + assertThat(found2).hasSize(2); + EcPerson foundFirst = found2.get(0); + String asJson = Ebean.json().toJson(foundFirst); + + EcPerson fromJson = Ebean.json().toBean(EcPerson.class, asJson); + + assertThat(fromJson.getPhoneNumbers()).containsAll(foundFirst.getPhoneNumbers()); } } diff --git a/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicSet.java b/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicSet.java new file mode 100644 index 000000000..946e273f7 --- /dev/null +++ b/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicSet.java @@ -0,0 +1,59 @@ +package org.tests.model.elementcollection; + +import io.ebean.BaseTestCase; +import io.ebean.Ebean; +import org.junit.Test; + +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestElementCollectionBasicSet extends BaseTestCase { + + @Test + public void test() { + + EcsPerson person = new EcsPerson("Fiona021"); + person.getPhoneNumbers().add("021 1234"); + person.getPhoneNumbers().add("021 4321"); + Ebean.save(person); + + + EcsPerson person1 = new EcsPerson("Fiona09"); + person1.getPhoneNumbers().add("09 1234"); + person1.getPhoneNumbers().add("09 4321"); + person1.getPhoneNumbers().add("09 9876"); + Ebean.save(person1); + + List found = + Ebean.find(EcsPerson.class).where() + .startsWith("name", "Fiona0") + .order().asc("id") + .findList(); + + Set phoneNumbers0 = found.get(0).getPhoneNumbers(); + Set phoneNumbers1 = found.get(1).getPhoneNumbers(); + phoneNumbers0.size(); + + assertThat(phoneNumbers0).containsExactly("021 1234", "021 4321"); + assertThat(phoneNumbers1).containsExactly("09 1234", "09 4321", "09 9876"); + + + List found2 = + Ebean.find(EcsPerson.class) + .fetch("phoneNumbers") + .where() + .startsWith("name", "Fiona0") + .order().asc("id") + .findList(); + + assertThat(found2).hasSize(2); + EcsPerson foundFirst = found2.get(0); + String asJson = Ebean.json().toJson(foundFirst); + + EcsPerson fromJson = Ebean.json().toBean(EcsPerson.class, asJson); + + assertThat(fromJson.getPhoneNumbers()).containsAll(foundFirst.getPhoneNumbers()); + } +}