diff --git a/src/main/java/com/avaje/ebean/annotation/Draft.java b/src/main/java/com/avaje/ebean/annotation/Draft.java
new file mode 100644
index 000000000..26f7c3398
--- /dev/null
+++ b/src/main/java/com/avaje/ebean/annotation/Draft.java
@@ -0,0 +1,19 @@
+package com.avaje.ebean.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a boolean property on a @Draftable bean that indicates if the bean instance is a 'draft' or 'live' bean.
+ * The property is transient and has no underlying DB column.
+ *
+ * For beans returned from an asDraft() query this property will be set to true.
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Draft {
+
+}
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 991ad293c..df81a623a 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java
@@ -163,6 +163,8 @@ public class BeanDescriptor implements MetaBeanInfo, SpiBeanType {
private final boolean draftableElement;
+ private final BeanProperty draft;
+
private final BeanProperty draftDirty;
/**
@@ -403,6 +405,7 @@ public class BeanDescriptor implements MetaBeanInfo, SpiBeanType {
this.softDelete = (softDeleteProperty != null);
this.idProperty = listHelper.getId();
this.versionProperty = listHelper.getVersionProperty();
+ this.draft = listHelper.getDraft();
this.draftDirty = listHelper.getDraftDirty();
this.propMap = listHelper.getPropertyMap();
this.propertiesTransient = listHelper.getTransients();
@@ -1989,6 +1992,16 @@ public class BeanDescriptor implements MetaBeanInfo, SpiBeanType {
return draftableElement;
}
+ /**
+ * Set the draft to true for this entity bean instance.
+ * This bean is being loaded via asDraft() query.
+ */
+ public void setDraft(EntityBean entityBean) {
+ if (draft != null) {
+ draft.setValue(entityBean, true);
+ }
+ }
+
/**
* If there is a @DraftDirty property set it's value on the bean.
*/
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java
index 0f2e02d52..bb0911b11 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java
@@ -224,6 +224,8 @@ public class BeanProperty implements ElPropertyValue {
final boolean jsonDeserialize;
+ final boolean draft;
+
final boolean draftOnly;
final boolean draftDirty;
@@ -262,6 +264,7 @@ public class BeanProperty implements ElPropertyValue {
this.dbInsertable = deploy.isDbInsertable();
this.dbUpdatable = deploy.isDbUpdateable();
this.excludedFromHistory = deploy.isExcludedFromHistory();
+ this.draft = deploy.isDraft();
this.draftDirty = deploy.isDraftDirty();
this.draftOnly = deploy.isDraftOnly();
this.draftReset = deploy.isDraftReset();
@@ -358,6 +361,7 @@ public class BeanProperty implements ElPropertyValue {
this.formula = false;
this.excludedFromHistory = source.excludedFromHistory;
+ this.draft = source.draft;
this.draftDirty = source.draftDirty;
this.draftOnly = source.draftOnly;
this.draftReset = source.draftReset;
@@ -1083,6 +1087,14 @@ public class BeanProperty implements ElPropertyValue {
return draftOnly;
}
+ /**
+ * Return true if this property is a boolean flag on a draftable bean
+ * indicating if the instance is a draft or live bean.
+ */
+ public boolean isDraft() {
+ return draft;
+ }
+
/**
* Return true if this property is a boolean flag only on the draft table
* indicating that when the draft is different from the published row.
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanProperty.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanProperty.java
index 30858aac0..9ef22652e 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanProperty.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanProperty.java
@@ -186,6 +186,7 @@ public class DeployBeanProperty {
private boolean excludedFromHistory;
+ private boolean draft;
private boolean draftOnly;
private boolean draftDirty;
private boolean draftReset;
@@ -657,6 +658,7 @@ public class DeployBeanProperty {
return false;
}
}
+
/**
* Return true if this property is based on a secondary table.
*/
@@ -853,6 +855,15 @@ public class DeployBeanProperty {
this.excludedFromHistory = true;
}
+ public void setDraft() {
+ this.draft = true;
+ this.isTransient = true;
+ }
+
+ public boolean isDraft() {
+ return draft;
+ }
+
public void setDraftOnly() {
this.draftOnly = true;
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java
index 700fe851f..697f13dcd 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java
@@ -28,6 +28,8 @@ public class DeployBeanPropertyLists {
private BeanProperty versionProperty;
+ private BeanProperty draft;
+
private BeanProperty draftDirty;
private final BeanDescriptor> desc;
@@ -136,6 +138,9 @@ public class DeployBeanPropertyLists {
private void allocateToList(BeanProperty prop) {
if (prop.isTransient()) {
transients.add(prop);
+ if (prop.isDraft()) {
+ draft = prop;
+ }
return;
}
if (prop.isId()) {
@@ -293,6 +298,10 @@ public class DeployBeanPropertyLists {
return draftDirty;
}
+ public BeanProperty getDraft() {
+ return draft;
+ }
+
public BeanProperty getSoftDeleteProperty() {
for (BeanProperty prop: nonManys) {
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java
index fde8d0041..d6dcc65a8 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java
@@ -149,6 +149,9 @@ public class AnnotationFields extends AnnotationParser {
util.setLobType(prop);
}
+ if (get(prop, Draft.class) != null) {
+ prop.setDraft();
+ }
if (get(prop, DraftOnly.class) != null) {
prop.setDraftOnly();
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java
index a0a20e710..b64dacb58 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/query/SqlTreeNodeBean.java
@@ -301,6 +301,9 @@ public class SqlTreeNodeBean implements SqlTreeNode {
if (readId && !temporalVersions) {
createListProxies(localDesc, ctx, localBean);
}
+ if (temporalMode == SpiQuery.TemporalMode.DRAFT) {
+ localDesc.setDraft(localBean);
+ }
localDesc.postLoad(localBean);
EntityBeanIntercept ebi = localBean._ebean_getIntercept();