diff --git a/pom.xml b/pom.xml
index 43793b541..beaf1d812 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
org.avaje.ebeanormavaje-ebeanorm
- 3.3.2-SNAPSHOT
+ 4.0.1-RC1-SNAPSHOTjaravaje-ebeanorm
@@ -94,7 +94,7 @@
org.avaje.ebeanormavaje-ebeanorm-agent
- 3.2.2
+ 4.0.1-RC1test
@@ -160,7 +160,6 @@
2.4test
-
diff --git a/src/main/java/com/avaje/ebean/BeanState.java b/src/main/java/com/avaje/ebean/BeanState.java
index fc4e3c371..3bd17068e 100644
--- a/src/main/java/com/avaje/ebean/BeanState.java
+++ b/src/main/java/com/avaje/ebean/BeanState.java
@@ -90,5 +90,5 @@ public interface BeanState {
* the properties that where loaded or null for a fully loaded entity
* bean.
*/
- public void setLoaded(Set loadedProperties);
+ public void setLoaded();
}
\ No newline at end of file
diff --git a/src/main/java/com/avaje/ebean/annotation/ConcurrencyMode.java b/src/main/java/com/avaje/ebean/annotation/ConcurrencyMode.java
index 59730225c..06d5cd7c5 100644
--- a/src/main/java/com/avaje/ebean/annotation/ConcurrencyMode.java
+++ b/src/main/java/com/avaje/ebean/annotation/ConcurrencyMode.java
@@ -13,10 +13,5 @@ public enum ConcurrencyMode {
/**
* Use a version column.
*/
- VERSION,
-
- /**
- * Use all the columns (except Lobs).
- */
- ALL
+ VERSION
}
diff --git a/src/main/java/com/avaje/ebean/bean/BeanCollection.java b/src/main/java/com/avaje/ebean/bean/BeanCollection.java
index 2b7e83342..6f069564d 100644
--- a/src/main/java/com/avaje/ebean/bean/BeanCollection.java
+++ b/src/main/java/com/avaje/ebean/bean/BeanCollection.java
@@ -37,7 +37,7 @@ public interface BeanCollection extends Serializable {
/**
* Return the bean that owns this collection.
*/
- public Object getOwnerBean();
+ public EntityBean getOwnerBean();
/**
* Return the bean property name this collection represents.
diff --git a/src/main/java/com/avaje/ebean/bean/BeanCollectionAdd.java b/src/main/java/com/avaje/ebean/bean/BeanCollectionAdd.java
index 8bc754166..1df602fc8 100644
--- a/src/main/java/com/avaje/ebean/bean/BeanCollectionAdd.java
+++ b/src/main/java/com/avaje/ebean/bean/BeanCollectionAdd.java
@@ -12,5 +12,5 @@ public interface BeanCollectionAdd {
/**
* Add a loaded bean to the collection.
*/
- public void addBean(Object bean);
+ public void addBean(EntityBean bean);
}
diff --git a/src/main/java/com/avaje/ebean/bean/EntityBean.java b/src/main/java/com/avaje/ebean/bean/EntityBean.java
index 701691126..ea39333c8 100644
--- a/src/main/java/com/avaje/ebean/bean/EntityBean.java
+++ b/src/main/java/com/avaje/ebean/bean/EntityBean.java
@@ -14,6 +14,10 @@ import java.io.Serializable;
*/
public interface EntityBean extends Serializable {
+ public String[] _ebean_getPropertyNames();
+
+ public String _ebean_getPropertyName(int pos);
+
/**
* Return the enhancement marker value.
*
@@ -79,31 +83,19 @@ public interface EntityBean extends Serializable {
*/
public Object _ebean_createCopy();
- /**
- * Return the fields in their index order.
- */
- public String[] _ebean_getFieldNames();
-
/**
* Set the value of a field of an entity bean of this type.
*
* Note that using this method bypasses any interception that otherwise occurs
* on entity beans. That means lazy loading and oldValues creation.
*
- *
- * @param fieldIndex
- * the index of the field
- * @param entityBean
- * the entityBean of this type to modify
- * @param value
- * the value to set
*/
- public void _ebean_setField(int fieldIndex, Object entityBean, Object value);
+ public void _ebean_setField(int fieldIndex, Object value);
/**
* Set the field value with interception.
*/
- public void _ebean_setFieldIntercept(int fieldIndex, Object entityBean, Object value);
+ public void _ebean_setFieldIntercept(int fieldIndex, Object value);
/**
* Return the value of a field from an entity bean of this type.
@@ -111,17 +103,12 @@ public interface EntityBean extends Serializable {
* Note that using this method bypasses any interception that otherwise occurs
* on entity beans. That means lazy loading.
*
- *
- * @param fieldIndex
- * the index of the field
- * @param entityBean
- * the entityBean to get the value from
*/
- public Object _ebean_getField(int fieldIndex, Object entityBean);
+ public Object _ebean_getField(int fieldIndex);
/**
* Return the field value with interception.
*/
- public Object _ebean_getFieldIntercept(int fieldIndex, Object entityBean);
+ public Object _ebean_getFieldIntercept(int fieldIndex);
}
diff --git a/src/main/java/com/avaje/ebean/bean/EntityBeanIntercept.java b/src/main/java/com/avaje/ebean/bean/EntityBeanIntercept.java
index ab9fa87c8..fccc5fbce 100644
--- a/src/main/java/com/avaje/ebean/bean/EntityBeanIntercept.java
+++ b/src/main/java/com/avaje/ebean/bean/EntityBeanIntercept.java
@@ -6,7 +6,7 @@ import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.math.BigDecimal;
import java.net.URL;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Set;
import javax.persistence.EntityNotFoundException;
@@ -23,8 +23,12 @@ import com.avaje.ebean.Ebean;
*/
public final class EntityBeanIntercept implements Serializable {
- private static final long serialVersionUID = -3664031775464862648L;
+ private static final long serialVersionUID = -3664031775464862649L;
+ private static final int STATE_NEW = 0;
+ private static final int STATE_REFERENCE = 1;
+ private static final int STATE_LOADED = 2;
+
private transient NodeUsageCollector nodeUsageCollector;
private transient PropertyChangeSupport pcs;
@@ -32,7 +36,7 @@ public final class EntityBeanIntercept implements Serializable {
private transient PersistenceContext persistenceContext;
private transient BeanLoader beanLoader;
-
+
private int beanLoaderIndex;
private String ebeanServerName;
@@ -45,54 +49,43 @@ public final class EntityBeanIntercept implements Serializable {
/**
* The parent bean by relationship (1-1 or 1-M).
*/
- private Object parentBean;
+ private EntityBean embeddedOwner;
+ private int embeddedOwnerIndex;
/**
- * true if the bean properties have been loaded. false if it is a reference
- * bean (will lazy load etc).
+ * One of NEW, REF, UPD.
*/
- private volatile boolean loaded;
-
+ private int state;
+
+ private boolean readOnly;
+
+ private boolean dirty;
+
/**
- * Flag set to disable lazy loading - typically for SQL "report" type entity
- * beans.
+ * Flag set to disable lazy loading - typically for SQL "report" type entity beans.
*/
private boolean disableLazyLoad;
/**
- * Flag set when lazy loading failed due to the underlying bean being deleted
- * in the DB.
+ * Flag set when lazy loading failed due to the underlying bean being deleted in the DB.
*/
private boolean lazyLoadFailure;
- /**
- * Set true when loaded or reference. Used to bypass interception when created
- * by user code.
- */
- private boolean intercepting;
-
- /**
- * The state of the Bean (DEFAULT,UDPATE,READONLY,SHARED).
- */
- private boolean readOnly;
-
- /**
- * The bean as it was before it was modified. Null if no non-transient setters
- * have been called.
- */
- private Object oldValues;
-
/**
* Used when a bean is partially filled.
*/
- private volatile Set loadedProps;
+ private boolean[] loadedProps;
+
+ private boolean fullyLoadedBean;
/**
* Set of changed properties.
*/
- private HashSet changedProps;
+ private boolean[] changedProps;
- private String lazyLoadProperty;
+ private Object[] origValues;
+
+ private int lazyLoadProperty = -1;
/**
* Create a intercept with a given entity.
@@ -100,20 +93,9 @@ public final class EntityBeanIntercept implements Serializable {
* Refer to agent ProxyConstructor.
*
*/
- public EntityBeanIntercept(Object owner) {
- this.owner = (EntityBean) owner;
- }
-
- /**
- * Copy the internal state of the intercept to another intercept.
- */
- public void copyStateTo(EntityBeanIntercept dest) {
- dest.loadedProps = loadedProps;
- dest.ebeanServerName = ebeanServerName;
-
- if (loaded) {
- dest.setLoaded();
- }
+ public EntityBeanIntercept(Object ownerBean) {
+ this.owner = (EntityBean) ownerBean;
+ this.loadedProps = new boolean[owner._ebean_getPropertyNames().length];
}
/**
@@ -123,13 +105,6 @@ public final class EntityBeanIntercept implements Serializable {
return owner;
}
- public String toString() {
- if (!loaded) {
- return "Reference...";
- }
- return "OldValues: " + oldValues;
- }
-
/**
* Return the persistenceContext.
*/
@@ -194,16 +169,17 @@ public final class EntityBeanIntercept implements Serializable {
/**
* Return the parent bean (by relationship).
*/
- public Object getParentBean() {
- return parentBean;
+ public Object getEmbeddedOwner() {
+ return embeddedOwner;
}
/**
* Special case for a OneToOne, Set the parent bean (by relationship). This is
* the owner of a 1-1.
*/
- public void setParentBean(Object parentBean) {
- this.parentBean = parentBean;
+ public void setEmbeddedOwner(EntityBean parentBean, int embeddedOwnerIndex) {
+ this.embeddedOwner = parentBean;
+ this.embeddedOwnerIndex = embeddedOwnerIndex;
}
/**
@@ -234,24 +210,37 @@ public final class EntityBeanIntercept implements Serializable {
this.persistenceContext = ctx;
this.ebeanServerName = beanLoader.getName();
}
+
+ public boolean isFullyLoadedBean() {
+ return fullyLoadedBean;
+ }
+
+ public void setFullyLoadedBean(boolean fullyLoadedBean) {
+ this.fullyLoadedBean = fullyLoadedBean;
+ }
/**
* Return true if this bean has been directly modified (it has oldValues) or
* if any embedded beans are either new or dirty (and hence need saving).
*/
public boolean isDirty() {
- if (oldValues != null) {
- return true;
- }
- // need to check all the embedded beans
- return owner._ebean_isEmbeddedNewOrDirty();
+ return dirty;
+ }
+
+ public void setEmbeddedDirty(int embeddedProperty) {
+ this.dirty = true;
+ setChangedProperty(embeddedProperty);
+ }
+
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
}
/**
* Return true if this entity bean is new and not yet saved.
*/
public boolean isNew() {
- return !intercepting && !loaded;
+ return state == STATE_NEW;
}
/**
@@ -265,22 +254,14 @@ public final class EntityBeanIntercept implements Serializable {
* Return true if the entity is a reference.
*/
public boolean isReference() {
- return intercepting && !loaded;
+ return state == STATE_REFERENCE;
}
/**
* Set this as a reference object.
*/
public void setReference() {
- this.loaded = false;
- this.intercepting = true;
- }
-
- /**
- * Return the old values used for ConcurrencyMode.ALL.
- */
- public Object getOldValues() {
- return oldValues;
+ state = STATE_REFERENCE;
}
/**
@@ -299,33 +280,11 @@ public final class EntityBeanIntercept implements Serializable {
this.readOnly = readOnly;
}
- /**
- * Return true if the bean currently has interception on.
- *
- * With interception on the bean will invoke lazy loading and dirty checking.
- *
- */
- public boolean isIntercepting() {
- return intercepting;
- }
-
- /**
- * Turn interception off or on.
- *
- * This is to support custom serialisation mechanisms that just read all the
- * properties on the bean.
- *
- *
- */
- public void setIntercepting(boolean intercepting) {
- this.intercepting = intercepting;
- }
-
/**
* Return true if the entity has been loaded.
*/
public boolean isLoaded() {
- return loaded;
+ return state == STATE_LOADED;
}
/**
@@ -340,12 +299,12 @@ public final class EntityBeanIntercept implements Serializable {
*
*/
public void setLoaded() {
- this.loaded = true;
- this.oldValues = null;
- this.intercepting = true;
+ this.state = STATE_LOADED;
this.owner._ebean_setEmbeddedLoaded();
- this.lazyLoadProperty = null;
+ this.lazyLoadProperty = -1;
+ this.origValues = null;
this.changedProps = null;
+ this.dirty = false;
}
/**
@@ -353,9 +312,8 @@ public final class EntityBeanIntercept implements Serializable {
* bean.
*/
public void setLoadedLazy() {
- this.loaded = true;
- this.intercepting = true;
- this.lazyLoadProperty = null;
+ this.state = STATE_LOADED;
+ this.lazyLoadProperty = -1;
}
/**
@@ -424,41 +382,128 @@ public final class EntityBeanIntercept implements Serializable {
}
}
- /**
- * Set the property names for a partially loaded bean.
- *
- * @param loadedPropertyNames
- * the names of the loaded properties
- */
- public void setLoadedProps(Set loadedPropertyNames) {
- this.loadedProps = loadedPropertyNames;
+ public String getProperty(int propertyIndex) {
+ if (propertyIndex == -1) {
+ return null;
+ }
+ return owner._ebean_getPropertyName(propertyIndex);
+ }
+
+ public int getPropertyLength() {
+ return owner._ebean_getPropertyNames().length;
+ }
+
+ public void setLoadedProperty(int propertyIndex) {
+ loadedProps[propertyIndex] = true;
+ }
+
+ public boolean isLoadedProperty(int propertyIndex) {
+ return loadedProps[propertyIndex];
+ }
+
+ public boolean isChangedProperty(int propertyIndex) {
+ return (changedProps != null && changedProps[propertyIndex]);
}
+ /**
+ * Explicitly mark a property as having been changed.
+ */
+ public void markPropertyAsChanged(int propertyIndex) {
+ setChangedProperty(propertyIndex);
+ setDirty(true);
+ }
+
+ private void setChangedProperty(int propertyIndex) {
+ if (changedProps == null) {
+ changedProps = new boolean[owner._ebean_getPropertyNames().length];
+ }
+ changedProps[propertyIndex] = true;
+ }
+
+ private void setOriginalValue(int propertyIndex, Object value) {
+ if (origValues == null) {
+ origValues = new Object[owner._ebean_getPropertyNames().length];
+ }
+ if (origValues[propertyIndex] == null) {
+ origValues[propertyIndex] = value;
+ }
+ }
+
+ /**
+ * For forced update on a 'New' bean move set all the changedProperties to loaded properties.
+ */
+ public void setNewBeanForUpdate() {
+
+ for (int i=0; i< loadedProps.length; i++) {
+ if (loadedProps[i]) {
+ setChangedProperty(i);
+ }
+ }
+ setDirty(true);
+ }
+
/**
* Return the set of property names for a partially loaded bean.
*/
- public Set getLoadedProps() {
- return loadedProps;
+ public Set getLoadedPropertyNames() {
+ if (fullyLoadedBean) {
+ return null;
+ }
+ Set props = new LinkedHashSet();
+ for (int i=0; i getChangedPropertyNames() {
+ Set props = new LinkedHashSet();
+ if (changedProps != null) {
+ for (int i=0; i getChangedProps() {
+ public boolean[] getChanged() {
return changedProps;
}
+ public boolean[] getLoaded() {
+ return loadedProps;
+ }
+
/**
* Return the property read or write that triggered the lazy load.
*/
- public String getLazyLoadProperty() {
+ public int getLazyLoadProperty() {
return lazyLoadProperty;
}
/**
* Load the bean when it is a reference.
*/
- protected void loadBean(String loadProperty) {
+ protected void loadBean(int loadProperty) {
synchronized (this) {
if (beanLoader == null) {
@@ -484,29 +529,24 @@ public final class EntityBeanIntercept implements Serializable {
/**
* Invoke the lazy loading. This method is synchronised externally.
*/
- private void loadBeanInternal(String loadProperty, BeanLoader loader) {
+ private void loadBeanInternal(int loadProperty, BeanLoader loader) {
- if (loaded && (loadedProps == null || loadedProps.contains(loadProperty))) {
+ if (loadedProps == null || loadedProps[loadProperty]) {
// race condition where multiple threads calling preGetter concurrently
return;
}
- if (disableLazyLoad) {
- loaded = true;
- return;
- }
-
if (lazyLoadFailure) {
// failed when batch lazy loaded by another bean in the batch
throw new EntityNotFoundException("Bean has been deleted - lazy loading failed");
}
- if (lazyLoadProperty == null) {
+ if (lazyLoadProperty == -1) {
lazyLoadProperty = loadProperty;
if (nodeUsageCollector != null) {
- nodeUsageCollector.setLoadProperty(lazyLoadProperty);
+ nodeUsageCollector.setLoadProperty(getProperty(lazyLoadProperty));
}
loader.loadBean(this);
@@ -521,20 +561,6 @@ public final class EntityBeanIntercept implements Serializable {
}
}
- /**
- * Create a copy of the bean as it is now. This is the original or 'old
- * values' prior to any modification. This is used to perform concurrency
- * testing.
- */
- protected void createOldValues() {
-
- oldValues = owner._ebean_createCopy();
-
- if (nodeUsageCollector != null) {
- nodeUsageCollector.setModified();
- }
- }
-
/**
* Helper method to check if two objects are equal.
*/
@@ -559,7 +585,6 @@ public final class EntityBeanIntercept implements Serializable {
} else {
return false;
}
-
}
if (obj1 instanceof URL) {
// use the string format to determine if dirty
@@ -567,26 +592,21 @@ public final class EntityBeanIntercept implements Serializable {
}
return obj1.equals(obj2);
}
-
+
/**
* Method that is called prior to a getter method on the actual entity.
- *
- * This checks if the bean is a reference and should be loaded.
- *
*/
- public void preGetter(String propertyName) {
- if (!intercepting) {
+ public void preGetter(int propertyIndex) {
+ if (state == STATE_NEW || disableLazyLoad) {
return;
}
-
- if (!loaded) {
- loadBean(propertyName);
- } else if (loadedProps != null && !loadedProps.contains(propertyName)) {
- loadBean(propertyName);
+
+ if (!isLoadedProperty(propertyIndex)) {
+ loadBean(propertyIndex);
}
- if (nodeUsageCollector != null && loaded) {
- nodeUsageCollector.addUsed(propertyName);
+ if (nodeUsageCollector != null) {
+ nodeUsageCollector.addUsed(getProperty(propertyIndex));
}
}
@@ -619,245 +639,211 @@ public final class EntityBeanIntercept implements Serializable {
* OneToMany and ManyToMany don't have any interception so just check for
* PropertyChangeSupport.
*/
- public PropertyChangeEvent preSetterMany(boolean interceptField, String propertyName,
- Object oldValue, Object newValue) {
+ public PropertyChangeEvent preSetterMany(boolean interceptField, int propertyIndex, Object oldValue, Object newValue) {
- // skip setter interception on many's
+ if (readOnly) {
+ throw new IllegalStateException("This bean is readOnly");
+ }
+
+ setLoadedProperty(propertyIndex);
+
+ // Bean itself not considered dirty when many changed
if (pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, oldValue, newValue);
+ return new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
} else {
return null;
}
}
+
+ private void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue) {
- private final void addDirty(String propertyName) {
-
- if (!intercepting) {
- return;
- }
if (readOnly) {
throw new IllegalStateException("This bean is readOnly");
}
+ setChangedProperty(propertyIndex);
- if (loaded) {
- if (oldValues == null) {
- // first time this bean is being made dirty
- createOldValues();
+ 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();
+ }
}
- if (changedProps == null) {
- changedProps = new HashSet();
- }
- changedProps.add(propertyName);
}
}
-
+
/**
* Check to see if the values are not equal. If they are not equal then create
* the old values for use with ConcurrencyMode.ALL.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, Object oldValue,
- Object newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, Object oldValue, Object newValue) {
- boolean changed = !areEqual(oldValue, newValue);
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (!areEqual(oldValue, newValue)) {
+ setChangedPropertyValue(propertyIndex, intercept, newValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, oldValue, newValue);
- }
-
- return null;
+
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
-
+
+
/**
* Check for primitive boolean.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, boolean oldValue,
- boolean newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, boolean oldValue, boolean newValue) {
- boolean changed = oldValue != newValue;
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (oldValue != newValue) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, Boolean.valueOf(oldValue),
- Boolean.valueOf(newValue));
- }
-
- return null;
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
}
/**
* Check for primitive int.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, int oldValue,
- int newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, int oldValue, int newValue) {
- boolean changed = oldValue != newValue;
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (oldValue != newValue) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, Integer.valueOf(oldValue),
- Integer.valueOf(newValue));
- }
- return null;
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Integer.valueOf(oldValue), Integer.valueOf(newValue));
}
/**
* long.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, long oldValue,
- long newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue) {
- boolean changed = oldValue != newValue;
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (oldValue != newValue) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, Long.valueOf(oldValue),
- Long.valueOf(newValue));
- }
- return null;
+
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Long.valueOf(oldValue), Long.valueOf(newValue));
}
/**
* double.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, double oldValue,
- double newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, double oldValue, double newValue) {
- boolean changed = oldValue != newValue;
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (oldValue != newValue) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, Double.valueOf(oldValue),
- Double.valueOf(newValue));
- }
- return null;
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Double.valueOf(oldValue), Double.valueOf(newValue));
}
/**
* float.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, float oldValue,
- float newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, float oldValue, float newValue) {
- boolean changed = oldValue != newValue;
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (oldValue != newValue) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, Float.valueOf(oldValue),
- Float.valueOf(newValue));
- }
- return null;
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Float.valueOf(oldValue), Float.valueOf(newValue));
}
/**
* short.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, short oldValue,
- short newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, short oldValue, short newValue) {
- boolean changed = oldValue != newValue;
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (oldValue != newValue) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, Short.valueOf(oldValue),
- Short.valueOf(newValue));
- }
- return null;
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Short.valueOf(oldValue), Short.valueOf(newValue));
}
/**
* char.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, char oldValue,
- char newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, char oldValue, char newValue) {
- boolean changed = oldValue != newValue;
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (oldValue != newValue) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, Character.valueOf(oldValue),
- Character.valueOf(newValue));
- }
- return null;
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Character.valueOf(oldValue), Character.valueOf(newValue));
}
/**
- * char.
+ * byte.
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, byte oldValue,
- byte newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, byte oldValue, byte newValue) {
- boolean changed = oldValue != newValue;
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (oldValue != newValue) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, Byte.valueOf(oldValue),
- Byte.valueOf(newValue));
- }
- return null;
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), Byte.valueOf(oldValue), Byte.valueOf(newValue));
}
/**
* char[].
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, char[] oldValue,
- char[] newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, char[] oldValue, char[] newValue) {
- boolean changed = !areEqualChars(oldValue, newValue);
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (!areEqualChars(oldValue, newValue)) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, oldValue, newValue);
- }
- return null;
+ return (pcs == null) ? null: new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
/**
* byte[].
*/
- public PropertyChangeEvent preSetter(boolean intercept, String propertyName, byte[] oldValue,
- byte[] newValue) {
+ public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, byte[] oldValue, byte[] newValue) {
- boolean changed = !areEqualBytes(oldValue, newValue);
-
- if (intercept && changed) {
- addDirty(propertyName);
+ if (state == STATE_NEW) {
+ setLoadedProperty(propertyIndex);
+ } else if (!areEqualBytes(oldValue, newValue)) {
+ setChangedPropertyValue(propertyIndex, intercept, oldValue);
+ } else {
+ return null;
}
-
- if (changed && pcs != null) {
- return new PropertyChangeEvent(owner, propertyName, oldValue, newValue);
- }
- return null;
+ return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
}
private static boolean areEqualBytes(byte[] b1, byte[] b2) {
diff --git a/src/main/java/com/avaje/ebean/common/AbstractBeanCollection.java b/src/main/java/com/avaje/ebean/common/AbstractBeanCollection.java
index a9cacd874..265c6541b 100644
--- a/src/main/java/com/avaje/ebean/common/AbstractBeanCollection.java
+++ b/src/main/java/com/avaje/ebean/common/AbstractBeanCollection.java
@@ -12,7 +12,6 @@ import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionLoader;
import com.avaje.ebean.bean.BeanCollectionTouched;
import com.avaje.ebean.bean.EntityBean;
-import com.avaje.ebean.bean.EntityBeanIntercept;
/**
* Base class for List Set and Map implementations of BeanCollection.
@@ -43,7 +42,7 @@ public abstract class AbstractBeanCollection implements BeanCollection {
/**
* The owning bean (used for lazy fetch).
*/
- protected final Object ownerBean;
+ protected final EntityBean ownerBean;
/**
* The name of this property in the owning bean (used for lazy fetch).
@@ -81,19 +80,15 @@ public abstract class AbstractBeanCollection implements BeanCollection {
/**
* Used to create deferred fetch proxy.
*/
- public AbstractBeanCollection(BeanCollectionLoader loader, Object ownerBean, String propertyName) {
+ public AbstractBeanCollection(BeanCollectionLoader loader, EntityBean ownerBean, String propertyName) {
this.loader = loader;
this.ebeanServerName = loader.getName();
this.ownerBean = ownerBean;
this.propertyName = propertyName;
-
- if (ownerBean instanceof EntityBean) {
- EntityBeanIntercept ebi = ((EntityBean) ownerBean)._ebean_getIntercept();
- this.readOnly = ebi.isReadOnly();
- }
+ this.readOnly = ownerBean._ebean_getIntercept().isReadOnly();
}
- public Object getOwnerBean() {
+ public EntityBean getOwnerBean() {
return ownerBean;
}
diff --git a/src/main/java/com/avaje/ebean/common/BeanList.java b/src/main/java/com/avaje/ebean/common/BeanList.java
index d24718ff5..b20a4175f 100644
--- a/src/main/java/com/avaje/ebean/common/BeanList.java
+++ b/src/main/java/com/avaje/ebean/common/BeanList.java
@@ -10,6 +10,7 @@ import java.util.ListIterator;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
+import com.avaje.ebean.bean.EntityBean;
/**
* List capable of lazy loading.
@@ -40,12 +41,12 @@ public final class BeanList extends AbstractBeanCollection implements List
/**
* Used to create deferred fetch proxy.
*/
- public BeanList(BeanCollectionLoader loader, Object ownerBean, String propertyName) {
+ public BeanList(BeanCollectionLoader loader, EntityBean ownerBean, String propertyName) {
super(loader, ownerBean, propertyName);
}
@SuppressWarnings("unchecked")
- public void addBean(Object bean) {
+ public void addBean(EntityBean bean) {
list.add((E) bean);
}
diff --git a/src/main/java/com/avaje/ebean/common/BeanMap.java b/src/main/java/com/avaje/ebean/common/BeanMap.java
index ea257e61a..c72d26604 100644
--- a/src/main/java/com/avaje/ebean/common/BeanMap.java
+++ b/src/main/java/com/avaje/ebean/common/BeanMap.java
@@ -8,6 +8,7 @@ import java.util.Map;
import java.util.Set;
import com.avaje.ebean.bean.BeanCollectionLoader;
+import com.avaje.ebean.bean.EntityBean;
/**
* Map capable of lazy loading.
@@ -33,7 +34,7 @@ public final class BeanMap extends AbstractBeanCollection implements Ma
this(new LinkedHashMap());
}
- public BeanMap(BeanCollectionLoader ebeanServer, Object ownerBean, String propertyName) {
+ public BeanMap(BeanCollectionLoader ebeanServer, EntityBean ownerBean, String propertyName) {
super(ebeanServer, ownerBean, propertyName);
}
diff --git a/src/main/java/com/avaje/ebean/common/BeanSet.java b/src/main/java/com/avaje/ebean/common/BeanSet.java
index 36e2472ea..344415c3a 100644
--- a/src/main/java/com/avaje/ebean/common/BeanSet.java
+++ b/src/main/java/com/avaje/ebean/common/BeanSet.java
@@ -8,6 +8,7 @@ import java.util.Set;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
+import com.avaje.ebean.bean.EntityBean;
/**
* Set capable of lazy loading.
@@ -33,12 +34,12 @@ public final class BeanSet extends AbstractBeanCollection implements Set());
}
- public BeanSet(BeanCollectionLoader loader, Object ownerBean, String propertyName) {
+ public BeanSet(BeanCollectionLoader loader, EntityBean ownerBean, String propertyName) {
super(loader, ownerBean, propertyName);
}
@SuppressWarnings("unchecked")
- public void addBean(Object bean) {
+ public void addBean(EntityBean bean) {
set.add((E) bean);
}
diff --git a/src/main/java/com/avaje/ebean/event/BeanPersistListener.java b/src/main/java/com/avaje/ebean/event/BeanPersistListener.java
index 1b1e1f23d..f38aee387 100644
--- a/src/main/java/com/avaje/ebean/event/BeanPersistListener.java
+++ b/src/main/java/com/avaje/ebean/event/BeanPersistListener.java
@@ -54,7 +54,7 @@ public interface BeanPersistListener {
* @param updatedProperties
* the properties on the bean that where updated
*/
- public boolean updated(T bean, Set updatedProperties);
+ public boolean updated(T bean);//, Set updatedProperties);
/**
* Notified that a bean has been deleted locally. Return true if you want the
diff --git a/src/main/java/com/avaje/ebean/event/BeanPersistRequest.java b/src/main/java/com/avaje/ebean/event/BeanPersistRequest.java
index 97573bcf6..88053c703 100644
--- a/src/main/java/com/avaje/ebean/event/BeanPersistRequest.java
+++ b/src/main/java/com/avaje/ebean/event/BeanPersistRequest.java
@@ -1,7 +1,5 @@
package com.avaje.ebean.event;
-import java.util.Set;
-
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.Transaction;
@@ -24,29 +22,29 @@ public interface BeanPersistRequest {
*/
public Transaction getTransaction();
- /**
- * For an update or delete of a partially populated bean this is the set of
- * loaded properties and otherwise returns null.
- */
- public Set getLoadedProperties();
-
- /**
- * For an update this is the set of properties that where updated.
- */
- public Set getUpdatedProperties();
+// /**
+// * For an update or delete of a partially populated bean this is the set of
+// * loaded properties and otherwise returns null.
+// */
+// public Set getLoadedProperties();
+//
+// /**
+// * For an update this is the set of properties that where updated.
+// */
+// public Set getUpdatedProperties();
/**
* Returns the bean being inserted updated or deleted.
*/
public T getBean();
- /**
- * Returns a bean containing the original values prior to the bean being
- * modified.
- *
- * This is for updates only.
- *
- */
- public T getOldValues();
+// /**
+// * Returns a bean containing the original values prior to the bean being
+// * modified.
+// *
+// * This is for updates only.
+// *
+// */
+// public T getOldValues();
}
diff --git a/src/main/java/com/avaje/ebeaninternal/api/SpiUpdatePlan.java b/src/main/java/com/avaje/ebeaninternal/api/SpiUpdatePlan.java
index 89588954f..9ac23a9af 100644
--- a/src/main/java/com/avaje/ebeaninternal/api/SpiUpdatePlan.java
+++ b/src/main/java/com/avaje/ebeaninternal/api/SpiUpdatePlan.java
@@ -1,9 +1,9 @@
package com.avaje.ebeaninternal.api;
import java.sql.SQLException;
-import java.util.Set;
import com.avaje.ebean.annotation.ConcurrencyMode;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.server.persist.dml.DmlHandler;
import com.avaje.ebeaninternal.server.persist.dmlbind.Bindable;
@@ -21,20 +21,20 @@ import com.avaje.ebeaninternal.server.persist.dmlbind.Bindable;
*/
public interface SpiUpdatePlan {
- /**
- * Return true if the set clause has no columns.
- *
- * Can occur when the only columns updated have a updatable=false in their
- * deployment.
- *
- */
- public boolean isEmptySetClause();
+ /**
+ * Return true if the set clause has no columns.
+ *
+ * Can occur when the only columns updated have a updatable=false in their
+ * deployment.
+ *
+ */
+ public boolean isEmptySetClause();
/**
* Bind given the request and bean. The bean could be the oldValues bean
* when binding a update or delete where clause with ALL concurrency mode.
*/
- public void bindSet(DmlHandler bind, Object bean) throws SQLException;
+ public void bindSet(DmlHandler bind, EntityBean bean) throws SQLException;
/**
* Return the time this plan was created.
@@ -66,10 +66,10 @@ public interface SpiUpdatePlan {
*/
public Bindable getSet();
- /**
- * Return the properties that where changed and should be included in the
- * update statement.
- */
- public Set getProperties();
+// /**
+// * Return the properties that where changed and should be included in the
+// * update statement.
+// */
+// public Set getProperties();
}
\ No newline at end of file
diff --git a/src/main/java/com/avaje/ebeaninternal/server/autofetch/StatisticsNodeUsage.java b/src/main/java/com/avaje/ebeaninternal/server/autofetch/StatisticsNodeUsage.java
index 105b765d2..ff4bc9357 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/autofetch/StatisticsNodeUsage.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/autofetch/StatisticsNodeUsage.java
@@ -86,9 +86,9 @@ public class StatisticsNodeUsage implements Serializable {
}
if ((modified || queryTuningAddVersion) && desc != null) {
- BeanProperty[] versionProps = desc.propertiesVersion();
- if (versionProps.length > 0) {
- pathProps.addToPath(path, versionProps[0].getName());
+ BeanProperty versionProp = desc.getVersionProperty();
+ if (versionProp != null) {
+ pathProps.addToPath(path, versionProp.getName());
}
}
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanData.java b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanData.java
index 53ebf05a1..e08e29ffb 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanData.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanData.java
@@ -1,50 +1,51 @@
package com.avaje.ebeaninternal.server.cache;
-import java.util.Set;
-
public class CachedBeanData {
- private final Object sharableBean;
- private final Set loadedProperties;
- private final Object[] data;
- private final int naturalKeyUpdate;
-
- public CachedBeanData(Object sharableBean, Set loadedProperties, Object[] data, int naturalKeyUpdate) {
- this.sharableBean = sharableBean;
- this.loadedProperties= loadedProperties;
- this.data = data;
- this.naturalKeyUpdate = naturalKeyUpdate;
- }
-
- public Object getSharableBean() {
- return sharableBean;
- }
+ private final Object sharableBean;
+ private final boolean[] loaded;
+ private final Object[] data;
+ private final int naturalKeyUpdate;
- public boolean isNaturalKeyUpdate() {
- return naturalKeyUpdate > -1;
- }
-
- public Object getNaturalKey() {
- return data[naturalKeyUpdate];
- }
+ public CachedBeanData(Object sharableBean, boolean[] loaded, Object[] data, int naturalKeyUpdate) {
+ this.sharableBean = sharableBean;
+ this.loaded = loaded;
+ this.data = data;
+ this.naturalKeyUpdate = naturalKeyUpdate;
+ }
+
+ public Object getSharableBean() {
+ return sharableBean;
+ }
+
+ public boolean isNaturalKeyUpdate() {
+ return naturalKeyUpdate > -1;
+ }
+
+ public Object getNaturalKey() {
+ return data[naturalKeyUpdate];
+ }
+
+ public boolean containsProperty(int propIndex) {
+ return loaded[propIndex];
+ }
+
+ public boolean[] getLoaded() {
+ return loaded;
+ }
+
+ public Object getData(int i) {
+ return data[i];
+ }
+
+ public Object[] copyData() {
+ Object[] dest = new Object[data.length];
+ System.arraycopy(data, 0, dest, 0, data.length);
+ return dest;
+ }
+
+ public boolean isLoaded(int i) {
+ return loaded[i];
+ }
- public boolean containsProperty(String propName) {
- return loadedProperties == null || loadedProperties.contains(propName);
- }
-
- public Object getData(int i){
- return data[i];
- }
-
- public Set getLoadedProperties() {
- return loadedProperties;
- }
-
- public Object[] copyData() {
- Object[] dest = new Object[data.length];
- System.arraycopy(data, 0, dest, 0, data.length);
- return dest;
- }
-
}
-
diff --git a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataFromBean.java b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataFromBean.java
index c2f5025c2..370d79c33 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataFromBean.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataFromBean.java
@@ -1,8 +1,5 @@
package com.avaje.ebeaninternal.server.cache;
-import java.util.HashSet;
-import java.util.Set;
-
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.bean.EntityBeanIntercept;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
@@ -10,94 +7,73 @@ import com.avaje.ebeaninternal.server.deploy.BeanProperty;
public class CachedBeanDataFromBean {
- private final BeanDescriptor> desc;
- private final Object bean;
- private final EntityBeanIntercept ebi;
-
- private final Set loadedProps;
- private final Set extractProps;
+ private final BeanDescriptor> desc;
+ private final EntityBean bean;
+ private final EntityBeanIntercept ebi;
- public static CachedBeanData extract(BeanDescriptor> desc, Object bean){
- if (bean instanceof EntityBean){
- return new CachedBeanDataFromBean(desc, bean, ((EntityBean)bean)._ebean_getIntercept()).extract();
-
- } else {
- return new CachedBeanDataFromBean(desc, bean, null).extract();
- }
- }
-
- public static CachedBeanData extract(BeanDescriptor> desc, Object bean, EntityBeanIntercept ebi){
- return new CachedBeanDataFromBean(desc, bean, ebi).extract();
- }
-
- private CachedBeanDataFromBean(BeanDescriptor> desc, Object bean, EntityBeanIntercept ebi) {
- this.desc = desc;
- this.bean = bean;
- this.ebi = ebi;
- if (ebi != null){
- this.loadedProps = ebi.getLoadedProps();
- this.extractProps = (loadedProps == null) ? null : new HashSet();
- } else {
- this.extractProps = new HashSet();
- this.loadedProps = null;
- }
- }
-
- private CachedBeanData extract(){
+ public static CachedBeanData extract(BeanDescriptor> desc, EntityBean bean) {
+ return new CachedBeanDataFromBean(desc, bean, bean._ebean_getIntercept()).extract();
+ }
- BeanProperty[] props = desc.propertiesNonMany();
+ private CachedBeanDataFromBean(BeanDescriptor> desc, EntityBean bean, EntityBeanIntercept ebi) {
+ this.desc = desc;
+ this.bean = bean;
+ this.ebi = ebi;
+ }
- Object[] data = new Object[props.length];
-
- int naturalKeyUpdate = -1;
- for (int i = 0; i < props.length; i++) {
- BeanProperty prop = props[i];
- if (includeNonManyProperty(prop.getName())){
-
- data[i] = prop.getCacheDataValue(bean);
- if (prop.isNaturalKey()) {
- naturalKeyUpdate = i;
- }
- if (ebi != null){
- if (extractProps != null){
- extractProps.add(prop.getName());
- }
- } else if (data[i] != null){
- if (extractProps != null){
- extractProps.add(prop.getName());
- }
- }
- }
- }
-
- Object sharableBean = null;
- if (desc.isCacheSharableBeans() && ebi != null && loadedProps == null){
- if (ebi.isReadOnly()){
- sharableBean = bean;
- } else {
- // create a readOnly sharable instance by copying the data
- sharableBean = desc.createBean();
- BeanProperty[] propertiesId = desc.propertiesId();
- for (int i = 0; i < propertiesId.length; i++) {
- Object v = propertiesId[i].getValue(bean);
- propertiesId[i].setValue(sharableBean, v);
- }
- BeanProperty[] propertiesNonTransient = desc.propertiesNonTransient();
- for (int i = 0; i < propertiesNonTransient.length; i++) {
- Object v = propertiesNonTransient[i].getValue(bean);
- propertiesNonTransient[i].setValue(sharableBean, v);
- }
- EntityBeanIntercept ebi = ((EntityBean)sharableBean)._ebean_intercept();
- ebi.setReadOnly(true);
- ebi.setLoaded();
- }
- }
-
- return new CachedBeanData(sharableBean, extractProps, data, naturalKeyUpdate);
- }
+ private CachedBeanData extract() {
+
+ Object[] data = new Object[desc.getPropertyCount()];
+ boolean[] loaded = new boolean[desc.getPropertyCount()];
- private boolean includeNonManyProperty(String name) {
- return loadedProps == null || loadedProps.contains(name);
+ BeanProperty[] props = desc.propertiesNonMany();
+
+ int naturalKeyUpdate = -1;
+ for (int i = 0; i < props.length; i++) {
+ BeanProperty prop = props[i];
+ if (isLoaded(prop)) {
+ int propertyIndex = prop.getPropertyIndex();
+ data[propertyIndex] = prop.getCacheDataValue(bean);
+ loaded[propertyIndex] = true;
+ if (prop.isNaturalKey()) {
+ naturalKeyUpdate = propertyIndex;
+ }
+ }
}
+
+ EntityBean sharableBean = createSharableBean();
+
+ return new CachedBeanData(sharableBean, loaded, data, naturalKeyUpdate);
+ }
+
+ private EntityBean createSharableBean() {
+ if (!desc.isCacheSharableBeans() || !ebi.isFullyLoadedBean()) {
+ return null;
+ }
+ if (ebi.isReadOnly()) {
+ return bean;
+ }
+ // create a readOnly sharable instance by copying the data
+ EntityBean sharableBean = desc.createBean();
+ BeanProperty[] propertiesId = desc.propertiesId();
+ for (int i = 0; i < propertiesId.length; i++) {
+ Object v = propertiesId[i].getValue(bean);
+ propertiesId[i].setValue(sharableBean, v);
+ }
+ BeanProperty[] propertiesNonTransient = desc.propertiesNonTransient();
+ for (int i = 0; i < propertiesNonTransient.length; i++) {
+ Object v = propertiesNonTransient[i].getValue(bean);
+ propertiesNonTransient[i].setValue(sharableBean, v);
+ }
+ EntityBeanIntercept ebi = ((EntityBean) sharableBean)._ebean_intercept();
+ ebi.setReadOnly(true);
+ ebi.setLoaded();
+ return sharableBean;
+ }
+
+ private boolean isLoaded(BeanProperty prop) {
+ return ebi.isLoadedProperty(prop.getPropertyIndex());
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataToBean.java b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataToBean.java
index 5199d8375..db3082753 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataToBean.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataToBean.java
@@ -1,8 +1,5 @@
package com.avaje.ebeaninternal.server.cache;
-import java.util.HashSet;
-import java.util.Set;
-
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.bean.EntityBeanIntercept;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
@@ -11,107 +8,55 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
public class CachedBeanDataToBean {
- private final BeanDescriptor> desc;
- private final Object bean;
- private final EntityBeanIntercept ebi;
- private final CachedBeanData cacheBeandata;
- private final Set cacheLoadedProperties;
- private final Set loadedProps;
-
- private final Set excludeProps;
- private final Object oldValuesBean;
- private final boolean readOnly;
+ private final BeanDescriptor> desc;
+ private final EntityBean bean;
+ private final EntityBeanIntercept ebi;
+ private final CachedBeanData cacheBeanData;
+ //private final boolean readOnly;
- public static void load(BeanDescriptor> desc, Object bean, CachedBeanData cacheBeandata) {
- if (bean instanceof EntityBean){
- load(desc, bean, ((EntityBean)bean)._ebean_getIntercept(), cacheBeandata);
- } else {
- load(desc, bean, null, cacheBeandata);
- }
- }
+ public static boolean load(BeanDescriptor> desc, EntityBean bean, CachedBeanData cacheBeandata) {
+ return new CachedBeanDataToBean(desc, bean, ((EntityBean) bean)._ebean_getIntercept(), cacheBeandata).load();
+ }
- public static void load(BeanDescriptor> desc, Object bean, EntityBeanIntercept ebi, CachedBeanData cacheBeandata) {
- new CachedBeanDataToBean(desc, bean, ebi, cacheBeandata).load();
- }
-
- private CachedBeanDataToBean(BeanDescriptor> desc, Object bean, EntityBeanIntercept ebi, CachedBeanData cacheBeandata) {
- this.desc = desc;
- this.bean = bean;
- this.ebi = ebi;
- this.cacheBeandata = cacheBeandata;
- this.cacheLoadedProperties = cacheBeandata.getLoadedProperties();
- this.loadedProps = (cacheLoadedProperties == null) ? null : new HashSet();
-
- if (ebi != null){
- this.excludeProps = ebi.getLoadedProps();
- this.oldValuesBean = ebi.getOldValues();
- this.readOnly = ebi.isReadOnly();
+ private CachedBeanDataToBean(BeanDescriptor> desc, EntityBean bean, EntityBeanIntercept ebi, CachedBeanData cacheBeandata) {
+ this.desc = desc;
+ this.bean = bean;
+ this.ebi = ebi;
+ this.cacheBeanData = cacheBeandata;
+ //this.readOnly = ebi.isReadOnly();
+ }
+
+ private boolean load() {
+
+ BeanProperty[] props = desc.propertiesNonMany();
+ for (int i = 0; i < props.length; i++) {
+
+ BeanProperty prop = props[i];
+ int propertyIndex = prop.getPropertyIndex();
+ if (cacheBeanData.isLoaded(propertyIndex)) {
+ if (ebi.isLoadedProperty(propertyIndex)) {
+ // already loaded (lazy load on partially loaded bean)
} else {
- this.excludeProps = null;
- this.oldValuesBean = null;
- this.readOnly = false;
+ Object data = cacheBeanData.getData(propertyIndex);
+ prop.setCacheDataValue(bean, data);
}
+ }
}
-
- private boolean load(){
-
- BeanProperty[] propertiesNonTransient = desc.propertiesNonMany();
- for (int i = 0; i < propertiesNonTransient.length; i++) {
- BeanProperty prop = propertiesNonTransient[i];
- if (includeNonManyProperty(prop.getName())){
- Object data = cacheBeandata.getData(i);
- prop.setCacheDataValue(bean, data, oldValuesBean, readOnly);
- }
- }
- BeanPropertyAssocMany>[] manys = desc.propertiesMany();
- for (int i = 0; i < manys.length; i++) {
- BeanPropertyAssocMany> prop = manys[i];
- if (includeManyProperty(prop.getName())){
- // set a lazy loading proxy
- prop.createReference(bean);
- }
- }
-
- if (ebi != null){
- if (loadedProps == null){
- ebi.setLoadedProps(null);
- } else {
- HashSet mergeProps = new HashSet();
- if (excludeProps != null) {
- mergeProps.addAll(excludeProps);
- }
- mergeProps.addAll(loadedProps);
- ebi.setLoadedProps(mergeProps);
- }
- ebi.setLoadedLazy();
- }
- return true;
+ BeanPropertyAssocMany>[] manys = desc.propertiesMany();
+ for (int i = 0; i < manys.length; i++) {
+ BeanPropertyAssocMany> prop = manys[i];
+ if (ebi.isLoadedProperty(prop.getPropertyIndex())) {
+ // already loaded property
+ } else {
+ // set a lazy loading proxy
+ prop.createReference(bean);
+ }
}
-
- private boolean includeManyProperty(String name) {
- if (excludeProps != null && excludeProps.contains(name)){
- // ignore this property (partial bean lazy loading)
- return false;
- }
- if (loadedProps != null){
- loadedProps.add(name);
- }
- return true;
- }
-
- private boolean includeNonManyProperty(String name) {
- if (excludeProps != null && excludeProps.contains(name)){
- // ignore this property (partial bean lazy loading)
- return false;
- }
- if (cacheLoadedProperties != null && !cacheLoadedProperties.contains(name)){
- return false;
- }
- if (loadedProps != null){
- loadedProps.add(name);
- }
- return true;
- }
-
+
+ ebi.setLoadedLazy();
+
+ return true;
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataUpdate.java b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataUpdate.java
index 93c883213..dbe0a8d94 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataUpdate.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/cache/CachedBeanDataUpdate.java
@@ -11,37 +11,38 @@ public class CachedBeanDataUpdate {
public static CachedBeanData update(BeanDescriptor> desc, CachedBeanData data, PersistRequestBean> updateRequest){
-
- Set loadedProperties = data.getLoadedProperties();
- Object[] copyOfData = data.copyData();
-
- Object updateBean = updateRequest.getBean();
- Set updatedProperties = updateRequest.getUpdatedProperties();
-
- int naturalKeyUpdate = -1;
- boolean mergeProperties = false;
- BeanProperty[] props = desc.propertiesNonMany();
- for (int i = 0; i < props.length; i++) {
- if (updatedProperties.contains(props[i].getName())){
- if (props[i].isNaturalKey()){
- naturalKeyUpdate = i;
- }
- copyOfData[i] = props[i].getCacheDataValue(updateBean);
- if (loadedProperties != null && !mergeProperties && !loadedProperties.contains(props[i].getName())){
- mergeProperties = true;
- }
- }
- }
-
- if (mergeProperties){
- HashSet mergeProps = new HashSet();
- mergeProps.addAll(loadedProperties);
- mergeProps.addAll(updatedProperties);
- loadedProperties = mergeProps;
- }
-
- return new CachedBeanData(null, loadedProperties, copyOfData, naturalKeyUpdate);
+//
+// Set loadedProperties = data.getLoadedProperties();
+// Object[] copyOfData = data.copyData();
+//
+// Object updateBean = updateRequest.getBean();
+// Set updatedProperties = updateRequest.getUpdatedProperties();
+//
+// int naturalKeyUpdate = -1;
+// boolean mergeProperties = false;
+// BeanProperty[] props = desc.propertiesNonMany();
+// for (int i = 0; i < props.length; i++) {
+// if (updatedProperties.contains(props[i].getName())){
+// if (props[i].isNaturalKey()){
+// naturalKeyUpdate = i;
+// }
+// copyOfData[i] = props[i].getCacheDataValue(updateBean);
+// if (loadedProperties != null && !mergeProperties && !loadedProperties.contains(props[i].getName())){
+// mergeProperties = true;
+// }
+// }
+// }
+//
+// if (mergeProperties){
+// HashSet mergeProps = new HashSet();
+// mergeProps.addAll(loadedProperties);
+// mergeProps.addAll(updatedProperties);
+// loadedProperties = mergeProps;
+// }
+//
+// return new CachedBeanData(null, loadedProperties, copyOfData, naturalKeyUpdate);
+ return null;
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/BootupClasses.java b/src/main/java/com/avaje/ebeaninternal/server/core/BootupClasses.java
index 138b52d8c..301544693 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/BootupClasses.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/BootupClasses.java
@@ -11,7 +11,6 @@ import javax.persistence.Table;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import com.avaje.ebean.config.CompoundType;
import com.avaje.ebean.config.ScalarTypeConverter;
import com.avaje.ebean.config.ServerConfig;
@@ -52,6 +51,7 @@ public class BootupClasses implements ClassPathSearchMatcher {
private ArrayList> beanQueryAdapterList = new ArrayList>();
+
private ArrayList> serverConfigStartupList = new ArrayList>();
private ArrayList serverConfigStartupInstances = new ArrayList();
@@ -311,7 +311,7 @@ public class BootupClasses implements ClassPathSearchMatcher {
} else if (isEntity(cls)) {
entityList.add(cls);
-
+
} else if (isInterestingInterface(cls)) {
return true;
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultBeanLoader.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultBeanLoader.java
index f8623f419..8deeb4b57 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultBeanLoader.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultBeanLoader.java
@@ -73,7 +73,7 @@ public class DefaultBeanLoader {
return batchSize;
}
- public void refreshMany(Object parentBean, String propertyName) {
+ public void refreshMany(EntityBean parentBean, String propertyName) {
refreshMany(parentBean, propertyName, null);
}
@@ -92,7 +92,7 @@ public class DefaultBeanLoader {
for (int i = 0; i < batch.size(); i++) {
BeanCollection> bc = batch.get(i);
- Object ownerBean = bc.getOwnerBean();
+ EntityBean ownerBean = bc.getOwnerBean();
Object id = many.getParentId(ownerBean);
idList.add(id);
}
@@ -143,7 +143,7 @@ public class DefaultBeanLoader {
public void loadMany(BeanCollection> bc, boolean onlyIds) {
- Object parentBean = bc.getOwnerBean();
+ EntityBean parentBean = bc.getOwnerBean();
String propertyName = bc.getPropertyName();
//ObjectGraphNode node = ctx == null ? null : ctx.getObjectGraphNode();
@@ -151,11 +151,11 @@ public class DefaultBeanLoader {
loadManyInternal(parentBean, propertyName, null, false, null, onlyIds);
}
- public void refreshMany(Object parentBean, String propertyName, Transaction t) {
+ public void refreshMany(EntityBean parentBean, String propertyName, Transaction t) {
loadManyInternal(parentBean, propertyName, t, true, null, false);
}
- private void loadManyInternal(Object parentBean, String propertyName, Transaction t, boolean refresh, ObjectGraphNode node, boolean onlyIds) {
+ private void loadManyInternal(EntityBean parentBean, String propertyName, Transaction t, boolean refresh, ObjectGraphNode node, boolean onlyIds) {
EntityBeanIntercept ebi = ((EntityBean) parentBean)._ebean_getIntercept();
PersistenceContext pc = ebi.getPersistenceContext();
@@ -267,7 +267,7 @@ public class DefaultBeanLoader {
for (int i = 0; i < batch.size(); i++) {
EntityBeanIntercept ebi = batch.get(i);
- Object bean = ebi.getOwner();
+ EntityBean bean = ebi.getOwner();
Object id = desc.getId(bean);
idList.add(id);
}
@@ -290,17 +290,6 @@ public class DefaultBeanLoader {
PersistenceContext persistenceContext = ctx.getPersistenceContext();
- // query the database
- for (int i = 0; i < ebis.length; i++) {
- Object parentBean = ebis[i].getParentBean();
- if (parentBean != null) {
- // Special case for OneToOne
- BeanDescriptor> parentDesc = server.getBeanDescriptor(parentBean.getClass());
- Object parentId = parentDesc.getId(parentBean);
- persistenceContext.put(parentId, parentBean);
- }
- }
-
SpiQuery> query = (SpiQuery>) server.createQuery(beanType);
query.setMode(Mode.LAZYLOAD_BEAN);
@@ -323,7 +312,7 @@ public class DefaultBeanLoader {
if (loadRequest.isLoadCache()) {
for (int i = 0; i < list.size(); i++) {
- desc.cachePutBeanData(list.get(i));
+ desc.cachePutBeanData((EntityBean)list.get(i));
}
}
@@ -336,7 +325,7 @@ public class DefaultBeanLoader {
}
}
- public void refresh(Object bean) {
+ public void refresh(EntityBean bean) {
refreshBeanInternal(bean, SpiQuery.Mode.REFRESH_BEAN);
}
@@ -344,7 +333,7 @@ public class DefaultBeanLoader {
refreshBeanInternal(ebi.getOwner(), SpiQuery.Mode.LAZYLOAD_BEAN);
}
- private void refreshBeanInternal(Object bean, SpiQuery.Mode mode) {
+ private void refreshBeanInternal(EntityBean bean, SpiQuery.Mode mode) {
EntityBeanIntercept ebi = ((EntityBean) bean)._ebean_getIntercept();;
PersistenceContext pc = ebi.getPersistenceContext();
@@ -364,7 +353,7 @@ public class DefaultBeanLoader {
if (ebi != null) {
if (SpiQuery.Mode.LAZYLOAD_BEAN.equals(mode) && desc.isBeanCaching()) {
// lazy loading and the bean cache is active
- if (desc.loadFromCache(bean, ebi, id)) {
+ if (desc.loadFromCache((EntityBean)bean, ebi, id)) {
return;
}
}
@@ -375,15 +364,8 @@ public class DefaultBeanLoader {
SpiQuery> query = (SpiQuery>) server.createQuery(desc.getBeanType());
if (ebi != null) {
- Object parentBean = ebi.getParentBean();
- if (parentBean != null) {
- // Special case for OneToOne
- BeanDescriptor> parentDesc = server.getBeanDescriptor(parentBean.getClass());
- Object parentId = parentDesc.getId(parentBean);
- pc.putIfAbsent(parentId, parentBean);
- }
-
- query.setLazyLoadProperty(ebi.getLazyLoadProperty());
+ int propIndex = ebi.getLazyLoadProperty();
+ query.setLazyLoadProperty(ebi.getProperty(propIndex));
}
// don't collect autoFetch usage profiling information
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultBeanState.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultBeanState.java
index b0980925d..cfea34803 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultBeanState.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultBeanState.java
@@ -1,7 +1,6 @@
package com.avaje.ebeaninternal.server.core;
import java.beans.PropertyChangeListener;
-import java.util.Collections;
import java.util.Set;
import com.avaje.ebean.BeanState;
@@ -39,14 +38,12 @@ public class DefaultBeanState implements BeanState {
}
public Set getLoadedProps() {
- Set props = intercept.getLoadedProps();
- return props == null ? null : Collections.unmodifiableSet(props);
+ return intercept.getLoadedPropertyNames();
}
public Set getChangedProps() {
- Set props = intercept.getChangedProps();
- return props == null ? null : Collections.unmodifiableSet(props);
- }
+ return intercept.getChangedPropertyNames();
+ }
public boolean isReadOnly() {
return intercept.isReadOnly();
@@ -64,9 +61,8 @@ public class DefaultBeanState implements BeanState {
entityBean.removePropertyChangeListener(listener);
}
- public void setLoaded(Set loadedProperties) {
- intercept.setLoadedProps(loadedProperties);
- intercept.setLoaded();
+ public void setLoaded() {
+ intercept.setLoaded();
}
public void setReference() {
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 63fdfafc0..70cf41634 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultServer.java
@@ -121,6 +121,10 @@ public final class DefaultServer implements SpiEbeanServer {
private static final Logger logger = LoggerFactory.getLogger(DefaultServer.class);
+ private static final int IGNORE_LEADING_ELEMENTS = 5;
+
+ private static final String AVAJE_EBEAN = Ebean.class.getName().substring(0, 15);
+
private final String serverName;
private final DatabasePlatform databasePlatform;
@@ -522,12 +526,12 @@ public final class DefaultServer implements SpiEbeanServer {
public void refreshMany(Object parentBean, String propertyName, Transaction t) {
- beanLoader.refreshMany(parentBean, propertyName, t);
+ beanLoader.refreshMany(checkEntityBean(parentBean), propertyName, t);
}
public void refreshMany(Object parentBean, String propertyName) {
- beanLoader.refreshMany(parentBean, propertyName);
+ beanLoader.refreshMany(checkEntityBean(parentBean), propertyName);
}
public void loadMany(LoadManyRequest loadRequest) {
@@ -542,7 +546,7 @@ public final class DefaultServer implements SpiEbeanServer {
public void refresh(Object bean) {
- beanLoader.refresh(bean);
+ beanLoader.refresh(checkEntityBean(bean));
}
public void loadBean(LoadBeanRequest loadRequest) {
@@ -674,7 +678,7 @@ public final class DefaultServer implements SpiEbeanServer {
} else {
// use the default reference options
- ref = desc.createReference(null, id, null);
+ ref = desc.createReference(null, id);
}
if (ctx != null && (ref instanceof EntityBean)) {
@@ -1604,10 +1608,8 @@ public final class DefaultServer implements SpiEbeanServer {
* Save the bean with an explicit transaction.
*/
public void save(Object bean, Transaction t) {
- if (bean == null) {
- throw new NullPointerException(Message.msg("bean.isnull"));
- }
- persister.save(bean, t);
+
+ persister.save(checkEntityBean(bean), t);
}
/**
@@ -1645,10 +1647,8 @@ public final class DefaultServer implements SpiEbeanServer {
* include in the update.
*/
public void update(Object bean, Set updateProps, Transaction t, boolean deleteMissingChildren, boolean updateNullProperties) {
- if (bean == null) {
- throw new NullPointerException(Message.msg("bean.isnull"));
- }
- persister.forceUpdate(bean, updateProps, t, deleteMissingChildren, updateNullProperties);
+
+ persister.forceUpdate(checkEntityBean(bean), updateProps, t, deleteMissingChildren, updateNullProperties);
}
/**
@@ -1674,12 +1674,19 @@ public final class DefaultServer implements SpiEbeanServer {
*
*/
public void insert(Object bean, Transaction t) {
+ persister.forceInsert(checkEntityBean(bean), t);
+ }
+
+ private EntityBean checkEntityBean(Object bean) {
if (bean == null) {
throw new NullPointerException(Message.msg("bean.isnull"));
}
- persister.forceInsert(bean, t);
+ if (bean instanceof EntityBean == false) {
+ throw new IllegalArgumentException("Was expecting an EntityBean but got a "+bean.getClass());
+ }
+ return (EntityBean)bean;
}
-
+
/**
* Delete the associations (from the intersection table) of a ManyToMany given
* the owner bean and the propertyName of the ManyToMany collection.
@@ -1700,10 +1707,11 @@ public final class DefaultServer implements SpiEbeanServer {
*/
public int deleteManyToManyAssociations(Object ownerBean, String propertyName, Transaction t) {
+ EntityBean owner = checkEntityBean(ownerBean);
TransWrapper wrap = initTransIfRequired(t);
try {
SpiTransaction trans = wrap.transaction;
- int rc = persister.deleteManyToManyAssociations(ownerBean, propertyName, trans);
+ int rc = persister.deleteManyToManyAssociations(owner, propertyName, trans);
wrap.commitIfCreated();
return rc;
@@ -1727,11 +1735,12 @@ public final class DefaultServer implements SpiEbeanServer {
*/
public void saveManyToManyAssociations(Object ownerBean, String propertyName, Transaction t) {
+ EntityBean owner = checkEntityBean(ownerBean);
TransWrapper wrap = initTransIfRequired(t);
try {
SpiTransaction trans = wrap.transaction;
- persister.saveManyToManyAssociations(ownerBean, propertyName, trans);
+ persister.saveManyToManyAssociations(owner, propertyName, trans);
wrap.commitIfCreated();
@@ -1747,21 +1756,12 @@ public final class DefaultServer implements SpiEbeanServer {
public void saveAssociation(Object ownerBean, String propertyName, Transaction t) {
- if (ownerBean instanceof EntityBean) {
- Set loadedProps = ((EntityBean) ownerBean)._ebean_getIntercept().getLoadedProps();
- if (loadedProps != null && !loadedProps.contains(propertyName)) {
- // skip as property is not actually loaded in this partially
- // loaded bean
- logger.debug("Skip saveAssociation as property " + propertyName + " is not loaded");
- return;
- }
- }
-
+ EntityBean owner = checkEntityBean(ownerBean);
+
TransWrapper wrap = initTransIfRequired(t);
try {
SpiTransaction trans = wrap.transaction;
-
- persister.saveAssociation(ownerBean, propertyName, trans);
+ persister.saveAssociation(owner, propertyName, trans);
wrap.commitIfCreated();
@@ -1797,7 +1797,7 @@ public final class DefaultServer implements SpiEbeanServer {
SpiTransaction trans = wrap.transaction;
int saveCount = 0;
while (it.hasNext()) {
- Object bean = it.next();
+ EntityBean bean = checkEntityBean(it.next());
persister.save(bean, trans);
saveCount++;
}
@@ -1861,10 +1861,8 @@ public final class DefaultServer implements SpiEbeanServer {
* Delete the bean with the explicit transaction.
*/
public void delete(Object bean, Transaction t) {
- if (bean == null) {
- throw new NullPointerException(Message.msg("bean.isnull"));
- }
- persister.delete(bean, t);
+
+ persister.delete(checkEntityBean(bean), t);
}
/**
@@ -1892,7 +1890,7 @@ public final class DefaultServer implements SpiEbeanServer {
SpiTransaction trans = wrap.transaction;
int deleteCount = 0;
while (it.hasNext()) {
- Object bean = it.next();
+ EntityBean bean = checkEntityBean(it.next());
persister.delete(bean, trans);
deleteCount++;
}
@@ -1995,13 +1993,14 @@ public final class DefaultServer implements SpiEbeanServer {
}
public Object getBeanId(Object bean) {
+ EntityBean eb = checkEntityBean(bean);
BeanDescriptor> desc = getBeanDescriptor(bean.getClass());
if (desc == null) {
String m = bean.getClass().getName() + " is NOT an Entity Bean registered with this server?";
throw new PersistenceException(m);
}
- return desc.getId(bean);
+ return desc.getId(eb);
}
/**
@@ -2067,8 +2066,6 @@ public final class DefaultServer implements SpiEbeanServer {
return transactionManager.createQueryTransaction();
}
- private static final int IGNORE_LEADING_ELEMENTS = 5;
- private static final String AVAJE_EBEAN = Ebean.class.getName().substring(0, 15);
/**
* Create a CallStack object.
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DiffHelp.java b/src/main/java/com/avaje/ebeaninternal/server/core/DiffHelp.java
index 90d586a05..7dbb1721f 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/DiffHelp.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/DiffHelp.java
@@ -37,30 +37,30 @@ public class DiffHelp {
// get the old values from a
if (a instanceof EntityBean) {
EntityBean eb = (EntityBean) a;
- b = eb._ebean_getIntercept().getOldValues();
+ b = null;//FIXME eb._ebean_getIntercept().getOldValues();
oldValues = true;
}
}
Map map = new LinkedHashMap();
- if (b == null) {
- return map;
- }
-
- // check the simple properties
- BeanProperty[] base = desc.propertiesBaseScalar();
- for (int i = 0; i < base.length; i++) {
-
- Object aval = base[i].getValue(a);
- Object bval = base[i].getValue(b);
- if (!ValueUtil.areEqual(aval, bval)) {
- map.put(base[i].getName(), new ValuePair(aval, bval));
- }
- }
-
- diffAssocOne(a, b, desc, map);
- diffEmbedded(a, b, desc, map, oldValues);
+// if (b == null) {
+// return map;
+// }
+//
+// // check the simple properties
+// BeanProperty[] base = desc.propertiesBaseScalar();
+// for (int i = 0; i < base.length; i++) {
+//
+// Object aval = base[i].getValue(a);
+// Object bval = base[i].getValue(b);
+// if (!ValueUtil.areEqual(aval, bval)) {
+// map.put(base[i].getName(), new ValuePair(aval, bval));
+// }
+// }
+//
+// diffAssocOne(a, b, desc, map);
+// diffEmbedded(a, b, desc, map, oldValues);
return map;
}
@@ -75,40 +75,40 @@ public class DiffHelp {
private void diffEmbedded(Object a, Object b, BeanDescriptor> desc, Map map,
boolean oldValues) {
- BeanPropertyAssocOne>[] emb = desc.propertiesEmbedded();
-
- for (int i = 0; i < emb.length; i++) {
- Object aval = emb[i].getValue(a);
- Object bval = emb[i].getValue(b);
- if (oldValues) {
- bval = ((EntityBean) bval)._ebean_getIntercept().getOldValues();
- if (bval == null) {
- continue;
- }
- }
-
- if (!isBothNull(aval, bval)) {
- if (isDiffNull(aval, bval)) {
- // one of the embedded beans is null
- map.put(emb[i].getName(), new ValuePair(aval, bval));
-
- } else {
- // if ANY of the properties in an Embedded bean is
- // different, treat the whole bean as being different
- BeanProperty[] props = emb[i].getProperties();
- for (int j = 0; j < props.length; j++) {
- Object aEmbPropVal = props[j].getValue(aval);
- Object bEmbPropVal = props[j].getValue(bval);
- if (!ValueUtil.areEqual(aEmbPropVal, bEmbPropVal)) {
-
- // if one prop is different put the
- // embedded bean in the map
- map.put(emb[i].getName(), new ValuePair(aval, bval));
- }
- }
- }
- }
- }
+// BeanPropertyAssocOne>[] emb = desc.propertiesEmbedded();
+//
+// for (int i = 0; i < emb.length; i++) {
+// Object aval = emb[i].getValue(a);
+// Object bval = emb[i].getValue(b);
+// if (oldValues) {
+// bval = null;//FIXME ((EntityBean) bval)._ebean_getIntercept().getOldValues();
+// if (bval == null) {
+// continue;
+// }
+// }
+//
+// if (!isBothNull(aval, bval)) {
+// if (isDiffNull(aval, bval)) {
+// // one of the embedded beans is null
+// map.put(emb[i].getName(), new ValuePair(aval, bval));
+//
+// } else {
+// // if ANY of the properties in an Embedded bean is
+// // different, treat the whole bean as being different
+// BeanProperty[] props = emb[i].getProperties();
+// for (int j = 0; j < props.length; j++) {
+// Object aEmbPropVal = props[j].getValue(aval);
+// Object bEmbPropVal = props[j].getValue(bval);
+// if (!ValueUtil.areEqual(aEmbPropVal, bEmbPropVal)) {
+//
+// // if one prop is different put the
+// // embedded bean in the map
+// map.put(emb[i].getName(), new ValuePair(aval, bval));
+// }
+// }
+// }
+// }
+// }
}
/**
@@ -119,29 +119,29 @@ public class DiffHelp {
BeanPropertyAssocOne>[] ones = desc.propertiesOne();
- for (int i = 0; i < ones.length; i++) {
- Object aval = ones[i].getValue(a);
- Object bval = ones[i].getValue(b);
-
- if (!isBothNull(aval, bval)) {
- if (isDiffNull(aval, bval)) {
- // one of them is/was null
- map.put(ones[i].getName(), new ValuePair(aval, bval));
-
- } else {
- // check to see if the Id properties
- // are different
- BeanDescriptor> oneDesc = ones[i].getTargetDescriptor();
- Object aOneId = oneDesc.getId(aval);
- Object bOneId = oneDesc.getId(bval);
-
- if (!ValueUtil.areEqual(aOneId, bOneId)) {
- // the ids are different
- map.put(ones[i].getName(), new ValuePair(aval, bval));
- }
- }
- }
- }
+// for (int i = 0; i < ones.length; i++) {
+// Object aval = ones[i].getValue(a);
+// Object bval = ones[i].getValue(b);
+//
+// if (!isBothNull(aval, bval)) {
+// if (isDiffNull(aval, bval)) {
+// // one of them is/was null
+// map.put(ones[i].getName(), new ValuePair(aval, bval));
+//
+// } else {
+// // check to see if the Id properties
+// // are different
+// BeanDescriptor> oneDesc = ones[i].getTargetDescriptor();
+// Object aOneId = oneDesc.getId(aval);
+// Object bOneId = oneDesc.getId(bval);
+//
+// if (!ValueUtil.areEqual(aOneId, bOneId)) {
+// // the ids are different
+// map.put(ones[i].getName(), new ValuePair(aval, bval));
+// }
+// }
+// }
+// }
}
private boolean isBothNull(Object aval, Object bval) {
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/OrmQueryRequest.java b/src/main/java/com/avaje/ebeaninternal/server/core/OrmQueryRequest.java
index e01896b93..3be51c24d 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/OrmQueryRequest.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/OrmQueryRequest.java
@@ -356,8 +356,7 @@ public final class OrmQueryRequest extends BeanRequest implements BeanQueryRe
cacheKey = query.queryHash();
- // TODO: Sort out returning BeanCollection from L2 cache
- return null;
+ return beanDescriptor.queryCacheGet(cacheKey);
}
public void putToQueryCache(BeanCollection queryResult) {
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequest.java b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequest.java
index 51f20722f..31a7983fd 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequest.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequest.java
@@ -32,6 +32,10 @@ public abstract class PersistRequest extends BeanRequest implements BatchPostExe
this.persistExecute = persistExecute;
}
+ public void setNotNullAsLoaded() {
+ // Do nothing by default
+ }
+
/**
* Execute a the request or queue/batch it for later execution.
*/
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 e23e922f8..816f94dcb 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/PersistRequestBean.java
@@ -41,6 +41,13 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
*/
protected final BeanPersistController controller;
+ /**
+ * The bean being persisted.
+ */
+ protected final T bean;
+
+ protected final EntityBean entityBean;
+
/**
* The associated intercept.
*/
@@ -53,22 +60,8 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
protected final boolean isDirty;
- /**
- * The bean being persisted.
- */
- protected final T bean;
-
- /**
- * Old values used for concurrency checking.
- */
- protected T oldValues;
-
- /**
- * The concurrency mode used for update or delete.
- */
protected ConcurrencyMode concurrencyMode;
- protected final Set loadedProps;
/**
* The unique id used for logging summary.
@@ -81,7 +74,6 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
protected Integer beanHash;
protected Integer beanIdentityHash;
- protected final Set changedProps;
protected boolean notifyCache;
@@ -89,39 +81,12 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
private boolean deleteMissingChildren;
private boolean updateNullProperties;
- /**
- * Used for forced update of a bean.
- */
- public PersistRequestBean(SpiEbeanServer server, T bean, Object parentBean, BeanManager mgr, SpiTransaction t,
- PersistExecute persistExecute, Set updateProps, ConcurrencyMode concurrencyMode) {
-
- super(server, t, persistExecute);
- this.beanManager = mgr;
- this.beanDescriptor = mgr.getBeanDescriptor();
- this.beanPersistListener = beanDescriptor.getPersistListener();
- this.bean = bean;
- this.parentBean = parentBean;
-
- this.controller = beanDescriptor.getPersistController();
- this.concurrencyMode = beanDescriptor.getConcurrencyMode();
-
- this.concurrencyMode = concurrencyMode;
- this.loadedProps = updateProps;
- this.changedProps = updateProps;
- this.isDirty = true;
- this.oldValues = bean;
- if (bean instanceof EntityBean) {
- this.intercept = ((EntityBean) bean)._ebean_getIntercept();
- } else {
- this.intercept = null;
- }
- }
-
- @SuppressWarnings("unchecked")
public PersistRequestBean(SpiEbeanServer server, T bean, Object parentBean, BeanManager mgr,
SpiTransaction t, PersistExecute persistExecute) {
super(server, t, persistExecute);
+ this.entityBean = (EntityBean)bean;
+ this.intercept = entityBean._ebean_getIntercept();
this.beanManager = mgr;
this.beanDescriptor = mgr.getBeanDescriptor();
this.beanPersistListener = beanDescriptor.getPersistListener();
@@ -130,38 +95,25 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
this.controller = beanDescriptor.getPersistController();
this.concurrencyMode = beanDescriptor.getConcurrencyMode();
- this.intercept = ((EntityBean) bean)._ebean_getIntercept();
if (intercept.isReference()) {
- // allowed to delete reference objects
- // with no concurrency checking
+ // delete reference objects with no concurrency checking
this.concurrencyMode = ConcurrencyMode.NONE;
}
// this is ok to not use isNewOrDirty() as used for updates only
this.isDirty = intercept.isDirty();
- if (!isDirty) {
- this.changedProps = intercept.getChangedProps();
- } else {
- // merge changed properties on the bean with changed embedded beans
- Set beanChangedProps = intercept.getChangedProps();
- Set dirtyEmbedded = beanDescriptor.getDirtyEmbeddedProperties(bean);
- this.changedProps = mergeChangedProperties(beanChangedProps, dirtyEmbedded);
- }
- this.loadedProps = intercept.getLoadedProps();
- this.oldValues = (T) intercept.getOldValues();
}
- /**
- * Merge the changed properties for the bean and embedded beans.
- */
- private Set mergeChangedProperties(Set beanChangedProps, Set embChanged) {
- if (embChanged == null) {
- return beanChangedProps;
- } else if (beanChangedProps == null) {
- return embChanged;
- } else {
- beanChangedProps.addAll(embChanged);
- return beanChangedProps;
- }
+
+ public void setNotNullAsLoaded() {
+ BeanProperty[] props = beanDescriptor.propertiesNonMany();
+ for (int i=0; i< props.length; i++) {
+ BeanProperty prop = props[i];
+ if (!intercept.isLoadedProperty(prop.getPropertyIndex())) {
+ if (prop.getValue(entityBean) != null) {
+ intercept.setLoadedProperty(prop.getPropertyIndex());
+ }
+ }
+ }
}
public boolean isNotify(TransactionEvent txnEvent) {
@@ -212,7 +164,7 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
return beanPersistListener.inserted(bean);
case UPDATE:
- return beanPersistListener.updated(bean, getUpdatedProperties());
+ return beanPersistListener.updated(bean);//, getUpdatedProperties());
case DELETE:
return beanPersistListener.deleted(bean);
@@ -229,7 +181,7 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
/**
* Return true if this bean has been already been persisted
- * (inserted/updated or deleted) in this transaction.
+ * (inserted or updated) in this transaction.
*/
public boolean isRegisteredBean() {
return transaction.isRegisteredBean(bean);
@@ -247,7 +199,7 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
*/
private Integer getBeanHash() {
if (beanHash == null) {
- Object id = beanDescriptor.getId(bean);
+ Object id = beanDescriptor.getId(entityBean);
int hc = 31 * bean.getClass().getName().hashCode();
if (id != null) {
hc += id.hashCode();
@@ -284,11 +236,6 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
public void setType(Type type) {
this.type = type;
notifyCache = beanDescriptor.isCacheNotify();
- if (type == Type.DELETE || type == Type.UPDATE) {
- if (oldValues == null) {
- oldValues = bean;
- }
- }
}
public BeanManager getBeanManager() {
@@ -354,20 +301,6 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
return concurrencyMode;
}
- /**
- * Set loaded properties when generated values has added properties such as
- * created and updated timestamps.
- */
- public void setLoadedProps(Set additionalProps) {
- if (intercept != null) {
- intercept.setLoadedProps(additionalProps);
- }
- }
-
- public Set getLoadedProperties() {
- return loadedProps;
- }
-
/**
* Returns a description of the request. This is typically the bean class
* name or the base table for MapBeans.
@@ -387,25 +320,22 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
return bean;
}
- /**
+
+ public EntityBean getEntityBean() {
+ return entityBean;
+ }
+
+ /**
* Return the Id value for the bean.
*/
public Object getBeanId() {
- return beanDescriptor.getId(bean);
+ return beanDescriptor.getId(entityBean);
}
public BeanDelta createDeltaBean() {
return new BeanDelta(beanDescriptor, getBeanId());
}
- /**
- * Get the old values bean. This is used to perform optimistic concurrency
- * checking on updates and deletes.
- */
- public T getOldValues() {
- return oldValues;
- }
-
/**
* Return the parent bean for cascading save with unidirectional
* relationship.
@@ -434,11 +364,7 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
* bean).
*/
public boolean isLoadedProperty(BeanProperty prop) {
- if (loadedProps == null) {
- return true;
- } else {
- return loadedProps.contains(prop.getName());
- }
+ return intercept.isLoadedProperty(prop.getPropertyIndex());
}
@Override
@@ -485,13 +411,8 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
*/
public void setGeneratedKey(Object idValue) {
if (idValue != null) {
-
- // set back to the bean so that we can use the same bean later
- // for update [refer ebeanIntercept.setLoaded(true)].
- idValue = beanDescriptor.convertSetId(idValue, bean);
-
// remember it for logging summary
- this.idValue = idValue;
+ this.idValue = beanDescriptor.convertSetId(idValue, entityBean);
}
}
@@ -597,18 +518,18 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
*
*/
public ConcurrencyMode determineConcurrencyMode() {
- if (loadedProps != null) {
- // 'partial bean' update/delete...
- if (concurrencyMode.equals(ConcurrencyMode.VERSION)) {
- // check the version property was loaded
- BeanProperty prop = beanDescriptor.firstVersionProperty();
- if (prop != null && loadedProps.contains(prop.getName())) {
- // OK to use version property
- } else {
- concurrencyMode = ConcurrencyMode.ALL;
- }
+
+ // 'partial bean' update/delete...
+ if (concurrencyMode.equals(ConcurrencyMode.VERSION)) {
+ // check the version property was loaded
+ BeanProperty prop = beanDescriptor.getVersionProperty();
+ if (prop != null && intercept.isLoadedProperty(prop.getPropertyIndex())) {
+ // OK to use version property
+ } else {
+ concurrencyMode = ConcurrencyMode.NONE;//ALL;
}
}
+
return concurrencyMode;
}
@@ -619,7 +540,7 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
*
*/
public boolean isDynamicUpdateSql() {
- return beanDescriptor.isUpdateChangesOnly() || (loadedProps != null);
+ return beanDescriptor.isUpdateChangesOnly() || !intercept.isFullyLoadedBean();//(loadedProps != null);
}
/**
@@ -630,37 +551,28 @@ public class PersistRequestBean extends PersistRequest implements BeanPersist
*
*/
public GenerateDmlRequest createGenerateDmlRequest(boolean emptyStringAsNull) {
- if (beanDescriptor.isUpdateChangesOnly()) {
- return new GenerateDmlRequest(emptyStringAsNull, changedProps, loadedProps, oldValues);
- } else {
- return new GenerateDmlRequest(emptyStringAsNull, loadedProps, loadedProps, oldValues);
- }
- }
-
- /**
- * Return the updated properties. If this returns null then all the
- * properties on the bean where updated.
- */
- public Set getUpdatedProperties() {
- if (changedProps != null) {
- return changedProps;
- }
- return loadedProps;
+ return new GenerateDmlRequest(emptyStringAsNull, intercept, beanDescriptor.isUpdateChangesOnly());
}
/**
* Test if the property value has changed and if so include it in the
* update.
*/
- public boolean hasChanged(BeanProperty prop) {
- if (changedProps == null) {
- return false;
- }
- return changedProps.contains(prop.getName());
+ public boolean isAddToUpdate(BeanProperty prop) {
+ return intercept.isChangedProperty(prop.getPropertyIndex());
}
- public List getDerivedRelationships() {
- return transaction.getDerivedRelationship(bean);
+ public List getDerivedRelationships() {
+ return transaction.getDerivedRelationship(bean);
+ }
+
+ public void postInsert() {
+ // mark all properties as loaded after an insert
+ // to support immediate update
+ int len = intercept.getPropertyLength();
+ for (int i = 0; i < len; i++) {
+ intercept.setLoadedProperty(i);
}
+ }
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/Persister.java b/src/main/java/com/avaje/ebeaninternal/server/core/Persister.java
index 319a5fd73..268ddf8ec 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/Persister.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/Persister.java
@@ -7,6 +7,7 @@ import com.avaje.ebean.CallableSql;
import com.avaje.ebean.SqlUpdate;
import com.avaje.ebean.Transaction;
import com.avaje.ebean.Update;
+import com.avaje.ebean.bean.EntityBean;
/**
@@ -17,23 +18,23 @@ public interface Persister {
/**
* Force an Update using the given bean.
*/
- public void forceUpdate(Object entityBean, Set updateProps, Transaction t, boolean deleteMissingChildren, boolean updateNullProperties);
+ public void forceUpdate(EntityBean entityBean, Set updateProps, Transaction t, boolean deleteMissingChildren, boolean updateNullProperties);
/**
* Force an Insert using the given bean.
*/
- public void forceInsert(Object entityBean, Transaction t);
+ public void forceInsert(EntityBean entityBean, Transaction t);
/**
* Insert or update the bean depending on its state.
*/
- public void save(Object entityBean, Transaction t);
+ public void save(EntityBean entityBean, Transaction t);
/**
* Save the associations of a ManyToMany given the owner bean and the
* propertyName of the ManyToMany collection.
*/
- public void saveManyToManyAssociations(Object ownerBean, String propertyName, Transaction t);
+ public void saveManyToManyAssociations(EntityBean ownerBean, String propertyName, Transaction t);
/**
* Save an association (OneToMany, ManyToOne, OneToOne or ManyToMany).
@@ -45,12 +46,12 @@ public interface Persister {
* @param t
* the transaction to use.
*/
- public void saveAssociation(Object parentBean, String propertyName, Transaction t);
+ public void saveAssociation(EntityBean parentBean, String propertyName, Transaction t);
/**
* Delete the associations of a ManyToMany given the owner bean and the property name of the ManyToMany.
*/
- public int deleteManyToManyAssociations(Object ownerBean, String propertyName, Transaction t);
+ public int deleteManyToManyAssociations(EntityBean ownerBean, String propertyName, Transaction t);
/**
* Delete a bean given it's type and id value.
@@ -63,7 +64,7 @@ public interface Persister {
/**
* Delete the bean.
*/
- public void delete(Object entityBean, Transaction t);
+ public void delete(EntityBean entityBean, Transaction t);
/**
* Delete multiple beans given a collection of Id values.
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanCollectionHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanCollectionHelp.java
index 061624e23..711d1496c 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanCollectionHelp.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanCollectionHelp.java
@@ -8,6 +8,7 @@ import com.avaje.ebean.Transaction;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;
/**
@@ -41,22 +42,22 @@ public interface BeanCollectionHelp {
/**
* Add a bean to the List Set or Map.
*/
- public void add(BeanCollection> collection, Object bean);
+ public void add(BeanCollection> collection, EntityBean bean);
/**
* Create a lazy loading proxy for a List Set or Map.
*/
- public BeanCollection createReference(Object parentBean, String propertyName);
+ public BeanCollection createReference(EntityBean parentBean, String propertyName);
/**
* Refresh the List Set or Map.
*/
- public void refresh(EbeanServer server, Query> query, Transaction t, Object parentBean);
+ public void refresh(EbeanServer server, Query> query, Transaction t, EntityBean parentBean);
/**
* Apply the new refreshed BeanCollection to the appropriate property of the parent bean.
*/
- public void refresh(BeanCollection> bc, Object parentBean);
+ public void refresh(BeanCollection> bc, EntityBean parentBean);
/**
* Write the collection out as json.
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 7e0ce4b6a..d4d44fbf4 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptor.java
@@ -15,9 +15,6 @@ import java.util.concurrent.ConcurrentHashMap;
import javax.persistence.PersistenceException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import com.avaje.ebean.Query;
import com.avaje.ebean.SqlUpdate;
import com.avaje.ebean.Transaction;
@@ -77,6 +74,8 @@ import com.avaje.ebeaninternal.server.type.TypeManager;
import com.avaje.ebeaninternal.util.SortByClause;
import com.avaje.ebeaninternal.util.SortByClause.Property;
import com.avaje.ebeaninternal.util.SortByClauseParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Describes Beans including their deployment information.
@@ -180,12 +179,11 @@ public class BeanDescriptor implements MetaBeanInfo {
*/
private final BeanDescriptorMap owner;
- /**
- * The EntityBean type used to create new EntityBeans.
- */
- private final Class> factoryType;
-
- private final boolean enhancedBean;
+
+ private final String[] properties;
+
+ private final int propertyCount;
+
/**
* Intercept pre post on insert,update,delete and postLoad(). Server side
@@ -223,7 +221,7 @@ public class BeanDescriptor implements MetaBeanInfo {
/**
* Derived list of properties that are used for version concurrency checking.
*/
- private final BeanProperty[] propertiesVersion;
+ private final BeanProperty versionProperty;
private final BeanProperty propertiesNaturalKey;
/**
@@ -284,11 +282,6 @@ public class BeanDescriptor implements MetaBeanInfo {
*/
final BeanProperty[] propertiesNonTransient;
- /**
- * Set to true if the bean has version properties or an embedded bean has
- * version properties.
- */
- private final BeanProperty propertyFirstVersion;
/**
* Set when the Id property is a single non-embedded property. Can make life
@@ -348,6 +341,7 @@ public class BeanDescriptor implements MetaBeanInfo {
private final String descriptorId;
+
private SpiEbeanServer ebeanServer;
private ServerCache beanCache;
@@ -363,6 +357,8 @@ public class BeanDescriptor implements MetaBeanInfo {
this.cacheManager = owner.getCacheManager();
this.serverName = owner.getServerName();
this.entityType = deploy.getEntityType();
+ this.properties = deploy.getProperties();
+ this.propertyCount = this.properties.length;
this.name = InternString.intern(deploy.getName());
this.baseTableAlias = "t0";
this.fullName = InternString.intern(deploy.getFullName());
@@ -370,8 +366,6 @@ public class BeanDescriptor implements MetaBeanInfo {
this.typeManager = typeManager;
this.beanType = deploy.getBeanType();
- this.factoryType = deploy.getFactoryType();
- this.enhancedBean = beanType.equals(factoryType);
this.namedQueries = deploy.getNamedQueries();
this.namedUpdates = deploy.getNamedUpdates();
@@ -416,7 +410,7 @@ public class BeanDescriptor implements MetaBeanInfo {
this.propertiesBaseCompound = listHelper.getBaseCompound();
this.propertiesId = listHelper.getId();
this.propertiesNaturalKey = listHelper.getNaturalKey();
- this.propertiesVersion = listHelper.getVersion();
+ this.versionProperty = listHelper.getVersionProperty();
this.propertiesEmbedded = listHelper.getEmbedded();
this.propertiesLocal = listHelper.getLocal();
this.unidirectional = listHelper.getUnidirectional();
@@ -440,7 +434,6 @@ public class BeanDescriptor implements MetaBeanInfo {
this.namesOfManyPropsHash = namesOfManyProps.hashCode();
this.derivedTableJoins = listHelper.getTableJoin();
- this.propertyFirstVersion = listHelper.getFirstVersion();
if (propertiesId.length == 1) {
this.propertySingleId = propertiesId[0];
@@ -491,19 +484,19 @@ public class BeanDescriptor implements MetaBeanInfo {
* Determine the concurrency mode based on the existence of a non-null version
* property value.
*/
- public ConcurrencyMode determineConcurrencyMode(Object bean) {
+ public ConcurrencyMode determineConcurrencyMode(EntityBean bean) {
- if (propertyFirstVersion == null) {
+ if (versionProperty == null) {
return ConcurrencyMode.NONE;
}
- Object v = propertyFirstVersion.getValue(bean);
+ Object v = versionProperty.getValue(bean);
return (v == null) ? ConcurrencyMode.NONE : ConcurrencyMode.VERSION;
}
/**
* Return the Set of embedded beans that have changed.
*/
- public Set getDirtyEmbeddedProperties(Object bean) {
+ public Set getDirtyEmbeddedProperties(EntityBean bean) {
HashSet dirtyProperties = null;
@@ -532,7 +525,7 @@ public class BeanDescriptor implements MetaBeanInfo {
/**
* Determine the non-null properties of the bean.
*/
- public Set determineLoadedProperties(Object bean) {
+ public Set determineLoadedProperties(EntityBean bean) {
HashSet nonNullProps = new HashSet();
@@ -563,6 +556,14 @@ public class BeanDescriptor implements MetaBeanInfo {
return entityType;
}
+ public int getPropertyCount() {
+ return propertyCount;
+ }
+
+ public String[] getProperties() {
+ return properties;
+ }
+
/**
* Initialise the Id properties first.
*
@@ -663,10 +664,6 @@ public class BeanDescriptor implements MetaBeanInfo {
return inheritInfo != null;
}
- protected boolean isDynamicSubclass() {
- return !beanType.equals(factoryType);
- }
-
public SqlUpdate deleteById(Object id, List
*/
- public BeanProperty firstVersionProperty() {
- return propertyFirstVersion;
+ public BeanProperty getVersionProperty() {
+ return versionProperty;
}
/**
* Return true if this is an Update (rather than insert) given that the bean
* is involved in a stateless update.
*/
- public boolean isStatelessUpdate(Object bean) {
- if (propertyFirstVersion == null) {
+ public boolean isStatelessUpdate(EntityBean bean) {
+ if (versionProperty == null) {
Object versionValue = getId(bean);
return !DmlUtil.isNullOrZero(versionValue);
} else {
- Object versionValue = propertyFirstVersion.getValue(bean);
+ Object versionValue = versionProperty.getValue(bean);
return !DmlUtil.isNullOrZero(versionValue);
}
}
- /**
- * Returns 'Version' properties on this bean. These are 'Counter' or 'Update
- * Timestamp' type properties. Note version properties can also be on embedded
- * beans rather than on the bean itself.
- */
- public BeanProperty[] propertiesVersion() {
- return propertiesVersion;
- }
-
/**
* Scalar properties without the unique id or secondary table properties.
*/
@@ -2242,7 +2219,7 @@ public class BeanDescriptor implements MetaBeanInfo {
return propertiesLocal;
}
- public void jsonWrite(WriteJsonContext ctx, Object bean) {
+ public void jsonWrite(WriteJsonContext ctx, EntityBean bean) {
if (bean != null) {
@@ -2268,7 +2245,7 @@ public class BeanDescriptor implements MetaBeanInfo {
}
@SuppressWarnings("unchecked")
- private void jsonWriteProperties(WriteJsonContext ctx, Object bean) {
+ private void jsonWriteProperties(WriteJsonContext ctx, EntityBean bean) {
boolean referenceBean = ctx.isReferenceBean();
@@ -2297,7 +2274,7 @@ public class BeanDescriptor implements MetaBeanInfo {
if (!explicitAllProps && props == null) {
// just render the loaded properties
- props = ctx.getLoadedProps();
+ props = ((EntityBean)bean)._ebean_getIntercept().getLoadedPropertyNames();
}
if (props != null) {
// render only the appropriate properties (when not all properties)
@@ -2386,7 +2363,7 @@ public class BeanDescriptor implements MetaBeanInfo {
private ReadBeanState jsonReadObject(ReadJsonContext ctx, String path) {
- T bean = createJsonBean();
+ EntityBean bean = createEntityBean();
ctx.pushBean(bean, path, this);
do {
@@ -2421,7 +2398,7 @@ public class BeanDescriptor implements MetaBeanInfo {
if (isLoadedReference(loadedProps)) {
ebi.setReference();
} else {
- ebi.setLoadedProps(loadedProps);
+ ebi.setLoaded();
}
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java
index c5714d1ee..fad2d4cc4 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java
@@ -61,6 +61,7 @@ import com.avaje.ebeaninternal.server.lib.util.Dnode;
import com.avaje.ebeaninternal.server.reflect.BeanReflect;
import com.avaje.ebeaninternal.server.reflect.BeanReflectFactory;
import com.avaje.ebeaninternal.server.reflect.BeanReflectGetter;
+import com.avaje.ebeaninternal.server.reflect.BeanReflectProperties;
import com.avaje.ebeaninternal.server.reflect.BeanReflectSetter;
import com.avaje.ebeaninternal.server.reflect.EnhanceBeanReflectFactory;
import com.avaje.ebeaninternal.server.type.TypeManager;
@@ -1298,43 +1299,34 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
// abstract classes as well.
Class> beanType = desc.getBeanType();
- Class> factType = desc.getFactoryType();
- BeanReflect beanReflect = reflectFactory.create(beanType, factType);
+ BeanReflectProperties reflectProps = new BeanReflectProperties(beanType);
+
+ BeanReflect beanReflect = reflectFactory.create(beanType);
desc.setBeanReflect(beanReflect);
+ desc.setProperties(reflectProps.getProperties());
- try {
- Iterator it = desc.propertiesAll();
- while (it.hasNext()) {
- DeployBeanProperty prop = it.next();
- String propName = prop.getName();
+ Iterator it = desc.propertiesAll();
+ while (it.hasNext()) {
+ DeployBeanProperty prop = it.next();
+ String propName = prop.getName();
+
+ Integer pos = reflectProps.getPropertyIndex(propName);
+ if (pos == null) {
+ throw new IllegalStateException("Property "+propName+" not found in "+reflectProps);
+ }
- if (desc.isAbstract() || beanReflect.isVanillaOnly()) {
- // use reflection in the case of imported abstract class
- // with
- // inheritance. Refer Bug 166
- prop.setGetter(ReflectGetter.create(prop));
- prop.setSetter(ReflectSetter.create(prop));
-
- } else {
- // use generated code for getting setting property values
- BeanReflectGetter getter = beanReflect.getGetter(propName);
- BeanReflectSetter setter = beanReflect.getSetter(propName);
- prop.setGetter(getter);
- prop.setSetter(setter);
- if (getter == null) {
- // should never happen
- String m = "BeanReflectGetter for " + prop.getFullBeanName() + " was not found?";
- throw new RuntimeException(m);
- }
- }
+ BeanReflectGetter getter = beanReflect.getGetter(propName, pos.intValue());
+ BeanReflectSetter setter = beanReflect.getSetter(propName, pos.intValue());
+ prop.setGetter(getter);
+ prop.setSetter(setter);
+ prop.setPropertyIndex(pos.intValue());
+
+ if (getter == null) {
+ String m = "BeanReflectGetter for " + prop.getFullBeanName() + " was not found?";
+ throw new RuntimeException(m);
}
- } catch (IllegalArgumentException e) {
- Class> superClass = desc.getBeanType().getSuperclass();
- String msg = "Error with [" + desc.getFullName() + "] I believe it is not enhanced but it's superClass [" + superClass + "] is?"
- + " (You are not allowed to mix enhancement in a single inheritance hierarchy)";
- throw new PersistenceException(msg, e);
}
}
@@ -1345,13 +1337,15 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
*/
private void setConcurrencyMode(DeployBeanDescriptor> desc) {
- if (!desc.getConcurrencyMode().equals(ConcurrencyMode.ALL)) {
+ if (desc.getConcurrencyMode() != null) {
// concurrency mode explicitly set during deployment
return;
}
if (checkForVersionProperties(desc)) {
desc.setConcurrencyMode(ConcurrencyMode.VERSION);
+ } else {
+ desc.setConcurrencyMode(ConcurrencyMode.NONE);
}
}
@@ -1390,91 +1384,35 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
Class> beanClass = desc.getBeanType();
- if (desc.isAbstract()) {
- if (hasEntityBeanInterface(beanClass)) {
- checkEnhanced(desc, beanClass);
- } else {
- checkSubclass(desc, beanClass);
- }
- return;
+ if (!hasEntityBeanInterface(beanClass)) {
+ throw new IllegalStateException("Bean "+beanClass+" is not enhanced?");
}
- try {
- Object testBean = null;
- try {
- testBean = beanClass.newInstance();
- } catch (InstantiationException e) {
- // expected when no default constructor
- logger.debug("no default constructor on " + beanClass + " e:" + e);
- } catch (IllegalAccessException e) {
- // expected when no default constructor
- logger.debug("no default constructor on " + beanClass + " e:" + e);
- }
- if (testBean instanceof EntityBean == false) {
- checkSubclass(desc, beanClass);
- } else {
- String className = beanClass.getName();
- try {
- // check that it really is enhanced (rather than mixed
- // enhancement)
- String marker = ((EntityBean) testBean)._ebean_getMarker();
- if (!marker.equals(className)) {
- String msg = "Error with [" + desc.getFullName() + "] It has not been enhanced but it's superClass ["
- + beanClass.getSuperclass() + "] is?" + " (You are not allowed to mix enhancement in a single inheritance hierarchy)"
- + " marker[" + marker + "] className[" + className + "]";
- throw new PersistenceException(msg);
- }
- } catch (AbstractMethodError e) {
- throw new PersistenceException("Old Ebean v1.0 enhancement detected in Ebean v1.1 - please do a clean enhancement.", e);
- }
-
- checkEnhanced(desc, beanClass);
- }
-
- } catch (PersistenceException ex) {
- throw ex;
-
- } catch (Exception ex) {
- throw new PersistenceException(ex);
- }
- }
-
- private void checkEnhanced(DeployBeanDescriptor> desc, Class> beanClass) {
// the bean already implements EntityBean
- checkInheritedClasses(true, beanClass);
- desc.setFactoryType(beanClass);
- enhancedClassCount++;
- }
+ checkInheritedClasses(beanClass);
- private void checkSubclass(DeployBeanDescriptor> desc, Class> beanClass) {
-
- throw new PersistenceException("Entity type "+beanClass+" is not an enhanced entity bean. Subclassing is not longer supported in Ebean");
+ if (!beanClass.getName().startsWith("com.avaje.ebean.meta")) {
+ enhancedClassCount++;
+ }
}
/**
* Check that the inherited classes are the same as the entity bean (aka all
* enhanced or all dynamically subclassed).
*/
- private void checkInheritedClasses(boolean ensureEnhanced, Class> beanClass) {
+ private void checkInheritedClasses(Class> beanClass) {
Class> superclass = beanClass.getSuperclass();
if (Object.class.equals(superclass)) {
// we got to the top of the inheritance
return;
}
- boolean isClassEnhanced = EntityBean.class.isAssignableFrom(superclass);
-
- if (ensureEnhanced != isClassEnhanced) {
- String msg;
- if (ensureEnhanced) {
- msg = "Class [" + superclass + "] is not enhanced and [" + beanClass + "] is - (you can not mix!!)";
- } else {
- msg = "Class [" + superclass + "] is enhanced and [" + beanClass + "] is not - (you can not mix!!)";
- }
- throw new IllegalStateException(msg);
+ if (!EntityBean.class.isAssignableFrom(superclass)) {
+ throw new IllegalStateException("Super type "+superclass+" is not enhanced?");
}
+
// recursively continue up the inheritance hierarchy
- checkInheritedClasses(ensureEnhanced, superclass);
+ checkInheritedClasses(superclass);
}
/**
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanEmbeddedMeta.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanEmbeddedMeta.java
index aa0987c00..7209b6d42 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanEmbeddedMeta.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanEmbeddedMeta.java
@@ -16,16 +16,4 @@ public class BeanEmbeddedMeta {
return properties;
}
- /**
- * Return true if at least one property is a version property.
- */
- public boolean isEmbeddedVersion() {
- for (int i = 0; i < properties.length; i++) {
- if (properties[i].isVersion()){
- return true;
- }
- }
- return false;
- }
-
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanFkeyProperty.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanFkeyProperty.java
index bd85b6d56..4ce2b4d73 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanFkeyProperty.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanFkeyProperty.java
@@ -1,5 +1,6 @@
package com.avaje.ebeaninternal.server.deploy;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.text.StringFormatter;
import com.avaje.ebean.text.StringParser;
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
@@ -95,7 +96,7 @@ public final class BeanFkeyProperty implements ElPropertyValue {
/**
* Returns null as not an AssocOne.
*/
- public Object[] getAssocOneIdValues(Object value) {
+ public Object[] getAssocOneIdValues(EntityBean value) {
return null;
}
@@ -159,7 +160,7 @@ public final class BeanFkeyProperty implements ElPropertyValue {
throw new RuntimeException("ElPropertyDeploy only - not implemented");
}
- public void elSetReference(Object bean) {
+ public void elSetReference(EntityBean bean) {
throw new RuntimeException("ElPropertyDeploy only - not implemented");
}
@@ -167,15 +168,15 @@ public final class BeanFkeyProperty implements ElPropertyValue {
throw new RuntimeException("ElPropertyDeploy only - not implemented");
}
- public void elSetValue(Object bean, Object value, boolean populate, boolean reference) {
+ public void elSetValue(EntityBean bean, Object value, boolean populate, boolean reference) {
throw new RuntimeException("ElPropertyDeploy only - not implemented");
}
- public Object elGetValue(Object bean) {
+ public Object elGetValue(EntityBean bean) {
throw new RuntimeException("ElPropertyDeploy only - not implemented");
}
- public Object elGetReference(Object bean) {
+ public Object elGetReference(EntityBean bean) {
throw new RuntimeException("ElPropertyDeploy only - not implemented");
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanListHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanListHelp.java
index c6a932e92..25baefd49 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanListHelp.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanListHelp.java
@@ -10,6 +10,7 @@ import com.avaje.ebean.Transaction;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.common.BeanList;
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;
@@ -35,11 +36,11 @@ public final class BeanListHelp implements BeanCollectionHelp {
public void setLoader(BeanCollectionLoader loader) {
this.loader = loader;
}
-
+
/**
* Internal add bypassing any modify listening.
*/
- public void add(BeanCollection> collection, Object bean) {
+ public void add(BeanCollection> collection, EntityBean bean) {
collection.internalAdd(bean);
}
@@ -70,7 +71,7 @@ public final class BeanListHelp implements BeanCollectionHelp {
this.list = list;
}
- public void addBean(Object bean) {
+ public void addBean(EntityBean bean) {
list.add(bean);
}
}
@@ -90,20 +91,20 @@ public final class BeanListHelp implements BeanCollectionHelp {
return beanList;
}
- public BeanCollection createReference(Object parentBean, String propertyName) {
+ public BeanCollection createReference(EntityBean parentBean, String propertyName) {
BeanList beanList = new BeanList(loader, parentBean, propertyName);
beanList.setModifyListening(many.getModifyListenMode());
return beanList;
}
- public void refresh(EbeanServer server, Query> query, Transaction t, Object parentBean) {
+ public void refresh(EbeanServer server, Query> query, Transaction t, EntityBean parentBean) {
BeanList> newBeanList = (BeanList>) server.findList(query, t);
refresh(newBeanList, parentBean);
}
- public void refresh(BeanCollection> bc, Object parentBean) {
+ public void refresh(BeanCollection> bc, EntityBean parentBean) {
BeanList> newBeanList = (BeanList>) bc;
@@ -152,7 +153,7 @@ public final class BeanListHelp implements BeanCollectionHelp {
ctx.appendComma();
}
Object detailBean = list.get(j);
- targetDescriptor.jsonWrite(ctx, detailBean);
+ targetDescriptor.jsonWrite(ctx, (EntityBean)detailBean);
}
ctx.endAssocMany();
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanMapHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanMapHelp.java
index 26c4e346c..8f61c0f91 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanMapHelp.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanMapHelp.java
@@ -11,6 +11,7 @@ import com.avaje.ebean.Transaction;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.common.BeanMap;
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;
@@ -93,7 +94,7 @@ public final class BeanMapHelp implements BeanCollectionHelp {
this.map = map;
}
- public void addBean(Object bean) {
+ public void addBean(EntityBean bean) {
Object keyValue = beanProperty.getValue(bean);
map.put(keyValue, bean);
}
@@ -111,18 +112,16 @@ public final class BeanMapHelp implements BeanCollectionHelp {
return beanMap;
}
-
- /**
- * Internal add bypassing any modify listening.
- */
- public void add(BeanCollection> collection, Object bean) {
+ @SuppressWarnings("unchecked")
+ public void add(BeanCollection> collection, EntityBean bean) {
Object keyValue = beanProperty.getValueIntercept(bean);
+
((BeanMap,?>) collection).internalPut(keyValue, bean);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- public BeanCollection createReference(Object parentBean, String propertyName) {
+ public BeanCollection createReference(EntityBean parentBean, String propertyName) {
BeanMap beanMap = new BeanMap(loader, parentBean, propertyName);
if (many != null) {
@@ -136,7 +135,7 @@ public final class BeanMapHelp implements BeanCollectionHelp {
refresh(newBeanMap, parentBean);
}
- public void refresh(BeanCollection> bc, Object parentBean) {
+ public void refresh(BeanCollection> bc, EntityBean parentBean) {
BeanMap, ?> newBeanMap = (BeanMap, ?>) bc;
Map, ?> current = (Map, ?>) many.getValue(parentBean);
@@ -187,7 +186,7 @@ public final class BeanMapHelp implements BeanCollectionHelp {
}
//FIXME: json write map key ...
Object detailBean = entry.getValue();
- targetDescriptor.jsonWrite(ctx, detailBean);
+ targetDescriptor.jsonWrite(ctx, (EntityBean)detailBean);
}
ctx.endAssocMany();
}
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 a69ffc731..7a98140c7 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanProperty.java
@@ -33,7 +33,6 @@ import com.avaje.ebeaninternal.server.text.json.ReadJsonContext;
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;
import com.avaje.ebeaninternal.server.type.DataBind;
import com.avaje.ebeaninternal.server.type.ScalarType;
-import com.avaje.ebeaninternal.util.ValueUtil;
/**
* Description of a property of a bean. Includes its deployment information such
@@ -141,6 +140,8 @@ public class BeanProperty implements ElPropertyValue {
*/
final String name;
+ final int propertyIndex;
+
/**
* The reflected field.
*/
@@ -249,8 +250,6 @@ public class BeanProperty implements ElPropertyValue {
final DbEncryptFunction dbEncryptFunction;
- final boolean dynamicSubclassWithInheritance;
-
int deployOrder;
final boolean jsonSerialize;
@@ -265,11 +264,8 @@ public class BeanProperty implements ElPropertyValue {
this.descriptor = descriptor;
this.name = InternString.intern(deploy.getName());
- if (descriptor != null) {
- this.dynamicSubclassWithInheritance = (descriptor.isDynamicSubclass() && descriptor.hasInheritance());
- } else {
- this.dynamicSubclassWithInheritance = false;
- }
+ this.propertyIndex = deploy.getPropertyIndex();
+
this.unidirectionalShadow = deploy.isUndirectionalShadow();
this.localEncrypted = deploy.isLocalEncrypted();
this.dbEncrypted = deploy.isDbEncrypted();
@@ -363,7 +359,7 @@ public class BeanProperty implements ElPropertyValue {
this.descriptor = source.descriptor;
this.name = InternString.intern(source.getName());
- this.dynamicSubclassWithInheritance = source.dynamicSubclassWithInheritance;
+ this.propertyIndex = source.propertyIndex;
this.dbColumn = InternString.intern(override.getDbColumn());
this.sqlFormulaJoin = InternString.intern(override.getSqlFormulaJoin());
@@ -473,14 +469,7 @@ public class BeanProperty implements ElPropertyValue {
return formula;
}
- public boolean hasChanged(Object bean, Object oldValues) {
- Object value = getValue(bean);
- Object oldVal = getValue(oldValues);
-
- return !ValueUtil.areEqual(value, oldVal);
- }
-
- public void copyProperty(Object sourceBean, Object destBean) {
+ public void copyProperty(EntityBean sourceBean, EntityBean destBean) {
Object value = getValue(sourceBean);
setValue(destBean, value);
}
@@ -561,7 +550,7 @@ public class BeanProperty implements ElPropertyValue {
return owningType.isAssignableFrom(type);
}
- public Object readSetOwning(DbReadContext ctx, Object bean, Class> type) throws SQLException {
+ public Object readSetOwning(DbReadContext ctx, EntityBean bean, Class> type) throws SQLException {
try {
Object value = scalarType.read(ctx.getDataReader());
@@ -599,7 +588,7 @@ public class BeanProperty implements ElPropertyValue {
return scalarType.read(ctx.getDataReader());
}
- public Object readSet(DbReadContext ctx, Object bean, Class> type) throws SQLException {
+ public Object readSet(DbReadContext ctx, EntityBean bean, Class> type) throws SQLException {
try {
Object value = scalarType.read(ctx.getDataReader());
@@ -690,15 +679,9 @@ public class BeanProperty implements ElPropertyValue {
* Set the value of the property without interception or
* PropertyChangeSupport.
*/
- public void setValue(Object bean, Object value) {
+ public void setValue(EntityBean bean, Object value) {
try {
- if (bean instanceof EntityBean) {
- setter.set(bean, value);
- } else {
- Object[] args = new Object[1];
- args[0] = value;
- writeMethod.invoke(bean, args);
- }
+ setter.set(bean, value);
} catch (Exception ex) {
String beanType = bean == null ? "null" : bean.getClass().getName();
String msg = "set " + name + " on [" + descriptor + "] arg[" + value + "] type[" + beanType
@@ -710,15 +693,9 @@ public class BeanProperty implements ElPropertyValue {
/**
* Set the value of the property.
*/
- public void setValueIntercept(Object bean, Object value) {
+ public void setValueIntercept(EntityBean bean, Object value) {
try {
- if (bean instanceof EntityBean) {
- setter.setIntercept(bean, value);
- } else {
- Object[] args = new Object[1];
- args[0] = value;
- writeMethod.invoke(bean, args);
- }
+ setter.setIntercept(bean, value);
} catch (Exception ex) {
String beanType = bean == null ? "null" : bean.getClass().getName();
String msg = "setIntercept " + name + " on [" + descriptor + "] arg[" + value + "] type[" + beanType
@@ -729,34 +706,20 @@ public class BeanProperty implements ElPropertyValue {
private static Object[] NO_ARGS = new Object[0];
- /**
- * Return the property value taking inheritance into account.
- */
- public Object getValueWithInheritance(Object bean) {
- if (dynamicSubclassWithInheritance) {
- return descriptor.getBeanPropertyWithInheritance(bean, name);
- }
- return getValue(bean);
- }
-
- public Object getCacheDataValue(Object bean){
+ public Object getCacheDataValue(EntityBean bean){
return getValue(bean);
}
- public void setCacheDataValue(Object bean, Object cacheData, Object oldValues, boolean readOnly){
+ public void setCacheDataValue(EntityBean bean, Object cacheData){
setValue(bean, cacheData);
}
/**
* Return the value of the property method.
*/
- public Object getValue(Object bean) {
+ public Object getValue(EntityBean bean) {
try {
- if (bean instanceof EntityBean) {
- return getter.get(bean);
- } else {
- return readMethod.invoke(bean, NO_ARGS);
- }
+ return getter.get(bean);
} catch (Exception ex) {
String beanType = bean == null ? "null" : bean.getClass().getName();
String msg = "get " + name + " on [" + descriptor + "] type[" + beanType + "] threw error.";
@@ -777,13 +740,9 @@ public class BeanProperty implements ElPropertyValue {
}
}
- public Object getValueIntercept(Object bean) {
+ public Object getValueIntercept(EntityBean bean) {
try {
- if (bean instanceof EntityBean) {
- return getter.getIntercept(bean);
- } else {
- return readMethod.invoke(bean, NO_ARGS);
- }
+ return getter.getIntercept(bean);
} catch (Exception ex) {
String beanType = bean == null ? "null" : bean.getClass().getName();
String msg = "getIntercept " + name + " on [" + descriptor + "] type[" + beanType + "] threw error.";
@@ -798,24 +757,25 @@ public class BeanProperty implements ElPropertyValue {
return convertToLogicalType(value);
}
- public void elSetReference(Object bean) {
+ public void elSetReference(EntityBean bean) {
throw new RuntimeException("Should not be called");
}
- public void elSetValue(Object bean, Object value, boolean populate, boolean reference) {
+ public void elSetValue(EntityBean bean, Object value, boolean populate, boolean reference) {
if (bean != null) {
- setValueIntercept(bean, value);
+ // Not using setValueIntercept at this stage
+ setValue(bean, value);
}
}
- public Object elGetValue(Object bean) {
+ public Object elGetValue(EntityBean bean) {
if (bean == null) {
return null;
}
return getValueIntercept(bean);
}
- public Object elGetReference(Object bean) {
+ public Object elGetReference(EntityBean bean) {
throw new RuntimeException("Not expected to call this");
}
@@ -826,6 +786,13 @@ public class BeanProperty implements ElPropertyValue {
return name;
}
+ /**
+ * Return the position of this property in the enhanced bean.
+ */
+ public int getPropertyIndex() {
+ return propertyIndex;
+ }
+
public String getElName() {
return name;
}
@@ -851,7 +818,7 @@ public class BeanProperty implements ElPropertyValue {
return false;
}
- public Object[] getAssocOneIdValues(Object bean) {
+ public Object[] getAssocOneIdValues(EntityBean bean) {
// Returns null as not an AssocOne.
return null;
}
@@ -1177,7 +1144,7 @@ public class BeanProperty implements ElPropertyValue {
}
@SuppressWarnings("unchecked")
- public void jsonWrite(WriteJsonContext ctx, Object bean) {
+ public void jsonWrite(WriteJsonContext ctx, EntityBean bean) {
if(!jsonSerialize){
return;
}
@@ -1189,7 +1156,7 @@ public class BeanProperty implements ElPropertyValue {
}
}
- public void jsonRead(ReadJsonContext ctx, Object bean) {
+ public void jsonRead(ReadJsonContext ctx, EntityBean bean) {
if(!jsonDeserialize){
return;
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssoc.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssoc.java
index 86665602d..9d552e140 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssoc.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssoc.java
@@ -216,7 +216,7 @@ public abstract class BeanPropertyAssoc extends BeanProperty {
/**
* Return true if the unique id properties are all not null for this bean.
*/
- public boolean hasId(Object bean) {
+ public boolean hasId(EntityBean bean) {
BeanDescriptor> targetDesc = getTargetDescriptor();
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java
index 414a376b7..6723d7132 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocMany.java
@@ -17,6 +17,7 @@ import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollection.ModifyListenMode;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
import com.avaje.ebeaninternal.server.deploy.id.ImportedId;
@@ -158,22 +159,22 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
}
@Override
- public Object getValue(Object bean) {
+ public Object getValue(EntityBean bean) {
return super.getValue(bean);
}
@Override
- public Object getValueIntercept(Object bean) {
+ public Object getValueIntercept(EntityBean bean) {
return super.getValueIntercept(bean);
}
@Override
- public void setValue(Object bean, Object value) {
+ public void setValue(EntityBean bean, Object value) {
super.setValue(bean, value);
}
@Override
- public void setValueIntercept(Object bean, Object value) {
+ public void setValueIntercept(EntityBean bean, Object value) {
super.setValueIntercept(bean, value);
}
@@ -324,7 +325,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
}
@Override
- public Object readSet(DbReadContext ctx, Object bean, Class> type) throws SQLException {
+ public Object readSet(DbReadContext ctx, EntityBean bean, Class> type) throws SQLException {
return null;
}
@@ -342,21 +343,21 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
return true;
}
- public void add(BeanCollection> collection, Object bean) {
+ public void add(BeanCollection> collection, EntityBean bean) {
help.add(collection, bean);
}
/**
* Refresh the appropriate list set or map.
*/
- public void refresh(EbeanServer server, Query> query, Transaction t, Object parentBean) {
+ public void refresh(EbeanServer server, Query> query, Transaction t, EntityBean parentBean) {
help.refresh(server, query, t, parentBean);
}
/**
* Apply the refreshed BeanCollection to the property of the parentBean.
*/
- public void refresh(BeanCollection> bc, Object parentBean) {
+ public void refresh(BeanCollection> bc, EntityBean parentBean) {
help.refresh(bc, parentBean);
}
@@ -364,7 +365,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
* Return the Id values from the given bean.
*/
@Override
- public Object[] getAssocOneIdValues(Object bean) {
+ public Object[] getAssocOneIdValues(EntityBean bean) {
return targetDescriptor.getIdBinder().getIdValues(bean);
}
@@ -435,7 +436,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
* Set the join properties from the parent bean to the child bean.
* This is only valid for OneToMany and NOT valid for ManyToMany.
*/
- public void setJoinValuesToChild(Object parent, Object child, Object mapKeyValue) {
+ public void setJoinValuesToChild(EntityBean parent, EntityBean child, Object mapKeyValue) {
if (mapKeyProperty != null){
mapKeyProperty.setValue(child, mapKeyValue);
@@ -468,7 +469,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
return mapKey;
}
- public BeanCollection> createReferenceIfNull(Object parentBean) {
+ public BeanCollection> createReferenceIfNull(EntityBean parentBean) {
Object v = getValue(parentBean);
if (v instanceof BeanCollection>){
@@ -479,7 +480,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
}
}
- public BeanCollection> createReference(Object parentBean) {
+ public BeanCollection> createReference(EntityBean parentBean) {
BeanCollection> ref = help.createReference(parentBean, name);
setValue(parentBean, ref);
@@ -494,7 +495,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
return help.getBeanCollectionAdd(bc, mapKey);
}
- public Object getParentId(Object parentBean) {
+ public Object getParentId(EntityBean parentBean) {
return descriptor.getId(parentBean);
}
@@ -518,8 +519,9 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
sqlUpd.addParameter(parentId);
return;
}
+ EntityBean parent = (EntityBean)parentId;
for (int i = 0; i < exportedProperties.length; i++) {
- Object embVal = exportedProperties[i].getValue(parentId);
+ Object embVal = exportedProperties[i].getValue(parent);
sqlUpd.addParameter(embVal);
}
}
@@ -531,8 +533,9 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
} else {
+ EntityBean parent = (EntityBean)parentId;
for (int i = 0; i < exportedProperties.length; i++) {
- Object embVal = exportedProperties[i].getValue(parentId);
+ Object embVal = exportedProperties[i].getValue(parent);
q.setParameter(pos++, embVal);
}
}
@@ -574,7 +577,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
return sb.toString();
}
- public void setPredicates(SpiQuery> query, Object parentBean) {
+ public void setPredicates(SpiQuery> query, EntityBean parentBean) {
if (manyToMany){
// for ManyToMany lazy loading we need to include a
@@ -586,7 +589,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
if (embeddedExportedProperties) {
// use the EmbeddedId object instead of the parentBean
BeanProperty[] uids = descriptor.propertiesId();
- parentBean = uids[0].getValue(parentBean);
+ parentBean = (EntityBean)uids[0].getValue(parentBean);
}
for (int i = 0; i < exportedProperties.length; i++) {
@@ -741,7 +744,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
throw new PersistenceException(msg);
}
- public IntersectionRow buildManyDeleteChildren(Object parentBean, ArrayList excludeDetailIds) {
+ public IntersectionRow buildManyDeleteChildren(EntityBean parentBean, ArrayList excludeDetailIds) {
IntersectionRow row = new IntersectionRow(tableJoin.getTable());
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
@@ -751,14 +754,14 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
return row;
}
- public IntersectionRow buildManyToManyDeleteChildren(Object parentBean) {
+ public IntersectionRow buildManyToManyDeleteChildren(EntityBean parentBean) {
IntersectionRow row = new IntersectionRow(intersectionJoin.getTable());
buildExport(row, parentBean);
return row;
}
- public IntersectionRow buildManyToManyMapBean(Object parent, Object other) {
+ public IntersectionRow buildManyToManyMapBean(EntityBean parent, EntityBean other) {
IntersectionRow row = new IntersectionRow(intersectionJoin.getTable());
@@ -767,11 +770,11 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
return row;
}
- private void buildExport(IntersectionRow row, Object parentBean) {
+ private void buildExport(IntersectionRow row, EntityBean parentBean) {
if (embeddedExportedProperties) {
BeanProperty[] uids = descriptor.propertiesId();
- parentBean = uids[0].getValue(parentBean);
+ parentBean = (EntityBean)uids[0].getValue(parentBean);
}
for (int i = 0; i < exportedProperties.length; i++) {
Object val = exportedProperties[i].getValue(parentBean);
@@ -785,7 +788,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
* Set the predicates for lazy loading of the association.
* Handles predicates for both OneToMany and ManyToMany.
*/
- private void buildImport(IntersectionRow row, Object otherBean) {
+ private void buildImport(IntersectionRow row, EntityBean otherBean) {
importedId.buildImport(row, otherBean);
}
@@ -793,12 +796,12 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
/**
* Return true if the otherBean has an Id value.
*/
- public boolean hasImportedId(Object otherBean) {
+ public boolean hasImportedId(EntityBean otherBean) {
return null != targetDescriptor.getId(otherBean);
}
- public void jsonWrite(WriteJsonContext ctx, Object bean) {
+ public void jsonWrite(WriteJsonContext ctx, EntityBean bean) {
if(!this.jsonSerialize){
return;
}
@@ -819,7 +822,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
}
}
- public void jsonRead(ReadJsonContext ctx, Object bean){
+ public void jsonRead(ReadJsonContext ctx, EntityBean bean){
if(!this.jsonDeserialize){
return;
}
@@ -836,7 +839,7 @@ public class BeanPropertyAssocMany extends BeanPropertyAssoc {
// probably empty array
break;
}
- Object detailBean = detailBeanState.getBean();
+ EntityBean detailBean = (EntityBean)detailBeanState.getBean();
add.addBean(detailBean);
if (bean != null && childMasterProperty != null){
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java
index 3352f7dd2..facdfdc03 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyAssocOne.java
@@ -34,8 +34,6 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
private final boolean oneToOneExported;
- private final boolean embeddedVersion;
-
private final boolean importedPrimaryKey;
private final LocalHelp localHelp;
@@ -78,11 +76,6 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
// Overriding of the columns and use table alias of owning BeanDescriptor
BeanEmbeddedMeta overrideMeta = BeanEmbeddedMetaFactory.create(owner, deploy, descriptor);
embeddedProps = overrideMeta.getProperties();
- if (id) {
- embeddedVersion = false;
- } else {
- embeddedVersion = overrideMeta.isEmbeddedVersion();
- }
embeddedPropsMap = new HashMap();
for (int i = 0; i < embeddedProps.length; i++) {
embeddedPropsMap.put(embeddedProps[i].getName(), embeddedProps[i]);
@@ -91,7 +84,6 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
} else {
embeddedProps = null;
embeddedPropsMap = null;
- embeddedVersion = false;
}
localHelp = createHelp(embedded, oneToOneExported);
}
@@ -130,11 +122,11 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
}
}
- public void cacheDelete(boolean clearOnNull, Object bean) {
+ public void cacheDelete(boolean clearOnNull, EntityBean bean) {
if (targetDescriptor.isBeanCaching() && relationshipProperty != null) {
Object assocBean = getValue(bean);
if (assocBean != null) {
- Object parentId = targetDescriptor.getId(assocBean);
+ Object parentId = targetDescriptor.getId((EntityBean)assocBean);
if (parentId != null) {
targetDescriptor.cacheRemoveCachedManyIds(parentId, relationshipProperty.getName());
return;
@@ -249,8 +241,9 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
} else {
int pos = 1;
+ EntityBean parent = (EntityBean)parentId;
for (int i = 0; i < exportedProperties.length; i++) {
- Object embVal = exportedProperties[i].getValue(parentId);
+ Object embVal = exportedProperties[i].getValue(parent);
q.setParameter(pos++, embVal);
}
}
@@ -270,41 +263,6 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
return true;
}
- private boolean hasChangedEmbedded(Object bean, Object oldValues) {
-
- Object embValue = getValue(oldValues);
- if (embValue instanceof EntityBean) {
- // the embedded bean .. has its own old values
- return ((EntityBean) embValue)._ebean_getIntercept().isNewOrDirty();
- }
- if (embValue == null) {
- return getValue(bean) != null;
- } else {
- return false;
- }
- }
-
- @Override
- public boolean hasChanged(Object bean, Object oldValues) {
- if (embedded) {
- return hasChangedEmbedded(bean, oldValues);
- }
- Object value = getValue(bean);
- Object oldVal = getValue(oldValues);
- if (oneToOneExported) {
- // FKey on other side
- return false;
- } else {
- if (value == null) {
- return oldVal != null;
- } else if (oldValues == null) {
- return true;
- }
-
- return importedId.hasChanged(value, oldVal);
- }
- }
-
/**
* Return meta data for the deployment of the embedded bean specific to this
* property.
@@ -342,13 +300,6 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
return oneToOneExported;
}
- /**
- * Returns true if the associated bean has version properties.
- */
- public boolean isEmbeddedVersion() {
- return embeddedVersion;
- }
-
/**
* If true this bean maps to the primary key.
*/
@@ -364,7 +315,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
return getPropertyType();
}
- public Object getCacheDataValue(Object bean){
+ public Object getCacheDataValue(EntityBean bean){
if (embedded) {
throw new RuntimeException();
} else {
@@ -372,24 +323,19 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
if (ap == null){
return null;
} else {
- return targetDescriptor.getId(ap);
+ return targetDescriptor.getId((EntityBean)ap);
}
}
}
- public void setCacheDataValue(Object bean, Object cacheData, Object oldValues, boolean readOnly){
+ @Override
+ public void setCacheDataValue(EntityBean bean, Object cacheData){
if (cacheData != null) {
if (embedded){
throw new RuntimeException();
} else {
- T ref = targetDescriptor.createReference(Boolean.FALSE, cacheData, null);
+ T ref = targetDescriptor.createReference(Boolean.FALSE, cacheData);
setValue(bean, ref);
- if (oldValues != null){
- setValue(oldValues, ref);
- }
- if (readOnly){
- ((EntityBean)ref)._ebean_intercept().setReadOnly(true);
- }
}
}
}
@@ -398,7 +344,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
* Return the Id values from the given bean.
*/
@Override
- public Object[] getAssocOneIdValues(Object bean) {
+ public Object[] getAssocOneIdValues(EntityBean bean) {
return targetDescriptor.getIdBinder().getIdValues(bean);
}
@@ -451,7 +397,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
return targetDescriptor.createEntityBean();
}
- public void elSetReference(Object bean) {
+ public void elSetReference(EntityBean bean) {
Object value = getValueIntercept(bean);
if (value != null) {
((EntityBean) value)._ebean_getIntercept().setReference();
@@ -459,7 +405,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
}
@Override
- public Object elGetReference(Object bean) {
+ public Object elGetReference(EntityBean bean) {
Object value = getValueIntercept(bean);
if (value == null) {
value = targetDescriptor.createEntityBean();
@@ -565,7 +511,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
}
@Override
- public Object readSet(DbReadContext ctx, Object bean, Class> type) throws SQLException {
+ public Object readSet(DbReadContext ctx, EntityBean bean, Class> type) throws SQLException {
boolean assignable = (type == null || owningType.isAssignableFrom(type));
return localHelp.readSet(ctx, bean, assignable);
}
@@ -579,6 +525,24 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
// pass in null for the bean so any data read is ignored
return localHelp.read(ctx);
}
+
+ @Override
+ public void setValue(EntityBean bean, Object value) {
+ super.setValue(bean, value);
+ if (value instanceof EntityBean) {
+ EntityBean embedded = (EntityBean)value;
+ embedded._ebean_getIntercept().setEmbeddedOwner(bean, propertyIndex);
+ }
+ }
+
+ @Override
+ public void setValueIntercept(EntityBean bean, Object value) {
+ super.setValueIntercept(bean, value);
+ if (value instanceof EntityBean) {
+ EntityBean embedded = (EntityBean)value;
+ embedded._ebean_getIntercept().setEmbeddedOwner(bean, propertyIndex);
+ }
+ }
@Override
public void loadIgnore(DbReadContext ctx) {
@@ -615,7 +579,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
abstract Object read(DbReadContext ctx) throws SQLException;
- abstract Object readSet(DbReadContext ctx, Object bean, boolean assignAble) throws SQLException;
+ abstract Object readSet(DbReadContext ctx, EntityBean bean, boolean assignAble) throws SQLException;
abstract void appendSelect(DbSqlContext ctx, boolean subQuery);
@@ -632,7 +596,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
}
@Override
- Object readSet(DbReadContext ctx, Object bean, boolean assignable) throws SQLException {
+ Object readSet(DbReadContext ctx, EntityBean bean, boolean assignable) throws SQLException {
Object dbVal = read(ctx);
if (bean != null && assignable) {
// set back to the parent bean
@@ -694,7 +658,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
}
}
- Object readSet(DbReadContext ctx, Object bean, boolean assignable) throws SQLException {
+ Object readSet(DbReadContext ctx, EntityBean bean, boolean assignable) throws SQLException {
Object val = read(ctx);
if (bean != null && assignable) {
setValue(bean, val);
@@ -733,16 +697,13 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
return existing;
}
- // parent always null for this case (but here to document)
- Object parent = null;
-
Boolean readOnly = ctx.isReadOnly();
Object ref;
if (targetInheritInfo != null) {
- // for inheritance hierarchy create the correct type for this row...
- ref = rowDescriptor.createReference(readOnly, id, parent);
+ // for inheritance hierarchy create the correct type for this row...
+ ref = rowDescriptor.createReference(readOnly, id);
} else {
- ref = targetDescriptor.createReference(readOnly, id, parent);
+ ref = targetDescriptor.createReference(readOnly, id);
}
Object existingBean = ctx.getPersistenceContext().putIfAbsent(id, ref);
@@ -802,7 +763,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
* Read and set a Reference bean.
*/
@Override
- Object readSet(DbReadContext ctx, Object bean, boolean assignable) throws SQLException {
+ Object readSet(DbReadContext ctx, EntityBean bean, boolean assignable) throws SQLException {
Object dbVal = read(ctx);
if (bean != null && assignable) {
@@ -828,8 +789,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
if (existing != null) {
return existing;
}
- Object parent = null;
- Object ref = targetDescriptor.createReference(ctx.isReadOnly(), id, parent);
+ Object ref = targetDescriptor.createReference(ctx.isReadOnly(), id);
EntityBeanIntercept ebi = ((EntityBean) ref)._ebean_getIntercept();
if (Boolean.TRUE.equals(ctx.isReadOnly())) {
@@ -867,7 +827,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
}
@Override
- public void jsonWrite(WriteJsonContext ctx, Object bean) {
+ public void jsonWrite(WriteJsonContext ctx, EntityBean bean) {
Object value = getValueIntercept(bean);
if (value == null){
@@ -881,7 +841,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
ctx.pushParentBean(bean);
ctx.beginAssocOne(name);
BeanDescriptor> refDesc = descriptor.getBeanDescriptor(value.getClass());
- refDesc.jsonWrite(ctx, value);
+ refDesc.jsonWrite(ctx, (EntityBean)value);
ctx.endAssocOne();
ctx.popParentBean();
}
@@ -889,7 +849,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc {
}
@Override
- public void jsonRead(ReadJsonContext ctx, Object bean){
+ public void jsonRead(ReadJsonContext ctx, EntityBean bean){
T assocBean = targetDescriptor.jsonReadBean(ctx, name);
setValue(bean, assocBean);
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompound.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompound.java
index 1b229cb48..00132e1d3 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompound.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompound.java
@@ -4,6 +4,7 @@ import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.config.ScalarTypeConverter;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertyCompound;
import com.avaje.ebeaninternal.server.el.ElPropertyChainBuilder;
@@ -89,7 +90,7 @@ public class BeanPropertyCompound extends BeanProperty {
* Get the underlying compound type.
*/
@SuppressWarnings("unchecked")
- public Object getValueUnderlying(Object bean) {
+ public Object getValueUnderlying(EntityBean bean) {
Object value = getValue(bean);
if (typeConverter != null){
@@ -97,27 +98,7 @@ public class BeanPropertyCompound extends BeanProperty {
}
return value;
}
-
- @Override
- public Object getValue(Object bean) {
- return super.getValue(bean);
- }
-
- @Override
- public Object getValueIntercept(Object bean) {
- return super.getValueIntercept(bean);
- }
-
- @Override
- public void setValue(Object bean, Object value) {
- super.setValue(bean, value);
- }
-
- @Override
- public void setValueIntercept(Object bean, Object value) {
- super.setValueIntercept(bean, value);
- }
-
+
public ElPropertyValue buildElPropertyValue(String propName, String remainder, ElPropertyChainBuilder chain, boolean propertyDeploy) {
if (chain == null) {
@@ -154,7 +135,7 @@ public class BeanPropertyCompound extends BeanProperty {
}
@Override
- public Object readSet(DbReadContext ctx, Object bean, Class> type) throws SQLException {
+ public Object readSet(DbReadContext ctx, EntityBean bean, Class> type) throws SQLException {
boolean assignable = (type == null || owningType.isAssignableFrom(type));
@@ -192,17 +173,17 @@ public class BeanPropertyCompound extends BeanProperty {
}
@Override
- public Object elGetReference(Object bean) {
+ public Object elGetReference(EntityBean bean) {
return bean;
}
- public void jsonWrite(WriteJsonContext ctx, Object bean) {
+ public void jsonWrite(WriteJsonContext ctx, EntityBean bean) {
Object valueObject = getValueIntercept(bean);
compoundType.jsonWrite(ctx, valueObject, name);
}
- public void jsonRead(ReadJsonContext ctx, Object bean){
+ public void jsonRead(ReadJsonContext ctx, EntityBean bean){
Object objValue = compoundType.jsonRead(ctx);
setValue(bean, objValue);
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompoundRoot.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompoundRoot.java
index 64a5ed286..064a862ec 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompoundRoot.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompoundRoot.java
@@ -73,7 +73,7 @@ public class BeanPropertyCompoundRoot {
* Set the value of the property without interception or
* PropertyChangeSupport.
*/
- public void setRootValue(Object bean, Object value) {
+ public void setRootValue(EntityBean bean, Object value) {
try {
if (bean instanceof EntityBean) {
setter.set(bean, value);
@@ -92,7 +92,7 @@ public class BeanPropertyCompoundRoot {
/**
* Set the value of the property.
*/
- public void setRootValueIntercept(Object bean, Object value) {
+ public void setRootValueIntercept(EntityBean bean, Object value) {
try {
if (bean instanceof EntityBean) {
setter.setIntercept(bean, value);
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompoundScalar.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompoundScalar.java
index 928cc5dd8..67c9725be 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompoundScalar.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanPropertyCompoundScalar.java
@@ -1,5 +1,6 @@
package com.avaje.ebeaninternal.server.deploy;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.config.ScalarTypeConverter;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import com.avaje.ebeaninternal.server.type.CtCompoundProperty;
@@ -30,20 +31,21 @@ public class BeanPropertyCompoundScalar extends BeanProperty {
@SuppressWarnings("unchecked")
@Override
- public Object getValue(Object valueObject) {
- if (typeConverter != null){
- valueObject = typeConverter.unwrapValue(valueObject);
+ public Object getValue(EntityBean valueObject) {
+ Object val = valueObject;
+ if (typeConverter != null){
+ val = typeConverter.unwrapValue(val);
}
- return ctProperty.getValue(valueObject);
+ return ctProperty.getValue(val);
}
@Override
- public void setValue(Object bean, Object value) {
+ public void setValue(EntityBean bean, Object value) {
setValueInCompound(bean, value, false);
}
@SuppressWarnings("unchecked")
- public void setValueInCompound(Object bean, Object value, boolean intercept) {
+ public void setValueInCompound(EntityBean bean, Object value, boolean intercept) {
Object compoundValue = ctProperty.setValue(bean, value);
@@ -65,7 +67,7 @@ public class BeanPropertyCompoundScalar extends BeanProperty {
* No interception on embedded scalar values inside a CVO.
*/
@Override
- public void setValueIntercept(Object bean, Object value) {
+ public void setValueIntercept(EntityBean bean, Object value) {
setValueInCompound(bean, value, true);
}
@@ -73,27 +75,27 @@ public class BeanPropertyCompoundScalar extends BeanProperty {
* No interception on embedded scalar values inside a CVO.
*/
@Override
- public Object getValueIntercept(Object bean) {
+ public Object getValueIntercept(EntityBean bean) {
return getValue(bean);
}
@Override
- public Object elGetReference(Object bean) {
+ public Object elGetReference(EntityBean bean) {
return getValue(bean);
}
@Override
- public Object elGetValue(Object bean) {
+ public Object elGetValue(EntityBean bean) {
return getValue(bean);
}
@Override
- public void elSetReference(Object bean) {
+ public void elSetReference(EntityBean bean) {
super.elSetReference(bean);
}
@Override
- public void elSetValue(Object bean, Object value, boolean populate, boolean reference) {
+ public void elSetValue(EntityBean bean, Object value, boolean populate, boolean reference) {
super.elSetValue(bean, value, populate, reference);
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanSetHelp.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanSetHelp.java
index 0691d24eb..57ff5575c 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanSetHelp.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanSetHelp.java
@@ -10,6 +10,7 @@ import com.avaje.ebean.Transaction;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.BeanCollectionAdd;
import com.avaje.ebean.bean.BeanCollectionLoader;
+import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.common.BeanSet;
import com.avaje.ebeaninternal.server.text.json.WriteJsonContext;
@@ -72,15 +73,12 @@ public final class BeanSetHelp implements BeanCollectionHelp {
this.set = set;
}
- public void addBean(Object bean) {
+ public void addBean(EntityBean bean) {
set.add(bean);
}
}
- /**
- * Internal add bypassing any modify listening.
- */
- public void add(BeanCollection> collection, Object bean) {
+ public void add(BeanCollection> collection, EntityBean bean) {
collection.internalAdd(bean);
}
@@ -95,20 +93,20 @@ public final class BeanSetHelp implements BeanCollectionHelp {
return beanSet;
}
- public BeanCollection createReference(Object parentBean, String propertyName) {
+ public BeanCollection createReference(EntityBean parentBean, String propertyName) {
BeanSet beanSet = new BeanSet(loader, parentBean, propertyName);
beanSet.setModifyListening(many.getModifyListenMode());
return beanSet;
}
- public void refresh(EbeanServer server, Query> query, Transaction t, Object parentBean) {
+ public void refresh(EbeanServer server, Query> query, Transaction t, EntityBean parentBean) {
BeanSet> newBeanSet = (BeanSet>)server.findSet(query, t);
refresh(newBeanSet, parentBean);
}
- public void refresh(BeanCollection> bc, Object parentBean) {
+ public void refresh(BeanCollection> bc, EntityBean parentBean) {
BeanSet> newBeanSet = (BeanSet>)bc;
@@ -158,7 +156,7 @@ public final class BeanSetHelp implements BeanCollectionHelp {
if (count++ > 0){
ctx.appendComma();
}
- targetDescriptor.jsonWrite(ctx, detailBean);
+ targetDescriptor.jsonWrite(ctx, (EntityBean)detailBean);
}
ctx.endAssocMany();
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/ChainedBeanPersistListener.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/ChainedBeanPersistListener.java
index da19e74d4..e5d7a1f81 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/ChainedBeanPersistListener.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/ChainedBeanPersistListener.java
@@ -2,7 +2,6 @@ package com.avaje.ebeaninternal.server.deploy;
import java.util.ArrayList;
import java.util.List;
-import java.util.Set;
import com.avaje.ebean.event.BeanPersistListener;
@@ -110,10 +109,10 @@ public class ChainedBeanPersistListener