From f5459920e97d32cc49496b9a30c637ffef161998 Mon Sep 17 00:00:00 2001 From: rob bygrave Date: Mon, 12 Aug 2019 21:05:32 +1200 Subject: [PATCH] #1785 - Bean gets replaced on json deserialization with primitive 'null' id --- .../server/deploy/BeanDescriptor.java | 4 ++- .../server/deploy/BeanDescriptorJsonHelp.java | 4 ++- .../server/persist/DefaultPersister.java | 6 ++--- .../server/persist/SaveManyBeans.java | 4 ++- .../server/persist/dml/InsertHandler.java | 5 ++-- .../java/org/tests/cascade/RelMaster.java | 6 ++--- .../tests/cascade/TestJsonMarshallingOTM.java | 27 +++++++++++++++++++ 7 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 src/test/java/org/tests/cascade/TestJsonMarshallingOTM.java diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index c42f960a9..cb38766e4 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -112,6 +112,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; import java.util.stream.Collectors; +import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; + /** * Describes Beans including their deployment information. */ @@ -3210,7 +3212,7 @@ public class BeanDescriptor implements BeanType, STreeType { } boolean hasIdValue(EntityBean bean) { - return (idProperty != null && !DmlUtil.isNullOrZero(idProperty.getValue(bean))); + return (idProperty != null && !isNullOrZero(idProperty.getValue(bean))); } boolean hasVersionProperty(EntityBeanIntercept ebi) { diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorJsonHelp.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorJsonHelp.java index a2355bdb9..059b368a0 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorJsonHelp.java +++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorJsonHelp.java @@ -14,6 +14,8 @@ import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; +import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; + class BeanDescriptorJsonHelp { private final BeanDescriptor desc; @@ -158,7 +160,7 @@ class BeanDescriptorJsonHelp { } Object contextBean = null; Object id = desc.beanId(bean); - if (id != null) { + if (!isNullOrZero(id)) { // check if the bean has already been loaded contextBean = readJson.persistenceContextPutIfAbsent(id, bean, desc); } diff --git a/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java b/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java index 6cfd8eb42..e3a93cfad 100644 --- a/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java +++ b/src/main/java/io/ebeaninternal/server/persist/DefaultPersister.java @@ -43,6 +43,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; + /** * Persister implementation using DML. *

@@ -1227,11 +1229,9 @@ public final class DefaultPersister implements Persister { EntityBean bean = request.getEntityBean(); Object uid = idProp.getValue(bean); - if (DmlUtil.isNullOrZero(uid)) { - + if (isNullOrZero(uid)) { // generate the nextId and set it to the property Object nextId = desc.nextId(request.getTransaction()); - // cast the data type if required and set it desc.convertSetId(nextId, bean); } diff --git a/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java b/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java index b7545c163..afbf394cd 100644 --- a/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java +++ b/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java @@ -20,6 +20,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; + /** * Saves the details for a OneToMany or ManyToMany relationship (entity beans). */ @@ -222,7 +224,7 @@ public class SaveManyBeans extends SaveManyBase { } if (detailBean instanceof EntityBean) { Object id = targetDescriptor.getId((EntityBean) detailBean); - if (!DmlUtil.isNullOrZero(id)) { + if (!isNullOrZero(id)) { // remember the Id (other details not in the collection) will be removed detailIds.add(id); } diff --git a/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java b/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java index 7e7541557..a56912651 100644 --- a/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java +++ b/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java @@ -6,7 +6,6 @@ import io.ebeaninternal.api.SpiTransaction; import io.ebeaninternal.server.core.Message; import io.ebeaninternal.server.core.PersistRequestBean; import io.ebeaninternal.server.deploy.BeanDescriptor; -import io.ebeaninternal.server.persist.DmlUtil; import javax.persistence.OptimisticLockException; import javax.persistence.PersistenceException; @@ -15,6 +14,8 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; + /** * Insert bean handler. */ @@ -66,7 +67,7 @@ public class InsertHandler extends DmlHandler { Object idValue = desc.getId(bean); - boolean withId = !DmlUtil.isNullOrZero(idValue); + boolean withId = !isNullOrZero(idValue); // check to see if we are going to use generated keys if (!withId) { diff --git a/src/test/java/org/tests/cascade/RelMaster.java b/src/test/java/org/tests/cascade/RelMaster.java index 37409306a..e7a736b0f 100644 --- a/src/test/java/org/tests/cascade/RelMaster.java +++ b/src/test/java/org/tests/cascade/RelMaster.java @@ -10,7 +10,7 @@ import javax.persistence.Version; public class RelMaster { @Id - Long id; + long id; String name; @@ -20,11 +20,11 @@ public class RelMaster { @ManyToOne(cascade = CascadeType.REMOVE) private RelDetail detail; - public Long getId() { + public long getId() { return id; } - public void setId(Long id) { + public void setId(long id) { this.id = id; } diff --git a/src/test/java/org/tests/cascade/TestJsonMarshallingOTM.java b/src/test/java/org/tests/cascade/TestJsonMarshallingOTM.java new file mode 100644 index 000000000..63e47b301 --- /dev/null +++ b/src/test/java/org/tests/cascade/TestJsonMarshallingOTM.java @@ -0,0 +1,27 @@ +package org.tests.cascade; + +import io.ebean.DB; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestJsonMarshallingOTM { + + @Test + public void test() { + + String json = ("" + + "{ 'masterRel': [" + + " { 'name': 'a' }," + + " { 'name': 'b' }" + + "] }" + ).replaceAll("'", "\""); + + RelDetail bean = DB.json().toBean(RelDetail.class, json); + + final RelMaster m0 = bean.getMasterRel().get(0); + assertThat(m0.getName()).isEqualTo("a"); + final RelMaster m1 = bean.getMasterRel().get(1); + assertThat(m1.getName()).isEqualTo("b"); + } +}