From 041324d17764950ef1fa5e73be2256a245f5827c Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 17 Jun 2015 23:16:02 +1200 Subject: [PATCH] #310 - Child bean with @Id long id = 0 ... when cascade saved from parent ... tries to update instead of insert resulting in OptimisticLockingException --- .../server/deploy/BeanDescriptor.java | 9 ++-- .../TestBeanDescriptorHasIdProperty.java | 10 ++-- .../avaje/tests/model/zero/TestWithZero.java | 34 ++++++++++++ .../com/avaje/tests/model/zero/WithZero.java | 53 +++++++++++++++++++ .../tests/model/zero/WithZeroParent.java | 27 ++++++++++ 5 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 src/test/java/com/avaje/tests/model/zero/TestWithZero.java create mode 100644 src/test/java/com/avaje/tests/model/zero/WithZero.java create mode 100644 src/test/java/com/avaje/tests/model/zero/WithZeroParent.java diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java index 4b3ab252c..12c9faba6 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java @@ -28,6 +28,7 @@ import com.avaje.ebeaninternal.server.deploy.id.IdBinder; import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor; import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertyLists; import com.avaje.ebeaninternal.server.el.*; +import com.avaje.ebeaninternal.server.persist.DmlUtil; import com.avaje.ebeaninternal.server.query.CQueryPlan; import com.avaje.ebeaninternal.server.query.CQueryPlanStats.Snapshot; import com.avaje.ebeaninternal.server.query.SplitName; @@ -1714,7 +1715,7 @@ public class BeanDescriptor implements MetaBeanInfo { // not using Id generator so just base on isLoaded() return !ebi.isLoaded(); } - if (!hasIdProperty(ebi)) { + if (!hasIdValue(ebi.getOwner())) { // No Id property means it must be an insert return true; } @@ -1729,9 +1730,9 @@ public class BeanDescriptor implements MetaBeanInfo { public boolean hasIdPropertyOnly(EntityBeanIntercept ebi) { return ebi.hasIdOnly(idPropertyIndex); } - - public boolean hasIdProperty(EntityBeanIntercept ebi) { - return idPropertyIndex > -1 && ebi.isLoadedProperty(idPropertyIndex); + + public boolean hasIdValue(EntityBean bean) { + return (idProperty != null && !DmlUtil.isNullOrZero(idProperty.getValue(bean))); } public boolean hasVersionProperty(EntityBeanIntercept ebi) { diff --git a/src/test/java/com/avaje/ebeaninternal/server/deploy/TestBeanDescriptorHasIdProperty.java b/src/test/java/com/avaje/ebeaninternal/server/deploy/TestBeanDescriptorHasIdProperty.java index d7e116ae4..19dbe0f4a 100644 --- a/src/test/java/com/avaje/ebeaninternal/server/deploy/TestBeanDescriptorHasIdProperty.java +++ b/src/test/java/com/avaje/ebeaninternal/server/deploy/TestBeanDescriptorHasIdProperty.java @@ -35,13 +35,13 @@ public class TestBeanDescriptorHasIdProperty extends BaseTestCase { Order order = new Order(); - Assert.assertFalse(beanDescriptor.hasIdProperty(getIntercept(order))); + Assert.assertFalse(beanDescriptor.hasIdValue(entityBean(order))); Assert.assertFalse(beanDescriptor.hasVersionProperty(getIntercept(order))); order.setId(23); order.setUpdtime(new Timestamp(System.currentTimeMillis())); - Assert.assertTrue(beanDescriptor.hasIdProperty(getIntercept(order))); + Assert.assertTrue(beanDescriptor.hasIdValue(entityBean(order))); Assert.assertTrue(beanDescriptor.hasVersionProperty(getIntercept(order))); } @@ -61,7 +61,11 @@ public class TestBeanDescriptorHasIdProperty extends BaseTestCase { order.setName("custName"); Assert.assertFalse(beanDescriptor.hasIdPropertyOnly(ebi)); } - + + private EntityBean entityBean(Object bean) { + return (EntityBean)bean; + } + private EntityBeanIntercept getIntercept(Object bean) { return ((EntityBean)bean)._ebean_getIntercept(); } diff --git a/src/test/java/com/avaje/tests/model/zero/TestWithZero.java b/src/test/java/com/avaje/tests/model/zero/TestWithZero.java new file mode 100644 index 000000000..3d9efa2fa --- /dev/null +++ b/src/test/java/com/avaje/tests/model/zero/TestWithZero.java @@ -0,0 +1,34 @@ +package com.avaje.tests.model.zero; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class TestWithZero extends BaseTestCase { + + @Test + public void testInsertUpdate() { + + + WithZero withZero = new WithZero(); + assertEquals(0, withZero.getId()); + assertEquals(0, withZero.getVersion()); + assertNull(withZero.getName()); + + WithZeroParent parent = new WithZeroParent(); + parent.getChildren().add(withZero); + + Ebean.save(parent); + + parent.getChildren().add(new WithZero()); + + //withZero.setName("Foo"); + Ebean.save(parent); + + } + + +} diff --git a/src/test/java/com/avaje/tests/model/zero/WithZero.java b/src/test/java/com/avaje/tests/model/zero/WithZero.java new file mode 100644 index 000000000..d5a7dc737 --- /dev/null +++ b/src/test/java/com/avaje/tests/model/zero/WithZero.java @@ -0,0 +1,53 @@ +package com.avaje.tests.model.zero; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Version; + +@Entity +public class WithZero { + + @Id + long id = 0; + + String name = null; + + @ManyToOne + WithZeroParent parent = null; + + @Version + long version = 0; + + 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 WithZeroParent getParent() { + return parent; + } + + public void setParent(WithZeroParent parent) { + this.parent = parent; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } +} diff --git a/src/test/java/com/avaje/tests/model/zero/WithZeroParent.java b/src/test/java/com/avaje/tests/model/zero/WithZeroParent.java new file mode 100644 index 000000000..b0e8f1832 --- /dev/null +++ b/src/test/java/com/avaje/tests/model/zero/WithZeroParent.java @@ -0,0 +1,27 @@ +package com.avaje.tests.model.zero; + +import javax.persistence.*; +import java.util.List; + +@Entity +@Table(name = "parent") +public class WithZeroParent { + @Id + @Column(name = "id") + private int id; + + @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) + private List children; + + public List getChildren() { + return children; + } + + public void setChildren(final List children) { + this.children = children; + } + + public int getId() { + return id; + } +} \ No newline at end of file