diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java index ceb1f211d..a139912c1 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java +++ b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java @@ -21,6 +21,7 @@ import com.avaje.ebeaninternal.server.persist.PersistExecute; import com.avaje.ebeaninternal.server.transaction.BeanPersistIdMap; import javax.persistence.OptimisticLockException; +import javax.persistence.PersistenceException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -436,6 +437,16 @@ public final class PersistRequestBean extends PersistRequest implements BeanP return beanDescriptor.isDraftable(); } + /** + * Checks for @Draftable entity beans with @Draft property that the bean is a 'draft'. + * Save or Update is not allowed to execute using 'live' beans - must use publish(). + */ + public void checkDraft() { + if (beanDescriptor.isDraftable() && !beanDescriptor.isDraftInstance(entityBean)) { + throw new PersistenceException("Save or update is not allowed on a 'live' bean - only draft beans"); + } + } + /** * Return the parent bean for cascading save with unidirectional relationship. */ @@ -827,4 +838,5 @@ public final class PersistRequestBean extends PersistRequest implements BeanP public boolean isSoftDelete() { return Type.SOFT_DELETE == type; } + } 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 df81a623a..bf5184a3c 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java @@ -2002,6 +2002,17 @@ public class BeanDescriptor implements MetaBeanInfo, SpiBeanType { } } + /** + * Return true if the bean is considered a 'draft' instance. + */ + public boolean isDraftInstance(EntityBean entityBean) { + if (draft != null) { + return Boolean.TRUE == draft.getValue(entityBean); + } + // no draft property - so just ignore the check / return true + return true; + } + /** * If there is a @DraftDirty property set it's value on the bean. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java b/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java index 46d3e476a..658d644d3 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java +++ b/src/main/java/com/avaje/ebeaninternal/server/persist/DefaultPersister.java @@ -354,6 +354,7 @@ public final class DefaultPersister implements Persister { PersistRequestBean req = createRequest(entityBean, t, PersistRequest.Type.UPDATE); req.setDeleteMissingChildren(deleteMissingChildren); + req.checkDraft(); try { req.initTransIfRequiredWithBatchCascade(); if (req.isReference()) {