From 8890079b80545566f493c84dd4d6943033ece60f Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Thu, 10 Oct 2019 21:32:44 +1300 Subject: [PATCH] #1839 - Fix JSON marshalling of @ElementCollection maps and scalar --- .../ebeaninternal/api/json/SpiJsonWriter.java | 10 ++++++ .../server/deploy/BeanDescriptor.java | 4 +++ .../server/deploy/BeanDescriptorElement.java | 5 +++ .../deploy/BeanDescriptorElementEmbedded.java | 5 +++ .../BeanDescriptorElementEmbeddedMap.java | 22 +++++------- .../BeanDescriptorElementScalarMap.java | 18 ++-------- .../server/deploy/BeanMapHelp.java | 5 +-- .../server/deploy/BeanPropertyAssocMany.java | 9 +++-- .../deploy/BeanPropertyAssocManyJsonHelp.java | 8 ++--- .../server/text/json/WriteJson.java | 31 ++++++++++++++++ .../TestElementCollectionBasicMap.java | 18 ++++++++++ .../TestElementCollectionBasicSet.java | 18 ++++++++++ .../TestElementCollectionEmbeddedList.java | 26 +++++++++++--- .../TestElementCollectionEmbeddedMap.java | 17 +++++++++ .../TestElementCollectionEnumSet.java | 18 ++++++++++ .../tests/query/other/TestOneToManyAsMap.java | 35 +++++++++++++++++++ src/test/resources/ebean.properties | 2 +- 17 files changed, 206 insertions(+), 45 deletions(-) diff --git a/src/main/java/io/ebeaninternal/api/json/SpiJsonWriter.java b/src/main/java/io/ebeaninternal/api/json/SpiJsonWriter.java index 4fd44f183..4d80bc4f7 100644 --- a/src/main/java/io/ebeaninternal/api/json/SpiJsonWriter.java +++ b/src/main/java/io/ebeaninternal/api/json/SpiJsonWriter.java @@ -62,6 +62,16 @@ public interface SpiJsonWriter extends JsonWriter { */ void endAssocMany(); + /** + * Start a Many. + */ + void beginAssocManyMap(String name, boolean elementCollection); + + /** + * End a Many. + */ + void endAssocManyMap(boolean elementCollection); + /** * Write value using underlying Jaskson object mapper if available. */ diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 1d40f53fa..cc12157b7 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -3549,6 +3549,10 @@ public class BeanDescriptor implements BeanType, STreeType { throw new IllegalStateException("Unexpected - expect Element override"); } + public boolean isJsonReadCollection() { + return false; + } + 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 a9541e50f..2f5cb47a8 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElement.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElement.java @@ -21,6 +21,11 @@ abstract class BeanDescriptorElement extends BeanDescriptor { this.elementHelp = elementHelp; } + @Override + public boolean isJsonReadCollection() { + return true; + } + /** * Find and return the first base scalar type (and we expect only 1). */ diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementEmbedded.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementEmbedded.java index 44328c081..c40a1c156 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementEmbedded.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementEmbedded.java @@ -35,6 +35,11 @@ class BeanDescriptorElementEmbedded extends BeanDescriptorElement { } } + @Override + public boolean isJsonReadCollection() { + return false; + } + @Override public void initialiseOther(BeanDescriptorInitContext initContext) { super.initialiseOther(initContext); diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementEmbeddedMap.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementEmbeddedMap.java index c30ff9a33..c57ed26b1 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementEmbeddedMap.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementEmbeddedMap.java @@ -28,10 +28,14 @@ class BeanDescriptorElementEmbeddedMap extends BeanDescriptorElementEmbedded< this.stringKey = String.class.equals(scalarTypeKey.getType()); } + @Override + public boolean isJsonReadCollection() { + return true; + } + @Override @SuppressWarnings("unchecked") public void jsonWriteMapEntry(SpiJsonWriter ctx, Map.Entry entry) throws IOException { - ctx.writeStartObject(); if (stringKey) { Object key = entry.getKey(); String keyName = (key == null) ? "null" : key.toString(); @@ -43,7 +47,6 @@ class BeanDescriptorElementEmbeddedMap extends BeanDescriptorElementEmbedded< ctx.writeFieldName("value"); writeJsonElement(ctx, entry.getValue()); } - ctx.writeEndObject(); } @Override @@ -52,30 +55,21 @@ class BeanDescriptorElementEmbeddedMap extends BeanDescriptorElementEmbedded< JsonParser parser = readJson.getParser(); ElementCollector add = elementHelp.createCollector(); do { - JsonToken token = parser.nextToken(); - if (token != JsonToken.START_OBJECT) { + String fieldName = parser.nextFieldName(); + if (fieldName == null) { break; } if (stringKey) { - String key = parser.nextFieldName(); parser.nextToken(); Object val = readJsonElement(readJson, null); - add.addKeyValue(key, val); - + add.addKeyValue(fieldName, val); } else { parser.nextFieldName(); Object key = scalarTypeKey.jsonRead(parser); - parser.nextFieldName(); Object val = readJsonElement(readJson, null); add.addKeyValue(key, val); } - - token = parser.nextToken(); - if (token != JsonToken.END_OBJECT) { - break; - } - } while (true); return add.collection(); diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementScalarMap.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementScalarMap.java index 96cb172f0..1aa30263c 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementScalarMap.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorElementScalarMap.java @@ -1,7 +1,6 @@ package io.ebeaninternal.server.deploy; import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; import io.ebean.bean.EntityBean; import io.ebeaninternal.api.json.SpiJsonReader; import io.ebeaninternal.api.json.SpiJsonWriter; @@ -35,7 +34,6 @@ class BeanDescriptorElementScalarMap extends BeanDescriptorElement { @Override @SuppressWarnings("unchecked") public void jsonWriteMapEntry(SpiJsonWriter ctx, Map.Entry entry) throws IOException { - ctx.writeStartObject(); if (stringKey) { Object key = entry.getKey(); String keyName = (key == null) ? "null" : key.toString(); @@ -47,7 +45,6 @@ class BeanDescriptorElementScalarMap extends BeanDescriptorElement { ctx.writeFieldName("value"); scalarTypeVal.jsonWrite(ctx.gen(), entry.getValue()); } - ctx.writeEndObject(); } @Override @@ -56,30 +53,21 @@ class BeanDescriptorElementScalarMap extends BeanDescriptorElement { JsonParser parser = readJson.getParser(); ElementCollector add = elementHelp.createCollector(); do { - JsonToken token = parser.nextToken(); - if (token != JsonToken.START_OBJECT) { + String fieldName = parser.nextFieldName(); + if (fieldName == null) { break; } if (stringKey) { - String key = parser.nextFieldName(); parser.nextToken(); Object val = scalarTypeVal.jsonRead(parser); - add.addKeyValue(key, val); - + add.addKeyValue(fieldName, val); } else { parser.nextFieldName(); Object key = scalarTypeKey.jsonRead(parser); - parser.nextFieldName(); Object val = scalarTypeVal.jsonRead(parser); add.addKeyValue(key, val); } - - token = parser.nextToken(); - if (token != JsonToken.END_OBJECT) { - break; - } - } while (true); return add.collection(); diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanMapHelp.java b/src/main/java/io/ebeaninternal/server/deploy/BeanMapHelp.java index f28fa54b9..9a6812d97 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanMapHelp.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanMapHelp.java @@ -163,11 +163,12 @@ public class BeanMapHelp extends BaseCollectionHelp { } if (!map.isEmpty() || ctx.isIncludeEmpty()) { - ctx.beginAssocMany(name); + final boolean elementCollection = many.isElementCollection(); + ctx.beginAssocManyMap(name, elementCollection); for (Entry entry : map.entrySet()) { many.jsonWriteMapEntry(ctx, entry); } - ctx.endAssocMany(); + ctx.endAssocManyMap(elementCollection); } } diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java index 7ee6ca372..eb90b455a 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocMany.java @@ -971,7 +971,11 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc implements ST } void jsonWriteMapEntry(SpiJsonWriter ctx, Map.Entry entry) throws IOException { - elementDescriptor.jsonWriteMapEntry(ctx, entry); + if (elementDescriptor != null) { + elementDescriptor.jsonWriteMapEntry(ctx, entry); + } else { + targetDescriptor.jsonWrite(ctx, (EntityBean)entry.getValue()); + } } void jsonWriteElementValue(SpiJsonWriter ctx, Object element) { @@ -1051,10 +1055,9 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc implements ST */ public Object jsonReadCollection(SpiJsonReader readJson, EntityBean parentBean) throws IOException { - if (elementDescriptor != null && manyType.isMap()) { + if (elementDescriptor != null && elementDescriptor.isJsonReadCollection()) { return elementDescriptor.jsonReadCollection(readJson, parentBean); } - BeanCollection collection = createEmpty(parentBean); BeanCollectionAdd add = getBeanCollectionAdd(collection); do { diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java index 247e113df..0448fb70d 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocManyJsonHelp.java @@ -40,22 +40,18 @@ class BeanPropertyAssocManyJsonHelp { if (!this.many.jsonDeserialize) { return; } - JsonParser parser = readJson.getParser(); JsonToken event = parser.nextToken(); if (JsonToken.VALUE_NULL == event) { return; } - if (many.isTransient()) { jsonReadTransientUsingObjectMapper(readJson, parentBean); return; } - - if (JsonToken.START_ARRAY != event) { - throw new JsonParseException(parser, "Unexpected token " + event + " - expecting start_array"); + if (JsonToken.START_ARRAY != event && JsonToken.START_OBJECT != event) { + throw new JsonParseException(parser, "Unexpected token " + event + " - expecting start array or object"); } - many.setValue(parentBean, many.jsonReadCollection(readJson, parentBean)); } diff --git a/src/main/java/io/ebeaninternal/server/text/json/WriteJson.java b/src/main/java/io/ebeaninternal/server/text/json/WriteJson.java index 2607974fa..91f01effb 100644 --- a/src/main/java/io/ebeaninternal/server/text/json/WriteJson.java +++ b/src/main/java/io/ebeaninternal/server/text/json/WriteJson.java @@ -398,6 +398,37 @@ public class WriteJson implements SpiJsonWriter { } } + @Override + public void beginAssocManyMap(String key, boolean elementCollection) { + try { + pathStack.pushPathKey(key); + if (key != null) { + generator.writeFieldName(key); + } + if (elementCollection) { + generator.writeStartObject(); + } else { + generator.writeStartArray(); + } + } catch (IOException e) { + throw new JsonIOException(e); + } + } + + @Override + public void endAssocManyMap(boolean elementCollection) { + try { + pathStack.pop(); + if (elementCollection) { + generator.writeEndObject(); + } else { + generator.writeEndArray(); + } + } catch (IOException e) { + throw new JsonIOException(e); + } + } + @Override public void writeBean(BeanDescriptor desc, EntityBean bean) { createWriteBean(desc, bean).write(this); diff --git a/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicMap.java b/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicMap.java index 1acc66fb9..a72c3ae0a 100644 --- a/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicMap.java +++ b/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicMap.java @@ -1,6 +1,7 @@ package org.tests.model.elementcollection; import io.ebean.BaseTestCase; +import io.ebean.DB; import io.ebean.Ebean; import org.ebeantest.LoggedSqlCollector; import org.junit.Test; @@ -175,4 +176,21 @@ public class TestElementCollectionBasicMap extends BaseTestCase { assertThat(fromJson.getPhoneNumbers()).containsValues("021 1234", "021 4321"); assertThat(fromJson.getPhoneNumbers().get("home")).isEqualTo("021 1234"); } + + @Test + public void json() { + + EcmPerson person = new EcmPerson("Fiona021"); + person.getPhoneNumbers().put("home", "021 1234"); + person.getPhoneNumbers().put("work", "021 4321"); + + final String asJson = DB.json().toJson(person); + + assertThat(asJson).isEqualTo("{\"name\":\"Fiona021\",\"phoneNumbers\":{\"home\":\"021 1234\",\"work\":\"021 4321\"}}"); + + final EcmPerson fromJson = DB.json().toBean(EcmPerson.class, asJson); + assertThat(fromJson.getName()).isEqualTo("Fiona021"); + assertThat(fromJson.getPhoneNumbers()).hasSize(2); + assertThat(fromJson.getPhoneNumbers().toString()).isEqualTo("BeanMap size[2] map{home=021 1234, work=021 4321}"); + } } diff --git a/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicSet.java b/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicSet.java index ce5ae70d2..084d848ee 100644 --- a/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicSet.java +++ b/src/test/java/org/tests/model/elementcollection/TestElementCollectionBasicSet.java @@ -1,6 +1,7 @@ package org.tests.model.elementcollection; import io.ebean.BaseTestCase; +import io.ebean.DB; import io.ebean.Ebean; import org.ebeantest.LoggedSqlCollector; import org.junit.Test; @@ -170,4 +171,21 @@ public class TestElementCollectionBasicSet extends BaseTestCase { EcsPerson fromJson = Ebean.json().toBean(EcsPerson.class, asJson); assertThat(fromJson.getPhoneNumbers()).containsAll(foundFirst.getPhoneNumbers()); } + + @Test + public void json() { + + EcsPerson person = new EcsPerson("Fiona021"); + person.getPhoneNumbers().add("021 1234"); + person.getPhoneNumbers().add("021 4321"); + + final String asJson = DB.json().toJson(person); + + assertThat(asJson).isEqualTo("{\"name\":\"Fiona021\",\"phoneNumbers\":[\"021 1234\",\"021 4321\"]}"); + + final EcsPerson fromJson = DB.json().toBean(EcsPerson.class, asJson); + assertThat(fromJson.getName()).isEqualTo("Fiona021"); + assertThat(fromJson.getPhoneNumbers()).hasSize(2); + assertThat(fromJson.getPhoneNumbers().toString()).isEqualTo("BeanSet size[2] set[021 1234, 021 4321]"); + } } diff --git a/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedList.java b/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedList.java index a0ae131a3..c7e4f90f4 100644 --- a/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedList.java +++ b/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedList.java @@ -1,6 +1,7 @@ package org.tests.model.elementcollection; import io.ebean.BaseTestCase; +import io.ebean.DB; import io.ebean.Ebean; import org.ebeantest.LoggedSqlCollector; import org.junit.Test; @@ -17,8 +18,8 @@ public class TestElementCollectionEmbeddedList extends BaseTestCase { LoggedSqlCollector.start(); EcblPerson person = new EcblPerson("Fiona64021"); - person.getPhoneNumbers().add(new EcPhone("64", "021","1234")); - person.getPhoneNumbers().add(new EcPhone("64","021","4321")); + person.getPhoneNumbers().add(new EcPhone("64", "021", "1234")); + person.getPhoneNumbers().add(new EcPhone("64", "021", "4321")); Ebean.save(person); List sql = LoggedSqlCollector.current(); @@ -35,8 +36,8 @@ public class TestElementCollectionEmbeddedList extends BaseTestCase { } EcblPerson person1 = new EcblPerson("Fiona6409"); - person1.getPhoneNumbers().add(new EcPhone("61","09","1234")); - person1.getPhoneNumbers().add(new EcPhone("64","09","4321")); + person1.getPhoneNumbers().add(new EcPhone("61", "09", "1234")); + person1.getPhoneNumbers().add(new EcPhone("64", "09", "4321")); Ebean.save(person1); LoggedSqlCollector.current(); @@ -175,4 +176,21 @@ public class TestElementCollectionEmbeddedList extends BaseTestCase { assertThat(phoneString).contains("64-021-1234"); assertThat(phoneString).contains("64-021-4321"); } + + @Test + public void json() { + + EcblPerson person = new EcblPerson("Fiona64021"); + person.getPhoneNumbers().add(new EcPhone("64", "021", "1234")); + person.getPhoneNumbers().add(new EcPhone("64", "021", "4321")); + + final String asJson = DB.json().toJson(person); + + assertThat(asJson).isEqualTo("{\"name\":\"Fiona64021\",\"phoneNumbers\":[{\"countryCode\":\"64\",\"area\":\"021\",\"number\":\"1234\"},{\"countryCode\":\"64\",\"area\":\"021\",\"number\":\"4321\"}]}"); + + final EcblPerson fromJson = DB.json().toBean(EcblPerson.class, asJson); + assertThat(fromJson.getName()).isEqualTo("Fiona64021"); + assertThat(fromJson.getPhoneNumbers()).hasSize(2); + assertThat(fromJson.getPhoneNumbers().toString()).isEqualTo("BeanList size[2] list[64-021-1234, 64-021-4321]"); + } } diff --git a/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedMap.java b/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedMap.java index 45de1a327..3d7b9be2b 100644 --- a/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedMap.java +++ b/src/test/java/org/tests/model/elementcollection/TestElementCollectionEmbeddedMap.java @@ -1,6 +1,7 @@ package org.tests.model.elementcollection; import io.ebean.BaseTestCase; +import io.ebean.DB; import io.ebean.Ebean; import org.ebeantest.LoggedSqlCollector; import org.junit.Test; @@ -167,4 +168,20 @@ public class TestElementCollectionEmbeddedMap extends BaseTestCase { assertThat(phoneString).contains("64-021-4321"); } + @Test + public void json() { + + EcbmPerson person = new EcbmPerson("Fiona64021"); + person.getPhoneNumbers().put("home", new EcPhone("64", "021","1234")); + person.getPhoneNumbers().put("work", new EcPhone("64","021","4321")); + + final String asJson = DB.json().toJson(person); + + assertThat(asJson).isEqualTo("{\"name\":\"Fiona64021\",\"phoneNumbers\":{\"home\":{\"countryCode\":\"64\",\"area\":\"021\",\"number\":\"1234\"},\"work\":{\"countryCode\":\"64\",\"area\":\"021\",\"number\":\"4321\"}}}"); + + final EcbmPerson fromJson = DB.json().toBean(EcbmPerson.class, asJson); + assertThat(fromJson.getName()).isEqualTo("Fiona64021"); + assertThat(fromJson.getPhoneNumbers()).hasSize(2); + assertThat(fromJson.getPhoneNumbers().toString()).isEqualTo("BeanMap size[2] map{home=64-021-1234, work=64-021-4321}"); + } } diff --git a/src/test/java/org/tests/model/elementcollection/TestElementCollectionEnumSet.java b/src/test/java/org/tests/model/elementcollection/TestElementCollectionEnumSet.java index 988097da5..2263c6639 100644 --- a/src/test/java/org/tests/model/elementcollection/TestElementCollectionEnumSet.java +++ b/src/test/java/org/tests/model/elementcollection/TestElementCollectionEnumSet.java @@ -1,6 +1,7 @@ package org.tests.model.elementcollection; import io.ebean.BaseTestCase; +import io.ebean.DB; import io.ebean.Ebean; import org.junit.Test; @@ -30,4 +31,21 @@ public class TestElementCollectionEnumSet extends BaseTestCase { Ebean.save(one); } + + @Test + public void json() { + + EcEnumPerson person = new EcEnumPerson("Enum Person"); + person.getTags().add(EcEnumPerson.Tags.BLUE); + person.getTags().add(EcEnumPerson.Tags.RED); + + final String asJson = DB.json().toJson(person); + + assertThat(asJson).isEqualTo("{\"name\":\"Enum Person\",\"tags\":[\"BLUE\",\"RED\"]}"); + + final EcEnumPerson fromJson = DB.json().toBean(EcEnumPerson.class, asJson); + assertThat(fromJson.getName()).isEqualTo("Enum Person"); + assertThat(fromJson.getTags()).hasSize(2); + assertThat(fromJson.getTags().toString()).isEqualTo("BeanSet size[2] set[BLUE, RED]"); + } } diff --git a/src/test/java/org/tests/query/other/TestOneToManyAsMap.java b/src/test/java/org/tests/query/other/TestOneToManyAsMap.java index a14930a3b..245550bb6 100644 --- a/src/test/java/org/tests/query/other/TestOneToManyAsMap.java +++ b/src/test/java/org/tests/query/other/TestOneToManyAsMap.java @@ -1,14 +1,18 @@ package org.tests.query.other; import io.ebean.BaseTestCase; +import io.ebean.DB; import io.ebean.Ebean; import org.junit.Assert; import org.junit.Test; import org.tests.model.map.MpRole; import org.tests.model.map.MpUser; +import java.util.LinkedHashMap; import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; + public class TestOneToManyAsMap extends BaseTestCase { @Test @@ -39,4 +43,35 @@ public class TestOneToManyAsMap extends BaseTestCase { } + @Test + public void json() { + + Map roles = new LinkedHashMap<>(); + roles.put("r1", newRole(1L, "r1")); + roles.put("r2", newRole(2L, "r2")); + + MpUser u = new MpUser(); + u.setName("myName"); + u.setRoles(roles); + + final String asJson = DB.json().toJson(u); + + assertThat(asJson).isEqualTo("{\"name\":\"myName\",\"roles\":[{\"id\":1,\"code\":\"r1\"},{\"id\":2,\"code\":\"r2\"}]}"); + + final MpUser bean = DB.json().toBean(MpUser.class, asJson); + assertThat(bean.getName()).isEqualTo("myName"); + final Map beanRoles = bean.getRoles(); + assertThat(beanRoles.get("r1").getId()).isEqualTo(1L); + assertThat(beanRoles.get("r1").getCode()).isEqualTo("r1"); + assertThat(beanRoles.get("r2").getId()).isEqualTo(2L); + assertThat(beanRoles.get("r2").getCode()).isEqualTo("r2"); + } + + private MpRole newRole(Long id, String code) { + MpRole role = new MpRole(); + role.setId(id); + role.setCode(code); + return role; + } + } diff --git a/src/test/resources/ebean.properties b/src/test/resources/ebean.properties index c067c5ed7..e08f0f8a0 100644 --- a/src/test/resources/ebean.properties +++ b/src/test/resources/ebean.properties @@ -132,7 +132,7 @@ datasource.hsqldb.databaseUrl=jdbc:hsqldb:mem:tests datasource.hsqldb.databaseDriver=org.hsqldb.jdbcDriver # Set caseSensitiveCollation to false when using -# MySql with case insenstive collation +# MySql with case insensitive collation #ebean.mysql.caseSensitiveCollation=false datasource.mysql.username=unit datasource.mysql.password=unit