From 6838b4df4f570aa6ce423a33a8c087c087e11fa5 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 27 Jun 2014 23:07:25 +1200 Subject: [PATCH] Fix for #155 Add markAsDirty() method --- src/main/java/com/avaje/ebean/Ebean.java | 26 ++++++++++++- .../java/com/avaje/ebean/EbeanServer.java | 22 +++++++++++ src/main/java/com/avaje/ebean/Model.java | 24 ++++++++++++ .../server/core/DefaultServer.java | 10 +++++ .../avaje/tests/update/TestMarkAsDirty.java | 37 +++++++++++++++++++ 5 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/avaje/tests/update/TestMarkAsDirty.java diff --git a/src/main/java/com/avaje/ebean/Ebean.java b/src/main/java/com/avaje/ebean/Ebean.java index 01579276b..76ca8670b 100644 --- a/src/main/java/com/avaje/ebean/Ebean.java +++ b/src/main/java/com/avaje/ebean/Ebean.java @@ -475,7 +475,31 @@ public final class Ebean { public static void insert(Collection beans) { serverMgr.getPrimaryServer().insert(beans); } - + + /** + * Marks the entity bean as dirty. + *

+ * This is used so that when a bean that is otherwise unmodified is updated with the version + * property updated. + *

+ * An unmodified bean that is saved or updated is normally skipped and this marks the bean as + * dirty so that it is not skipped. + * + *

+   * 
+   * Customer customer = Ebean.find(Customer, id);
+   * 
+   * // mark the bean as dirty so that a save() or update() will
+   * // increment the version property
+   * Ebean.markAsDirty(customer);
+   * Ebean.save(customer);
+   * 
+   * 
+ */ + public static void markAsDirty(Object bean) throws OptimisticLockException { + serverMgr.getPrimaryServer().markAsDirty(bean); + } + /** * Saves the bean using an update. If you know you are updating a bean then it is preferrable to * use this update() method rather than save(). diff --git a/src/main/java/com/avaje/ebean/EbeanServer.java b/src/main/java/com/avaje/ebean/EbeanServer.java index aeac5f9c6..8bab109bb 100644 --- a/src/main/java/com/avaje/ebean/EbeanServer.java +++ b/src/main/java/com/avaje/ebean/EbeanServer.java @@ -837,6 +837,28 @@ public interface EbeanServer { */ public int save(Collection beans, Transaction transaction) throws OptimisticLockException; + /** + * Marks the entity bean as dirty. + *

+ * This is used so that when a bean that is otherwise unmodified is updated the version + * property is updated. + *

+ * An unmodified bean that is saved or updated is normally skipped and this marks the bean as + * dirty so that it is not skipped. + * + *

+   * 
+   * Customer customer = ebeanServer.find(Customer, id);
+   * 
+   * // mark the bean as dirty so that a save() or update() will
+   * // increment the version property
+   * ebeanServer.markAsDirty(customer);
+   * ebeanServer.save(customer);
+   * 
+   * 
+ */ + public void markAsDirty(Object bean); + /** * Saves the bean using an update. If you know you are updating a bean then it is preferrable to * use this update() method rather than save(). diff --git a/src/main/java/com/avaje/ebean/Model.java b/src/main/java/com/avaje/ebean/Model.java index a6b43ce8d..d9594fac2 100644 --- a/src/main/java/com/avaje/ebean/Model.java +++ b/src/main/java/com/avaje/ebean/Model.java @@ -85,6 +85,30 @@ public abstract class Model { return Ebean.getServer(server); } + /** + * Marks the entity bean as dirty. + *

+ * This is used so that when a bean that is otherwise unmodified is updated the version + * property is updated. + *

+ * An unmodified bean that is saved or updated is normally skipped and this marks the bean as + * dirty so that it is not skipped. + * + *

+   * 
+   * Customer customer = Customer.find.byId(id);
+   * 
+   * // mark the bean as dirty so that a save() or update() will
+   * // increment the version property
+   * customer.markAsDirty();
+   * customer.save();
+   * 
+   * 
+ */ + public void markAsDirty() { + db().markAsDirty(this); + } + /** * Insert or update this entity depending on its state. * diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java index 5e2af4eb4..472caa707 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java @@ -1576,6 +1576,16 @@ public final class DefaultServer implements SpiEbeanServer { persister.save(checkEntityBean(bean), t); } + + @Override + public void markAsDirty(Object bean) { + if (bean instanceof EntityBean == false) { + throw new IllegalArgumentException("This bean is not an EntityBean?"); + } + // mark the bean as dirty (so that an update will not get skipped) + ((EntityBean)bean)._ebean_getIntercept().setDirty(true); + } + /** * Update the bean using the default 'updatesDeleteMissingChildren' setting. */ diff --git a/src/test/java/com/avaje/tests/update/TestMarkAsDirty.java b/src/test/java/com/avaje/tests/update/TestMarkAsDirty.java new file mode 100644 index 000000000..dbca56a69 --- /dev/null +++ b/src/test/java/com/avaje/tests/update/TestMarkAsDirty.java @@ -0,0 +1,37 @@ +package com.avaje.tests.update; + +import java.sql.Timestamp; + +import org.junit.Assert; +import org.junit.Test; + +import com.avaje.ebean.BaseTestCase; +import com.avaje.ebean.Ebean; +import com.avaje.tests.model.basic.EBasicVer; + +public class TestMarkAsDirty extends BaseTestCase { + + @Test + public void test() throws InterruptedException { + + EBasicVer bean = new EBasicVer(); + bean.setName("markAsDirty"); + + Ebean.save(bean); + + Timestamp lastUpdate = bean.getLastUpdate(); + Assert.assertNotNull(lastUpdate); + + Thread.sleep(100); + + // ensure the update occurs and version property is updated/incremented + Ebean.markAsDirty(bean); + Ebean.save(bean); + + Timestamp lastUpdate2 = bean.getLastUpdate(); + Assert.assertNotNull(lastUpdate2); + Assert.assertNotEquals(lastUpdate, lastUpdate2); + + } + +}