From e182190f96a297c59f44c2b112b8bb1c2b4ca548 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Wed, 7 Mar 2018 20:19:48 +1300 Subject: [PATCH] #1339 - Regression: Fix for not throwing OptimisticLockException when loaded bean has @Version property set --- .../io/ebean/bean/EntityBeanIntercept.java | 38 +++++++++++++------ .../java/org/tests/basic/TestIUDVanilla.java | 15 +++++++- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/src/main/java/io/ebean/bean/EntityBeanIntercept.java index 17b1eac73..de6c82456 100644 --- a/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -529,6 +529,16 @@ public final class EntityBeanIntercept implements Serializable { } } + /** + * Set old value but force it to be set regardless if it already has a value. + */ + private void setOriginalValueForce(int propertyIndex, Object value) { + if (origValues == null) { + origValues = new Object[owner._ebean_getPropertyNames().length]; + } + origValues[propertyIndex] = value; + } + /** * For forced update on a 'New' bean set all the loaded properties to changed. */ @@ -901,15 +911,19 @@ public final class EntityBeanIntercept implements Serializable { if (setDirtyState) { setOriginalValue(propertyIndex, origValue); - if (!dirty) { - dirty = true; - if (embeddedOwner != null) { - // Cascade dirty state from Embedded bean to parent bean - embeddedOwner._ebean_getIntercept().setEmbeddedDirty(embeddedOwnerIndex); - } - if (nodeUsageCollector != null) { - nodeUsageCollector.setModified(); - } + setDirtyStatus(); + } + } + + private void setDirtyStatus() { + if (!dirty) { + dirty = true; + if (embeddedOwner != null) { + // Cascade dirty state from Embedded bean to parent bean + embeddedOwner._ebean_getIntercept().setEmbeddedDirty(embeddedOwnerIndex); + } + if (nodeUsageCollector != null) { + nodeUsageCollector.setModified(); } } } @@ -1049,10 +1063,12 @@ public final class EntityBeanIntercept implements Serializable { } /** - * Explicitly set an old value. + * Explicitly set an old value with force (the old value is forced even it is already set). */ public void setOldValue(int propertyIndex, Object oldValue) { - setChangedPropertyValue(propertyIndex, true, oldValue); + setChangedProperty(propertyIndex); + setOriginalValueForce(propertyIndex, oldValue); + setDirtyStatus(); } /** diff --git a/src/test/java/org/tests/basic/TestIUDVanilla.java b/src/test/java/org/tests/basic/TestIUDVanilla.java index f215d1614..f5117c4e7 100644 --- a/src/test/java/org/tests/basic/TestIUDVanilla.java +++ b/src/test/java/org/tests/basic/TestIUDVanilla.java @@ -2,10 +2,12 @@ package org.tests.basic; import io.ebean.BaseTestCase; import io.ebean.Ebean; -import org.tests.model.basic.EBasicVer; import org.junit.Assert; import org.junit.Test; +import org.tests.model.basic.EBasicVer; +import org.tests.model.basic.UTMaster; +import javax.persistence.OptimisticLockException; import java.sql.Timestamp; public class TestIUDVanilla extends BaseTestCase { @@ -66,4 +68,15 @@ public class TestIUDVanilla extends BaseTestCase { Ebean.update(e3); } + + @Test(expected = OptimisticLockException.class) + public void modifyVersion_expect_optimisticLock() { + + UTMaster e0 = new UTMaster("save me"); + Ebean.save(e0); + + // for this case we know 42 should throw OptimisticLockException + e0.setVersion(42); + Ebean.update(e0); + } }