mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
initial rework for new enhancement
This commit is contained in:
@@ -90,5 +90,5 @@ public interface BeanState {
|
||||
* the properties that where loaded or null for a fully loaded entity
|
||||
* bean.
|
||||
*/
|
||||
public void setLoaded(Set<String> loadedProperties);
|
||||
public void setLoaded();
|
||||
}
|
||||
@@ -13,10 +13,5 @@ public enum ConcurrencyMode {
|
||||
/**
|
||||
* Use a version column.
|
||||
*/
|
||||
VERSION,
|
||||
|
||||
/**
|
||||
* Use all the columns (except Lobs).
|
||||
*/
|
||||
ALL
|
||||
VERSION
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public interface BeanCollection<E> extends Serializable {
|
||||
/**
|
||||
* Return the bean that owns this collection.
|
||||
*/
|
||||
public Object getOwnerBean();
|
||||
public EntityBean getOwnerBean();
|
||||
|
||||
/**
|
||||
* Return the bean property name this collection represents.
|
||||
|
||||
@@ -12,5 +12,5 @@ public interface BeanCollectionAdd {
|
||||
/**
|
||||
* Add a loaded bean to the collection.
|
||||
*/
|
||||
public void addBean(Object bean);
|
||||
public void addBean(EntityBean bean);
|
||||
}
|
||||
|
||||
@@ -83,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.
|
||||
* <p>
|
||||
* Note that using this method bypasses any interception that otherwise occurs
|
||||
* on entity beans. That means lazy loading and oldValues creation.
|
||||
* </p>
|
||||
*
|
||||
* @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.
|
||||
@@ -115,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.
|
||||
* </p>
|
||||
*
|
||||
* @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);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.beans.PropertyChangeSupport;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
@@ -24,6 +25,10 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
|
||||
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;
|
||||
@@ -31,7 +36,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
private transient PersistenceContext persistenceContext;
|
||||
|
||||
private transient BeanLoader beanLoader;
|
||||
|
||||
|
||||
private int beanLoaderIndex;
|
||||
|
||||
private String ebeanServerName;
|
||||
@@ -44,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 boolean[] loadedProps;
|
||||
private boolean[] loadedProps;
|
||||
|
||||
private boolean fullyLoadedBean;
|
||||
|
||||
/**
|
||||
* Set of changed properties.
|
||||
*/
|
||||
private boolean[] changedProps;
|
||||
|
||||
private int lazyLoadProperty;
|
||||
private Object[] origValues;
|
||||
|
||||
private int lazyLoadProperty = -1;
|
||||
|
||||
/**
|
||||
* Create a intercept with a given entity.
|
||||
@@ -99,20 +93,9 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* Refer to agent ProxyConstructor.
|
||||
* </p>
|
||||
*/
|
||||
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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -122,13 +105,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (!loaded) {
|
||||
return "Reference...";
|
||||
}
|
||||
return "OldValues: " + oldValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the persistenceContext.
|
||||
*/
|
||||
@@ -193,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,33 +280,11 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bean currently has interception on.
|
||||
* <p>
|
||||
* With interception on the bean will invoke lazy loading and dirty checking.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isIntercepting() {
|
||||
return intercepting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn interception off or on.
|
||||
* <p>
|
||||
* This is to support custom serialisation mechanisms that just read all the
|
||||
* properties on the bean.
|
||||
* </p>
|
||||
*
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,12 +299,12 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* </p>
|
||||
*/
|
||||
public void setLoaded() {
|
||||
this.loaded = true;
|
||||
this.oldValues = null;
|
||||
this.intercepting = true;
|
||||
this.state = STATE_LOADED;
|
||||
this.owner._ebean_setEmbeddedLoaded();
|
||||
this.lazyLoadProperty = -1;
|
||||
this.origValues = null;
|
||||
this.changedProps = null;
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,8 +312,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* bean.
|
||||
*/
|
||||
public void setLoadedLazy() {
|
||||
this.loaded = true;
|
||||
this.intercepting = true;
|
||||
this.state = STATE_LOADED;
|
||||
this.lazyLoadProperty = -1;
|
||||
}
|
||||
|
||||
@@ -423,27 +382,104 @@ 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(boolean[] loadedPropertyNames) {
|
||||
// this.loadedProps = loadedPropertyNames;
|
||||
// }
|
||||
public String getProperty(int propertyIndex) {
|
||||
if (propertyIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
return owner._ebean_getPropertyName(propertyIndex);
|
||||
}
|
||||
|
||||
public void setLoadedProps(Set<String> loadedPropertyNames) {
|
||||
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 boolean[] getLoadedProps() {
|
||||
// return loadedProps;
|
||||
// }
|
||||
public Set<String> getLoadedProps() {
|
||||
return null;
|
||||
public Set<String> getLoadedPropertyNames() {
|
||||
if (fullyLoadedBean) {
|
||||
return null;
|
||||
}
|
||||
Set<String> props = new LinkedHashSet<String>();
|
||||
for (int i=0; i<loadedProps.length; i++) {
|
||||
if (loadedProps[i]) {
|
||||
props.add(getProperty(i));
|
||||
}
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
public Set<String> getChangedPropertyNames() {
|
||||
Set<String> props = new LinkedHashSet<String>();
|
||||
if (changedProps != null) {
|
||||
for (int i=0; i<changedProps.length; i++) {
|
||||
if (changedProps[i]) {
|
||||
props.add(getProperty(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
public int getChangedPropertiesHash() {
|
||||
int h = 1;
|
||||
if (changedProps != null) {
|
||||
for (int i=0; i<changedProps.length; i++) {
|
||||
if (changedProps[i]) {
|
||||
h = h * 31 + (i+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,19 +488,16 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
public boolean[] getChanged() {
|
||||
return changedProps;
|
||||
}
|
||||
|
||||
public Set<String> getChangedProps() {
|
||||
return null;
|
||||
|
||||
public boolean[] getLoaded() {
|
||||
return loadedProps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the property read or write that triggered the lazy load.
|
||||
*/
|
||||
// public int getLazyLoadProperty() {
|
||||
// return lazyLoadProperty;
|
||||
// }
|
||||
public String getLazyLoadProperty() {
|
||||
return null;
|
||||
public int getLazyLoadProperty() {
|
||||
return lazyLoadProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -498,16 +531,11 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
*/
|
||||
private void loadBeanInternal(int loadProperty, BeanLoader loader) {
|
||||
|
||||
if (loaded && (loadedProps == null || loadedProps[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");
|
||||
@@ -533,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.
|
||||
*/
|
||||
@@ -571,7 +585,6 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
if (obj1 instanceof URL) {
|
||||
// use the string format to determine if dirty
|
||||
@@ -582,22 +595,17 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
|
||||
/**
|
||||
* Method that is called prior to a getter method on the actual entity.
|
||||
* <p>
|
||||
* This checks if the bean is a reference and should be loaded.
|
||||
* </p>
|
||||
*/
|
||||
public void preGetter(int propertyIndex) {
|
||||
if (!intercepting) {
|
||||
if (state == STATE_NEW || disableLazyLoad) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!loaded) {
|
||||
loadBean(propertyIndex);
|
||||
} else if (loadedProps != null && !loadedProps[propertyIndex]) {
|
||||
|
||||
if (!isLoadedProperty(propertyIndex)) {
|
||||
loadBean(propertyIndex);
|
||||
}
|
||||
|
||||
if (nodeUsageCollector != null && loaded) {
|
||||
if (nodeUsageCollector != null) {
|
||||
nodeUsageCollector.addUsed(getProperty(propertyIndex));
|
||||
}
|
||||
}
|
||||
@@ -631,10 +639,15 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
* OneToMany and ManyToMany don't have any interception so just check for
|
||||
* PropertyChangeSupport.
|
||||
*/
|
||||
public PropertyChangeEvent preSetterMany(boolean interceptField, int propertyIndex,
|
||||
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, getProperty(propertyIndex), oldValue, newValue);
|
||||
} else {
|
||||
@@ -642,57 +655,27 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public String getProperty(int propertyIndex) {
|
||||
return owner._ebean_getPropertyName(propertyIndex);
|
||||
}
|
||||
|
||||
public int getPropertyLength() {
|
||||
return owner._ebean_getPropertyNames().length;
|
||||
}
|
||||
private void setChangedPropertyValue(int propertyIndex, boolean setDirtyState, Object origValue) {
|
||||
|
||||
private final void changedProperty(int propertyIndex, boolean setDirty) {
|
||||
|
||||
if (changedProps == null) {
|
||||
changedProps = new boolean[owner._ebean_getPropertyNames().length];
|
||||
}
|
||||
changedProps[propertyIndex] = true;
|
||||
|
||||
if (!setDirty || !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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void addDirty(int propertyIndex) {
|
||||
|
||||
if (!intercepting) {
|
||||
return;
|
||||
}
|
||||
if (readOnly) {
|
||||
throw new IllegalStateException("This bean is readOnly");
|
||||
}
|
||||
|
||||
if (loaded) {
|
||||
if (oldValues == null) {
|
||||
// first time this bean is being made dirty
|
||||
createOldValues();
|
||||
}
|
||||
if (changedProps == null) {
|
||||
changedProps = new boolean[getPropertyLength()];
|
||||
}
|
||||
changedProps[propertyIndex] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check to see if the values are not equal. If they are not equal then create
|
||||
@@ -700,205 +683,167 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
*/
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, Object oldValue, Object newValue) {
|
||||
|
||||
// If state 'new' then mark property as changed
|
||||
// Else state is 'update', check for change
|
||||
if (!areEqual(oldValue, newValue)) {
|
||||
changedProperty(propertyIndex, intercept);
|
||||
if (pcs != null) {
|
||||
return new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
|
||||
}
|
||||
if (state == STATE_NEW) {
|
||||
setLoadedProperty(propertyIndex);
|
||||
} else if (!areEqual(oldValue, newValue)) {
|
||||
setChangedPropertyValue(propertyIndex, intercept, newValue);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check for primitive boolean.
|
||||
*/
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, boolean oldValue,
|
||||
boolean newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, boolean oldValue, boolean newValue) {
|
||||
|
||||
boolean changed = oldValue != newValue;
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), 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, int propertyIndex, int oldValue,
|
||||
int newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, int oldValue, int newValue) {
|
||||
|
||||
boolean changed = oldValue != newValue;
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), 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, int propertyIndex, long oldValue,
|
||||
long newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, long oldValue, long newValue) {
|
||||
|
||||
boolean changed = oldValue != newValue;
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), 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, int propertyIndex, double oldValue,
|
||||
double newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, double oldValue, double newValue) {
|
||||
|
||||
boolean changed = oldValue != newValue;
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), 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, int propertyIndex, float oldValue,
|
||||
float newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, float oldValue, float newValue) {
|
||||
|
||||
boolean changed = oldValue != newValue;
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), 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, int propertyIndex, short oldValue,
|
||||
short newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, short oldValue, short newValue) {
|
||||
|
||||
boolean changed = oldValue != newValue;
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), 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, int propertyIndex, char oldValue,
|
||||
char newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, char oldValue, char newValue) {
|
||||
|
||||
boolean changed = oldValue != newValue;
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), 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, int propertyIndex, byte oldValue,
|
||||
byte newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, byte oldValue, byte newValue) {
|
||||
|
||||
boolean changed = oldValue != newValue;
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), 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, int propertyIndex, char[] oldValue,
|
||||
char[] newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, char[] oldValue, char[] newValue) {
|
||||
|
||||
boolean changed = !areEqualChars(oldValue, newValue);
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), oldValue, newValue);
|
||||
}
|
||||
return null;
|
||||
return (pcs == null) ? null: new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* byte[].
|
||||
*/
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, byte[] oldValue,
|
||||
byte[] newValue) {
|
||||
public PropertyChangeEvent preSetter(boolean intercept, int propertyIndex, byte[] oldValue, byte[] newValue) {
|
||||
|
||||
boolean changed = !areEqualBytes(oldValue, newValue);
|
||||
|
||||
if (intercept && changed) {
|
||||
addDirty(propertyIndex);
|
||||
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, getProperty(propertyIndex), oldValue, newValue);
|
||||
}
|
||||
return null;
|
||||
return (pcs == null) ? null : new PropertyChangeEvent(owner, getProperty(propertyIndex), oldValue, newValue);
|
||||
}
|
||||
|
||||
private static boolean areEqualBytes(byte[] b1, byte[] b2) {
|
||||
|
||||
@@ -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<E> implements BeanCollection<E> {
|
||||
/**
|
||||
* 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<E> implements BeanCollection<E> {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<E> extends AbstractBeanCollection<E> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<K, E> extends AbstractBeanCollection<E> implements Ma
|
||||
this(new LinkedHashMap<K, E>());
|
||||
}
|
||||
|
||||
public BeanMap(BeanCollectionLoader ebeanServer, Object ownerBean, String propertyName) {
|
||||
public BeanMap(BeanCollectionLoader ebeanServer, EntityBean ownerBean, String propertyName) {
|
||||
super(ebeanServer, ownerBean, propertyName);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -34,12 +35,12 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
this(new LinkedHashSet<E>());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public interface BeanPersistListener<T> {
|
||||
* @param updatedProperties
|
||||
* the properties on the bean that where updated
|
||||
*/
|
||||
public boolean updated(T bean, Set<String> updatedProperties);
|
||||
public boolean updated(T bean);//, Set<String> updatedProperties);
|
||||
|
||||
/**
|
||||
* Notified that a bean has been deleted locally. Return true if you want the
|
||||
|
||||
@@ -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<T> {
|
||||
*/
|
||||
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<String> getLoadedProperties();
|
||||
|
||||
/**
|
||||
* For an update this is the set of properties that where updated.
|
||||
*/
|
||||
public Set<String> getUpdatedProperties();
|
||||
// /**
|
||||
// * For an update or delete of a partially populated bean this is the set of
|
||||
// * loaded properties and otherwise returns null.
|
||||
// */
|
||||
// public Set<String> getLoadedProperties();
|
||||
//
|
||||
// /**
|
||||
// * For an update this is the set of properties that where updated.
|
||||
// */
|
||||
// public Set<String> 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.
|
||||
* <p>
|
||||
* This is for updates only.
|
||||
* </p>
|
||||
*/
|
||||
public T getOldValues();
|
||||
// /**
|
||||
// * Returns a bean containing the original values prior to the bean being
|
||||
// * modified.
|
||||
// * <p>
|
||||
// * This is for updates only.
|
||||
// * </p>
|
||||
// */
|
||||
// public T getOldValues();
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
* <p>
|
||||
* Can occur when the only columns updated have a updatable=false in their
|
||||
* deployment.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isEmptySetClause();
|
||||
/**
|
||||
* Return true if the set clause has no columns.
|
||||
* <p>
|
||||
* Can occur when the only columns updated have a updatable=false in their
|
||||
* deployment.
|
||||
* </p>
|
||||
*/
|
||||
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<String> getProperties();
|
||||
// /**
|
||||
// * Return the properties that where changed and should be included in the
|
||||
// * update statement.
|
||||
// */
|
||||
// public Set<String> getProperties();
|
||||
|
||||
}
|
||||
@@ -93,9 +93,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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +1,51 @@
|
||||
package com.avaje.ebeaninternal.server.cache;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class CachedBeanData {
|
||||
|
||||
private final Object sharableBean;
|
||||
private final Set<String> loadedProperties;
|
||||
private final Object[] data;
|
||||
private final int naturalKeyUpdate;
|
||||
|
||||
public CachedBeanData(Object sharableBean, Set<String> 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<String> getLoadedProperties() {
|
||||
return loadedProperties;
|
||||
}
|
||||
|
||||
public Object[] copyData() {
|
||||
Object[] dest = new Object[data.length];
|
||||
System.arraycopy(data, 0, dest, 0, data.length);
|
||||
return dest;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+63
-87
@@ -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<String> loadedProps;
|
||||
private final Set<String> 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<String>();
|
||||
} else {
|
||||
this.extractProps = new HashSet<String>();
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
+44
-99
@@ -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<String> cacheLoadedProperties;
|
||||
private final Set<String> loadedProps;
|
||||
|
||||
private final Set<String> 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<String>();
|
||||
|
||||
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<String> mergeProps = new HashSet<String>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
+31
-30
@@ -11,37 +11,38 @@ public class CachedBeanDataUpdate {
|
||||
|
||||
public static CachedBeanData update(BeanDescriptor<?> desc, CachedBeanData data, PersistRequestBean<?> updateRequest){
|
||||
|
||||
|
||||
Set<String> loadedProperties = data.getLoadedProperties();
|
||||
Object[] copyOfData = data.copyData();
|
||||
|
||||
Object updateBean = updateRequest.getBean();
|
||||
Set<String> 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<String> mergeProps = new HashSet<String>();
|
||||
mergeProps.addAll(loadedProperties);
|
||||
mergeProps.addAll(updatedProperties);
|
||||
loadedProperties = mergeProps;
|
||||
}
|
||||
|
||||
return new CachedBeanData(null, loadedProperties, copyOfData, naturalKeyUpdate);
|
||||
//
|
||||
// Set<String> loadedProperties = data.getLoadedProperties();
|
||||
// Object[] copyOfData = data.copyData();
|
||||
//
|
||||
// Object updateBean = updateRequest.getBean();
|
||||
// Set<String> 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<String> mergeProps = new HashSet<String>();
|
||||
// mergeProps.addAll(loadedProperties);
|
||||
// mergeProps.addAll(updatedProperties);
|
||||
// loadedProperties = mergeProps;
|
||||
// }
|
||||
//
|
||||
// return new CachedBeanData(null, loadedProperties, copyOfData, naturalKeyUpdate);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -325,10 +325,6 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
|
||||
} else if (isEntity(cls)) {
|
||||
entityList.add(cls);
|
||||
|
||||
} else if (isXmlBean(cls)){
|
||||
entityList.add(cls);
|
||||
//xmlBeanList.add(cls);
|
||||
|
||||
} else if (isInterestingInterface(cls)) {
|
||||
return true;
|
||||
@@ -420,17 +416,4 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isXmlBean(Class<?> cls) {
|
||||
|
||||
Annotation ann = cls.getAnnotation(XmlRootElement.class);
|
||||
if (ann != null) {
|
||||
return true;
|
||||
}
|
||||
ann = cls.getAnnotation(XmlType.class);
|
||||
if (ann != null) {
|
||||
// Only looking for Beans and not Enums
|
||||
return !cls.isEnum();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class DefaultBeanLoader {
|
||||
return requestedBatchSize;
|
||||
}
|
||||
|
||||
public void refreshMany(Object parentBean, String propertyName) {
|
||||
public void refreshMany(EntityBean parentBean, String propertyName) {
|
||||
refreshMany(parentBean, propertyName, null);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,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);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ public class DefaultBeanLoader {
|
||||
|
||||
public void loadMany(BeanCollection<?> bc, LoadManyContext ctx, boolean onlyIds) {
|
||||
|
||||
Object parentBean = bc.getOwnerBean();
|
||||
EntityBean parentBean = bc.getOwnerBean();
|
||||
String propertyName = bc.getPropertyName();
|
||||
|
||||
ObjectGraphNode node = ctx == null ? null : ctx.getObjectGraphNode();
|
||||
@@ -164,11 +164,11 @@ public class DefaultBeanLoader {
|
||||
loadManyInternal(parentBean, propertyName, null, false, node, 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 = null;
|
||||
PersistenceContext pc = null;
|
||||
@@ -282,7 +282,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);
|
||||
}
|
||||
@@ -305,17 +305,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);
|
||||
@@ -338,7 +327,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +341,7 @@ public class DefaultBeanLoader {
|
||||
|
||||
}
|
||||
|
||||
public void refresh(Object bean) {
|
||||
public void refresh(EntityBean bean) {
|
||||
refreshBeanInternal(bean, SpiQuery.Mode.REFRESH_BEAN);
|
||||
}
|
||||
|
||||
@@ -360,7 +349,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();;
|
||||
@@ -381,7 +370,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;
|
||||
}
|
||||
}
|
||||
@@ -392,15 +381,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
|
||||
|
||||
@@ -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<String> getLoadedProps() {
|
||||
Set<String> props = intercept.getLoadedProps();
|
||||
return props == null ? null : Collections.unmodifiableSet(props);
|
||||
return intercept.getLoadedPropertyNames();
|
||||
}
|
||||
|
||||
public Set<String> getChangedProps() {
|
||||
Set<String> 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<String> loadedProperties) {
|
||||
intercept.setLoadedProps(loadedProperties);
|
||||
intercept.setLoaded();
|
||||
public void setLoaded() {
|
||||
intercept.setLoaded();
|
||||
}
|
||||
|
||||
public void setReference() {
|
||||
|
||||
@@ -115,6 +115,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;
|
||||
@@ -486,12 +490,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) {
|
||||
@@ -506,7 +510,7 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
|
||||
public void refresh(Object bean) {
|
||||
|
||||
beanLoader.refresh(bean);
|
||||
beanLoader.refresh(checkEntityBean(bean));
|
||||
}
|
||||
|
||||
public void loadBean(LoadBeanRequest loadRequest) {
|
||||
@@ -638,7 +642,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)) {
|
||||
@@ -1565,10 +1569,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1606,10 +1608,8 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
* include in the update.
|
||||
*/
|
||||
public void update(Object bean, Set<String> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1635,12 +1635,19 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
* </p>
|
||||
*/
|
||||
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.
|
||||
@@ -1661,10 +1668,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;
|
||||
|
||||
@@ -1688,11 +1696,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();
|
||||
|
||||
@@ -1708,21 +1717,12 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
|
||||
public void saveAssociation(Object ownerBean, String propertyName, Transaction t) {
|
||||
|
||||
if (ownerBean instanceof EntityBean) {
|
||||
Set<String> 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();
|
||||
|
||||
@@ -1758,7 +1758,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++;
|
||||
}
|
||||
@@ -1822,10 +1822,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1853,7 +1851,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++;
|
||||
}
|
||||
@@ -1949,13 +1947,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2021,8 +2020,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.
|
||||
|
||||
@@ -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<String, ValuePair> map = new LinkedHashMap<String, ValuePair>();
|
||||
|
||||
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<String, ValuePair> 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) {
|
||||
|
||||
@@ -365,8 +365,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
|
||||
cacheKey = Integer.valueOf(31 * query.queryHash() + query.getType().hashCode());
|
||||
}
|
||||
|
||||
// TODO: Sort out returning BeanCollection from L2 cache
|
||||
return null;
|
||||
return beanDescriptor.queryCacheGet(cacheKey);
|
||||
}
|
||||
|
||||
public void putToQueryCache(BeanCollection<T> queryResult) {
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
|
||||
@@ -41,6 +40,13 @@ public class PersistRequestBean<T> extends PersistRequest implements BeanPersist
|
||||
*/
|
||||
protected final BeanPersistController controller;
|
||||
|
||||
/**
|
||||
* The bean being persisted.
|
||||
*/
|
||||
protected final T bean;
|
||||
|
||||
protected final EntityBean entityBean;
|
||||
|
||||
/**
|
||||
* The associated intercept.
|
||||
*/
|
||||
@@ -53,23 +59,8 @@ public class PersistRequestBean<T> 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<String> loadedProps;
|
||||
|
||||
/**
|
||||
* The unique id used for logging summary.
|
||||
*/
|
||||
@@ -80,48 +71,18 @@ public class PersistRequestBean<T> extends PersistRequest implements BeanPersist
|
||||
*/
|
||||
protected Integer beanHash;
|
||||
protected Integer beanIdentityHash;
|
||||
|
||||
protected final Set<String> changedProps;
|
||||
|
||||
protected boolean notifyCache;
|
||||
|
||||
private boolean statelessUpdate;
|
||||
private boolean deleteMissingChildren;
|
||||
private boolean updateNullProperties;
|
||||
|
||||
/**
|
||||
* Used for forced update of a bean.
|
||||
*/
|
||||
public PersistRequestBean(SpiEbeanServer server, T bean, Object parentBean, BeanManager<T> mgr, SpiTransaction t,
|
||||
PersistExecute persistExecute, Set<String> 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<T> 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 +91,24 @@ public class PersistRequestBean<T> 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<String> beanChangedProps = intercept.getChangedProps();
|
||||
Set<String> 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<String> mergeChangedProperties(Set<String> beanChangedProps, Set<String> 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) {
|
||||
@@ -176,26 +123,25 @@ public class PersistRequestBean<T> extends PersistRequest implements BeanPersist
|
||||
return beanPersistListener != null;
|
||||
}
|
||||
|
||||
public void notifyCache() {
|
||||
if (notifyCache) {
|
||||
switch (type) {
|
||||
case INSERT:
|
||||
beanDescriptor.cacheInsert(idValue, this);
|
||||
break;
|
||||
case UPDATE:
|
||||
beanDescriptor.cacheUpdate(idValue, this);
|
||||
break;
|
||||
case DELETE:
|
||||
beanDescriptor.cacheDelete(idValue, this);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid type "+type);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void notifyCache() {
|
||||
if (notifyCache) {
|
||||
switch (type) {
|
||||
case INSERT:
|
||||
beanDescriptor.cacheInsert(idValue, this);
|
||||
break;
|
||||
case UPDATE:
|
||||
beanDescriptor.cacheUpdate(idValue, this);
|
||||
break;
|
||||
case DELETE:
|
||||
beanDescriptor.cacheDelete(idValue, this);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid type " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addToPersistMap(BeanPersistIdMap beanPersistMap) {
|
||||
|
||||
beanPersistMap.add(beanDescriptor, type, idValue);
|
||||
}
|
||||
|
||||
@@ -209,7 +155,7 @@ public class PersistRequestBean<T> 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);
|
||||
@@ -226,7 +172,7 @@ public class PersistRequestBean<T> 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);
|
||||
@@ -244,7 +190,7 @@ public class PersistRequestBean<T> 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();
|
||||
@@ -281,11 +227,6 @@ public class PersistRequestBean<T> 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<T> getBeanManager() {
|
||||
@@ -351,20 +292,6 @@ public class PersistRequestBean<T> 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<String> additionalProps) {
|
||||
if (intercept != null) {
|
||||
intercept.setLoadedProps(additionalProps);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getLoadedProperties() {
|
||||
return loadedProps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a description of the request. This is typically the bean class
|
||||
* name or the base table for MapBeans.
|
||||
@@ -384,25 +311,22 @@ public class PersistRequestBean<T> 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.
|
||||
@@ -431,11 +355,7 @@ public class PersistRequestBean<T> 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
|
||||
@@ -482,13 +402,8 @@ public class PersistRequestBean<T> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,18 +501,18 @@ public class PersistRequestBean<T> extends PersistRequest implements BeanPersist
|
||||
* </p>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -608,7 +523,7 @@ public class PersistRequestBean<T> extends PersistRequest implements BeanPersist
|
||||
* </p>
|
||||
*/
|
||||
public boolean isDynamicUpdateSql() {
|
||||
return beanDescriptor.isUpdateChangesOnly() || (loadedProps != null);
|
||||
return beanDescriptor.isUpdateChangesOnly() || !intercept.isFullyLoadedBean();//(loadedProps != null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -619,37 +534,28 @@ public class PersistRequestBean<T> extends PersistRequest implements BeanPersist
|
||||
* </p>
|
||||
*/
|
||||
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<String> 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<DerivedRelationshipData> getDerivedRelationships() {
|
||||
return transaction.getDerivedRelationship(bean);
|
||||
public List<DerivedRelationshipData> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String> updateProps, Transaction t, boolean deleteMissingChildren, boolean updateNullProperties);
|
||||
public void forceUpdate(EntityBean entityBean, Set<String> 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.
|
||||
|
||||
@@ -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<T> {
|
||||
/**
|
||||
* 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<T> createReference(Object parentBean, String propertyName);
|
||||
public BeanCollection<T> 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.
|
||||
|
||||
@@ -92,7 +92,7 @@ public class BeanDescriptor<T> {
|
||||
private final ConcurrentHashMap<String, BeanFkeyProperty> fkeyMap = new ConcurrentHashMap<String, BeanFkeyProperty>();
|
||||
|
||||
public enum EntityType {
|
||||
ORM, EMBEDDED, SQL, META, XMLELEMENT
|
||||
ORM, EMBEDDED, SQL, META
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,14 +175,11 @@ public class BeanDescriptor<T> {
|
||||
* This is not sent to a remote client.
|
||||
*/
|
||||
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
|
||||
* only.
|
||||
@@ -219,7 +216,7 @@ public class BeanDescriptor<T> {
|
||||
/**
|
||||
* Derived list of properties that are used for version concurrency checking.
|
||||
*/
|
||||
private final BeanProperty[] propertiesVersion;
|
||||
private final BeanProperty versionProperty;
|
||||
private final BeanProperty propertiesNaturalKey;
|
||||
|
||||
/**
|
||||
@@ -280,12 +277,6 @@ public class BeanDescriptor<T> {
|
||||
*/
|
||||
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
|
||||
* simpler for this case.
|
||||
@@ -362,6 +353,8 @@ public class BeanDescriptor<T> {
|
||||
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 +363,6 @@ public class BeanDescriptor<T> {
|
||||
this.useIndex = deploy.getUseIndex();
|
||||
this.typeManager = typeManager;
|
||||
this.beanType = deploy.getBeanType();
|
||||
this.factoryType = deploy.getFactoryType();
|
||||
this.enhancedBean = beanType.equals(factoryType);
|
||||
this.namedQueries = deploy.getNamedQueries();
|
||||
this.namedUpdates = deploy.getNamedUpdates();
|
||||
|
||||
@@ -417,7 +408,7 @@ public class BeanDescriptor<T> {
|
||||
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();
|
||||
@@ -441,7 +432,6 @@ public class BeanDescriptor<T> {
|
||||
this.namesOfManyPropsHash = namesOfManyProps.hashCode();
|
||||
|
||||
this.derivedTableJoins = listHelper.getTableJoin();
|
||||
this.propertyFirstVersion = listHelper.getFirstVersion();
|
||||
|
||||
if (propertiesId.length == 1) {
|
||||
this.propertySingleId = propertiesId[0];
|
||||
@@ -492,19 +482,19 @@ public class BeanDescriptor<T> {
|
||||
* 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<String> getDirtyEmbeddedProperties(Object bean) {
|
||||
public Set<String> getDirtyEmbeddedProperties(EntityBean bean) {
|
||||
|
||||
HashSet<String> dirtyProperties = null;
|
||||
|
||||
@@ -533,7 +523,7 @@ public class BeanDescriptor<T> {
|
||||
/**
|
||||
* Determine the non-null properties of the bean.
|
||||
*/
|
||||
public Set<String> determineLoadedProperties(Object bean) {
|
||||
public Set<String> determineLoadedProperties(EntityBean bean) {
|
||||
|
||||
HashSet<String> nonNullProps = new HashSet<String>();
|
||||
|
||||
@@ -564,6 +554,14 @@ public class BeanDescriptor<T> {
|
||||
return entityType;
|
||||
}
|
||||
|
||||
public int getPropertyCount() {
|
||||
return propertyCount;
|
||||
}
|
||||
|
||||
public String[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default strategy for using a lucene index (if an index is
|
||||
* defined on this bean type).
|
||||
@@ -672,10 +670,6 @@ public class BeanDescriptor<T> {
|
||||
return inheritInfo != null;
|
||||
}
|
||||
|
||||
protected boolean isDynamicSubclass() {
|
||||
return !beanType.equals(factoryType);
|
||||
}
|
||||
|
||||
public SqlUpdate deleteById(Object id, List<Object> idList) {
|
||||
if (id != null) {
|
||||
return deleteById(id);
|
||||
@@ -919,10 +913,14 @@ public class BeanDescriptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public void cachePutBean(T bean) {
|
||||
cachePutBeanData((EntityBean)bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a bean into the bean cache.
|
||||
*/
|
||||
public void cachePutBeanData(Object bean) {
|
||||
public void cachePutBeanData(EntityBean bean) {
|
||||
|
||||
CachedBeanData beanData = CachedBeanDataFromBean.extract(this, bean);
|
||||
|
||||
@@ -953,10 +951,10 @@ public class BeanDescriptor<T> {
|
||||
bc.checkEmptyLazyLoad();
|
||||
for (int i = 0; i < idList.size(); i++) {
|
||||
Object id = idList.get(i);
|
||||
Object refBean = targetDescriptor.createReference(readOnly, id, null);
|
||||
Object refBean = targetDescriptor.createReference(readOnly, id);
|
||||
EntityBeanIntercept refEbi = ((EntityBean) refBean)._ebean_getIntercept();
|
||||
|
||||
many.add(bc, refBean);
|
||||
many.add(bc, (EntityBean)refBean);
|
||||
persistenceContext.put(id, refBean);
|
||||
refEbi.setPersistenceContext(persistenceContext);
|
||||
}
|
||||
@@ -968,7 +966,7 @@ public class BeanDescriptor<T> {
|
||||
Collection<?> actualDetails = bc.getActualDetails();
|
||||
ArrayList<Object> idList = new ArrayList<Object>();
|
||||
for (Object bean : actualDetails) {
|
||||
Object id = targetDescriptor.getId(bean);
|
||||
Object id = targetDescriptor.getId((EntityBean)bean);
|
||||
idList.add(id);
|
||||
}
|
||||
CachedManyIds ids = new CachedManyIds(idList);
|
||||
@@ -1012,14 +1010,14 @@ public class BeanDescriptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
T bean = (T) createBean();
|
||||
EntityBean bean = createBean();
|
||||
convertSetId(id, bean);
|
||||
if (Boolean.TRUE.equals(readOnly)) {
|
||||
((EntityBean) bean)._ebean_getIntercept().setReadOnly(true);
|
||||
bean._ebean_getIntercept().setReadOnly(true);
|
||||
}
|
||||
|
||||
CachedBeanDataToBean.load(this, bean, d);
|
||||
return bean;
|
||||
return (T)bean;
|
||||
}
|
||||
|
||||
public boolean cacheIsNaturalKey(String propName) {
|
||||
@@ -1049,13 +1047,16 @@ public class BeanDescriptor<T> {
|
||||
* Remove a bean from the cache given its Id.
|
||||
*/
|
||||
public void cacheDelete(Object id, PersistRequestBean<T> deleteRequest) {
|
||||
if (queryCache != null) {
|
||||
queryCache.clear();
|
||||
}
|
||||
if (beanCache != null) {
|
||||
beanCache.remove(id);
|
||||
}
|
||||
for (int i = 0; i < propertiesOneImported.length; i++) {
|
||||
BeanPropertyAssocMany<?> many = propertiesOneImported[i].getRelationshipProperty();
|
||||
if (many != null) {
|
||||
propertiesOneImported[i].cacheDelete(true, deleteRequest);
|
||||
propertiesOneImported[i].cacheDelete(true, deleteRequest.getEntityBean());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1065,7 +1066,7 @@ public class BeanDescriptor<T> {
|
||||
queryCache.clear();
|
||||
}
|
||||
for (int i = 0; i < propertiesOneImported.length; i++) {
|
||||
propertiesOneImported[i].cacheDelete(false, insertRequest.getBean());
|
||||
propertiesOneImported[i].cacheDelete(false, insertRequest.getEntityBean());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1074,17 +1075,22 @@ public class BeanDescriptor<T> {
|
||||
*/
|
||||
public void cacheUpdate(Object id, PersistRequestBean<T> updateRequest) {
|
||||
|
||||
if (queryCache != null) {
|
||||
queryCache.clear();
|
||||
}
|
||||
|
||||
ServerCache cache = getBeanCache();
|
||||
CachedBeanData cd = (CachedBeanData) cache.get(id);
|
||||
if (cd != null) {
|
||||
CachedBeanData newCd = CachedBeanDataUpdate.update(this, cd, updateRequest);
|
||||
cache.put(id, newCd);
|
||||
if (newCd.isNaturalKeyUpdate() && naturalKeyCache != null) {
|
||||
Object oldKey = propertiesNaturalKey.getValue(updateRequest.getOldValues());
|
||||
Object newKey = propertiesNaturalKey.getValue(updateRequest.getBean());
|
||||
if (oldKey != null) {
|
||||
naturalKeyCache.remove(oldKey);
|
||||
}
|
||||
//FIXME: natural key invalidate old value
|
||||
//Object oldKey = propertiesNaturalKey.getValue(updateRequest.getOldValues());
|
||||
Object newKey = propertiesNaturalKey.getValue(updateRequest.getEntityBean());
|
||||
//if (oldKey != null) {
|
||||
// naturalKeyCache.remove(oldKey);
|
||||
//}
|
||||
if (newKey != null) {
|
||||
naturalKeyCache.put(newKey, id);
|
||||
}
|
||||
@@ -1101,24 +1107,24 @@ public class BeanDescriptor<T> {
|
||||
}
|
||||
|
||||
public boolean loadFromCache(EntityBeanIntercept ebi) {
|
||||
Object bean = ebi.getOwner();
|
||||
EntityBean bean = ebi.getOwner();
|
||||
Object id = getId(bean);
|
||||
|
||||
return loadFromCache(bean, ebi, id);
|
||||
}
|
||||
|
||||
public boolean loadFromCache(Object bean, EntityBeanIntercept ebi, Object id) {
|
||||
public boolean loadFromCache(EntityBean bean, EntityBeanIntercept ebi, Object id) {
|
||||
|
||||
CachedBeanData cacheData = (CachedBeanData) getBeanCache().get(id);
|
||||
if (cacheData == null) {
|
||||
return false;
|
||||
}
|
||||
String lazyLoadProperty = ebi.getLazyLoadProperty();
|
||||
if (lazyLoadProperty != null && !cacheData.containsProperty(lazyLoadProperty)) {
|
||||
int lazyLoadProperty = ebi.getLazyLoadProperty();
|
||||
if (lazyLoadProperty > -1 && !cacheData.containsProperty(lazyLoadProperty)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CachedBeanDataToBean.load(this, bean, ebi, cacheData);
|
||||
CachedBeanDataToBean.load(this, bean, cacheData);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1308,7 +1314,7 @@ public class BeanDescriptor<T> {
|
||||
/**
|
||||
* Create an EntityBean.
|
||||
*/
|
||||
public Object createBean() {
|
||||
public EntityBean createBean() {
|
||||
return createEntityBean();
|
||||
}
|
||||
|
||||
@@ -1331,7 +1337,7 @@ public class BeanDescriptor<T> {
|
||||
* Create a reference bean based on the id.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T createReference(Boolean readOnly, Object id, Object parent) {
|
||||
public T createReference(Boolean readOnly, Object id) { //, Object parent
|
||||
|
||||
if (cacheSharableBeans && !Boolean.FALSE.equals(readOnly)) {
|
||||
CachedBeanData d = (CachedBeanData) getBeanCache().get(id);
|
||||
@@ -1343,25 +1349,17 @@ public class BeanDescriptor<T> {
|
||||
}
|
||||
}
|
||||
try {
|
||||
Object bean = createBean();
|
||||
EntityBean eb = createBean();
|
||||
|
||||
convertSetId(id, bean);
|
||||
|
||||
EntityBean eb = (EntityBean) bean;
|
||||
convertSetId(id, eb);
|
||||
|
||||
EntityBeanIntercept ebi = eb._ebean_getIntercept();
|
||||
ebi.setBeanLoaderByServerName(ebeanServer.getName());
|
||||
|
||||
if (parent != null) {
|
||||
// Special case for a OneToOne ... parent
|
||||
// needs to be added to context prior to query
|
||||
ebi.setParentBean(parent);
|
||||
}
|
||||
|
||||
// Note: not creating proxies for many's...
|
||||
ebi.setReference();
|
||||
|
||||
return (T) bean;
|
||||
return (T) eb;
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new PersistenceException(ex);
|
||||
@@ -1438,7 +1436,7 @@ public class BeanDescriptor<T> {
|
||||
/**
|
||||
* Get a property value from a bean of this type.
|
||||
*/
|
||||
public Object getValue(Object bean, String property) {
|
||||
public Object getValue(EntityBean bean, String property) {
|
||||
return getBeanProperty(property).getValue(bean);
|
||||
}
|
||||
|
||||
@@ -1468,12 +1466,12 @@ public class BeanDescriptor<T> {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class type this BeanDescriptor describes.
|
||||
*/
|
||||
public Class<?> getFactoryType() {
|
||||
return factoryType;
|
||||
}
|
||||
// /**
|
||||
// * Return the class type this BeanDescriptor describes.
|
||||
// */
|
||||
// public Class<?> getFactoryType() {
|
||||
// return factoryType;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return the bean class name this descriptor is used for.
|
||||
@@ -1506,16 +1504,10 @@ public class BeanDescriptor<T> {
|
||||
* unique id then a Map is built with the keys being the names of the
|
||||
* properties that make up the unique id.
|
||||
*/
|
||||
public Object getId(Object bean) {
|
||||
public Object getId(EntityBean bean) {
|
||||
|
||||
if (propertySingleId != null) {
|
||||
if (inheritInfo != null && !enhancedBean) {
|
||||
// avoid generated method via forced reflection use
|
||||
return propertySingleId.getValueViaReflection(bean);
|
||||
|
||||
} else {
|
||||
return propertySingleId.getValue(bean);
|
||||
}
|
||||
}
|
||||
|
||||
// it is a concatenated id Not embedded
|
||||
@@ -1559,7 +1551,7 @@ public class BeanDescriptor<T> {
|
||||
* after it has been converted to the correct type.
|
||||
* </p>
|
||||
*/
|
||||
public Object convertSetId(Object idValue, Object bean) {
|
||||
public Object convertSetId(Object idValue, EntityBean bean) {
|
||||
return idBinder.convertSetId(idValue, bean);
|
||||
}
|
||||
|
||||
@@ -1591,19 +1583,16 @@ public class BeanDescriptor<T> {
|
||||
*/
|
||||
public boolean lazyLoadMany(EntityBeanIntercept ebi) {
|
||||
|
||||
String lazyLoadProperty = ebi.getLazyLoadProperty();
|
||||
BeanProperty lazyLoadBeanProp = getBeanProperty(lazyLoadProperty);
|
||||
int lazyLoadProperty = ebi.getLazyLoadProperty();
|
||||
if (lazyLoadProperty == -1) {
|
||||
return false;
|
||||
}
|
||||
String lazyLoadPropertyName = ebi.getProperty(lazyLoadProperty);
|
||||
BeanProperty lazyLoadBeanProp = getBeanProperty(lazyLoadPropertyName);
|
||||
|
||||
if (lazyLoadBeanProp instanceof BeanPropertyAssocMany<?>) {
|
||||
BeanPropertyAssocMany<?> manyProp = (BeanPropertyAssocMany<?>) lazyLoadBeanProp;
|
||||
manyProp.createReference(ebi.getOwner());
|
||||
Set<String> loadedProps = ebi.getLoadedProps();
|
||||
HashSet<String> newLoadedProps = new HashSet<String>();
|
||||
if (loadedProps != null) {
|
||||
newLoadedProps.addAll(loadedProps);
|
||||
}
|
||||
newLoadedProps.add(lazyLoadProperty);
|
||||
ebi.setLoadedProps(newLoadedProps);
|
||||
ebi.setLoadedLazy();
|
||||
return true;
|
||||
}
|
||||
@@ -1749,7 +1738,7 @@ public class BeanDescriptor<T> {
|
||||
return prop;
|
||||
}
|
||||
|
||||
protected Object getBeanPropertyWithInheritance(Object bean, String propName) {
|
||||
protected Object getBeanPropertyWithInheritance(EntityBean bean, String propName) {
|
||||
|
||||
BeanDescriptor<?> desc = getBeanDescriptor(bean.getClass());
|
||||
BeanProperty beanProperty = desc.findBeanProperty(propName);
|
||||
@@ -2186,33 +2175,24 @@ public class BeanDescriptor<T> {
|
||||
* Note that this DOES NOT find a version property on an embedded bean.
|
||||
* </p>
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@@ -2237,7 +2217,7 @@ public class BeanDescriptor<T> {
|
||||
return propertiesLocal;
|
||||
}
|
||||
|
||||
public void jsonWrite(WriteJsonContext ctx, Object bean) {
|
||||
public void jsonWrite(WriteJsonContext ctx, EntityBean bean) {
|
||||
|
||||
if (bean != null) {
|
||||
|
||||
@@ -2263,7 +2243,7 @@ public class BeanDescriptor<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void jsonWriteProperties(WriteJsonContext ctx, Object bean) {
|
||||
private void jsonWriteProperties(WriteJsonContext ctx, EntityBean bean) {
|
||||
|
||||
boolean referenceBean = ctx.isReferenceBean();
|
||||
|
||||
@@ -2292,7 +2272,7 @@ public class BeanDescriptor<T> {
|
||||
|
||||
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)
|
||||
@@ -2371,10 +2351,9 @@ public class BeanDescriptor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ReadBeanState jsonReadObject(ReadJsonContext ctx, String path) {
|
||||
|
||||
T bean = (T) createEntityBean();
|
||||
EntityBean bean = createEntityBean();
|
||||
ctx.pushBean(bean, path, this);
|
||||
|
||||
do {
|
||||
@@ -2409,7 +2388,7 @@ public class BeanDescriptor<T> {
|
||||
if (isLoadedReference(loadedProps)) {
|
||||
ebi.setReference();
|
||||
} else {
|
||||
ebi.setLoadedProps(loadedProps);
|
||||
ebi.setLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -1286,43 +1287,33 @@ 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<DeployBeanProperty> it = desc.propertiesAll();
|
||||
while (it.hasNext()) {
|
||||
DeployBeanProperty prop = it.next();
|
||||
String propName = prop.getName();
|
||||
Iterator<DeployBeanProperty> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1333,13 +1324,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1378,103 +1371,34 @@ 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);
|
||||
checkInheritedClasses(beanClass);
|
||||
|
||||
desc.setFactoryType(beanClass);
|
||||
if (!beanClass.getName().startsWith("com.avaje.ebean.meta")) {
|
||||
enhancedClassCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSubclass(DeployBeanDescriptor<?> desc, Class<?> beanClass) {
|
||||
|
||||
checkInheritedClasses(false, beanClass);
|
||||
desc.checkReadAndWriteMethods();
|
||||
|
||||
EntityType entityType = desc.getEntityType();
|
||||
if (EntityType.XMLELEMENT.equals(entityType)) {
|
||||
desc.setFactoryType(beanClass);
|
||||
|
||||
} else {
|
||||
throw new PersistenceException("Entity type "+beanClass+" is not an enhanced entity bean. Subclassing is not longer supported in Ebean");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -90,7 +91,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;
|
||||
}
|
||||
|
||||
@@ -154,7 +155,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");
|
||||
}
|
||||
|
||||
@@ -162,15 +163,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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -36,7 +37,7 @@ public final class BeanListHelp<T> implements BeanCollectionHelp<T> {
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
public void add(BeanCollection<?> collection, Object bean) {
|
||||
public void add(BeanCollection<?> collection, EntityBean bean) {
|
||||
collection.internalAdd(bean);
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ public final class BeanListHelp<T> implements BeanCollectionHelp<T> {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public void addBean(Object bean) {
|
||||
public void addBean(EntityBean bean) {
|
||||
list.add(bean);
|
||||
}
|
||||
}
|
||||
@@ -80,18 +81,18 @@ public final class BeanListHelp<T> implements BeanCollectionHelp<T> {
|
||||
return vanilla ? new ArrayList<T>() : new BeanList<T>();
|
||||
}
|
||||
|
||||
public BeanCollection<T> createReference(Object parentBean, String propertyName) {
|
||||
public BeanCollection<T> createReference(EntityBean parentBean, String propertyName) {
|
||||
|
||||
return new BeanList<T>(loader, parentBean, propertyName);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -140,7 +141,7 @@ public final class BeanListHelp<T> implements BeanCollectionHelp<T> {
|
||||
ctx.appendComma();
|
||||
}
|
||||
Object detailBean = list.get(j);
|
||||
targetDescriptor.jsonWrite(ctx, detailBean);
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean)detailBean);
|
||||
}
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
|
||||
@@ -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<T> implements BeanCollectionHelp<T> {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
public void addBean(Object bean) {
|
||||
public void addBean(EntityBean bean) {
|
||||
Object keyValue = beanProperty.getValue(bean);
|
||||
map.put(keyValue, bean);
|
||||
}
|
||||
@@ -105,7 +106,7 @@ public final class BeanMapHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void add(BeanCollection<?> collection, Object bean) {
|
||||
public void add(BeanCollection<?> collection, EntityBean bean) {
|
||||
|
||||
Object keyValue = beanProperty.getValueIntercept(bean);
|
||||
|
||||
@@ -114,17 +115,17 @@ public final class BeanMapHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public BeanCollection<T> createReference(Object parentBean, String propertyName) {
|
||||
public BeanCollection<T> createReference(EntityBean parentBean, String propertyName) {
|
||||
|
||||
return new BeanMap(loader, parentBean, propertyName);
|
||||
}
|
||||
|
||||
public void refresh(EbeanServer server, Query<?> query, Transaction t, Object parentBean) {
|
||||
public void refresh(EbeanServer server, Query<?> query, Transaction t, EntityBean parentBean) {
|
||||
BeanMap<?, ?> newBeanMap = (BeanMap<?, ?>) server.findMap(query, t);
|
||||
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);
|
||||
@@ -175,7 +176,7 @@ public final class BeanMapHelp<T> implements BeanCollectionHelp<T> {
|
||||
}
|
||||
//FIXME: json write map key ...
|
||||
Object detailBean = entry.getValue();
|
||||
targetDescriptor.jsonWrite(ctx, detailBean);
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean)detailBean);
|
||||
}
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -845,7 +812,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;
|
||||
}
|
||||
@@ -1184,7 +1151,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;
|
||||
}
|
||||
@@ -1196,7 +1163,7 @@ public class BeanProperty implements ElPropertyValue {
|
||||
}
|
||||
}
|
||||
|
||||
public void jsonRead(ReadJsonContext ctx, Object bean) {
|
||||
public void jsonRead(ReadJsonContext ctx, EntityBean bean) {
|
||||
if(!jsonDeserialize){
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ public abstract class BeanPropertyAssoc<T> 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();
|
||||
|
||||
|
||||
@@ -16,6 +16,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;
|
||||
@@ -145,22 +146,22 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -291,7 +292,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@@ -309,21 +310,21 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -331,7 +332,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
* Return the Id values from the given bean.
|
||||
*/
|
||||
@Override
|
||||
public Object[] getAssocOneIdValues(Object bean) {
|
||||
public Object[] getAssocOneIdValues(EntityBean bean) {
|
||||
return targetDescriptor.getIdBinder().getIdValues(bean);
|
||||
}
|
||||
|
||||
@@ -402,7 +403,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
* 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);
|
||||
@@ -435,7 +436,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
return mapKey;
|
||||
}
|
||||
|
||||
public BeanCollection<?> createReferenceIfNull(Object parentBean) {
|
||||
public BeanCollection<?> createReferenceIfNull(EntityBean parentBean) {
|
||||
|
||||
Object v = getValue(parentBean);
|
||||
if (v instanceof BeanCollection<?>){
|
||||
@@ -446,7 +447,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public BeanCollection<?> createReference(Object parentBean) {
|
||||
public BeanCollection<?> createReference(EntityBean parentBean) {
|
||||
|
||||
BeanCollection<?> ref = help.createReference(parentBean, name);
|
||||
setValue(parentBean, ref);
|
||||
@@ -461,7 +462,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
return help.getBeanCollectionAdd(bc, mapKey);
|
||||
}
|
||||
|
||||
public Object getParentId(Object parentBean) {
|
||||
public Object getParentId(EntityBean parentBean) {
|
||||
return descriptor.getId(parentBean);
|
||||
}
|
||||
|
||||
@@ -471,8 +472,9 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -484,8 +486,9 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
@@ -516,7 +519,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
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
|
||||
@@ -528,7 +531,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
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++) {
|
||||
@@ -683,7 +686,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
|
||||
public IntersectionRow buildManyDeleteChildren(Object parentBean, ArrayList<Object> excludeDetailIds) {
|
||||
public IntersectionRow buildManyDeleteChildren(EntityBean parentBean, ArrayList<Object> excludeDetailIds) {
|
||||
|
||||
IntersectionRow row = new IntersectionRow(tableJoin.getTable());
|
||||
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
|
||||
@@ -693,14 +696,14 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
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());
|
||||
|
||||
@@ -709,11 +712,11 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
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);
|
||||
@@ -727,7 +730,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
* 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);
|
||||
}
|
||||
@@ -735,12 +738,12 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
@@ -757,7 +760,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public void jsonRead(ReadJsonContext ctx, Object bean){
|
||||
public void jsonRead(ReadJsonContext ctx, EntityBean bean){
|
||||
if(!this.jsonDeserialize){
|
||||
return;
|
||||
}
|
||||
@@ -774,7 +777,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
|
||||
// probably empty array
|
||||
break;
|
||||
}
|
||||
Object detailBean = detailBeanState.getBean();
|
||||
EntityBean detailBean = (EntityBean)detailBeanState.getBean();
|
||||
add.addBean(detailBean);
|
||||
|
||||
if (bean != null && childMasterProperty != null){
|
||||
|
||||
@@ -34,8 +34,6 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
|
||||
private final boolean oneToOneExported;
|
||||
|
||||
private final boolean embeddedVersion;
|
||||
|
||||
private final boolean importedPrimaryKey;
|
||||
|
||||
private final LocalHelp localHelp;
|
||||
@@ -78,11 +76,6 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
// 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<String, BeanProperty>();
|
||||
for (int i = 0; i < embeddedProps.length; i++) {
|
||||
embeddedPropsMap.put(embeddedProps[i].getName(), embeddedProps[i]);
|
||||
@@ -91,7 +84,6 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
} else {
|
||||
embeddedProps = null;
|
||||
embeddedPropsMap = null;
|
||||
embeddedVersion = false;
|
||||
}
|
||||
localHelp = createHelp(embedded, oneToOneExported);
|
||||
}
|
||||
@@ -130,11 +122,11 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
|
||||
} 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<T> extends BeanPropertyAssoc<T> {
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
* 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<T> extends BeanPropertyAssoc<T> {
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
@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<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
@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<T> extends BeanPropertyAssoc<T> {
|
||||
// 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<T> extends BeanPropertyAssoc<T> {
|
||||
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
@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<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
* 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<T> extends BeanPropertyAssoc<T> {
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
@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<T> extends BeanPropertyAssoc<T> {
|
||||
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<T> extends BeanPropertyAssoc<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jsonRead(ReadJsonContext ctx, Object bean){
|
||||
public void jsonRead(ReadJsonContext ctx, EntityBean bean){
|
||||
|
||||
T assocBean = targetDescriptor.jsonReadBean(ctx, name);
|
||||
setValue(bean, assocBean);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+14
-12
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,12 +73,12 @@ public final class BeanSetHelp<T> implements BeanCollectionHelp<T> {
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public void addBean(Object bean) {
|
||||
public void addBean(EntityBean bean) {
|
||||
set.add(bean);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(BeanCollection<?> collection, Object bean) {
|
||||
public void add(BeanCollection<?> collection, EntityBean bean) {
|
||||
collection.internalAdd(bean);
|
||||
}
|
||||
|
||||
@@ -85,18 +86,18 @@ public final class BeanSetHelp<T> implements BeanCollectionHelp<T> {
|
||||
return vanilla ? new LinkedHashSet<T>() : new BeanSet<T>();
|
||||
}
|
||||
|
||||
public BeanCollection<T> createReference(Object parentBean, String propertyName) {
|
||||
public BeanCollection<T> createReference(EntityBean parentBean, String propertyName) {
|
||||
|
||||
return new BeanSet<T>(loader, parentBean, propertyName);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -146,7 +147,7 @@ public final class BeanSetHelp<T> implements BeanCollectionHelp<T> {
|
||||
if (count++ > 0){
|
||||
ctx.appendComma();
|
||||
}
|
||||
targetDescriptor.jsonWrite(ctx, detailBean);
|
||||
targetDescriptor.jsonWrite(ctx, (EntityBean)detailBean);
|
||||
}
|
||||
ctx.endAssocMany();
|
||||
}
|
||||
|
||||
@@ -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<T> implements BeanPersistListener<T> {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean updated(T bean, Set<String> updatedProperties) {
|
||||
public boolean updated(T bean) {
|
||||
boolean notifyCluster = false;
|
||||
for (int i = 0; i < chain.length; i++) {
|
||||
if (chain[i].updated(bean, updatedProperties)) {
|
||||
if (chain[i].updated(bean)) {
|
||||
notifyCluster = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public class DRawSqlSelect {
|
||||
sqlTree.setSummary(desc.getName());
|
||||
|
||||
LinkedHashSet<String> includedProps = new LinkedHashSet<String>();
|
||||
SqlTreeProperties selectProps = new SqlTreeProperties();
|
||||
SqlTreeProperties selectProps = new SqlTreeProperties(desc);
|
||||
|
||||
for (int i = 0; i < selectColumns.length; i++) {
|
||||
|
||||
@@ -156,7 +156,6 @@ public class DRawSqlSelect {
|
||||
}
|
||||
}
|
||||
|
||||
selectProps.setIncludedProperties(includedProps);
|
||||
SqlTreeNode sqlRoot = new SqlTreeNodeRoot(desc, selectProps, null, withId);
|
||||
sqlTree.setRootNode(sqlRoot);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.deploy;
|
||||
import java.util.Map;
|
||||
|
||||
import com.avaje.ebean.bean.BeanCollection;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.EntityBeanIntercept;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
@@ -72,12 +73,12 @@ public interface DbReadContext {
|
||||
/**
|
||||
* Set back the bean that has just been loaded with its id.
|
||||
*/
|
||||
public void setLoadedBean(Object loadedBean, Object id);
|
||||
public void setLoadedBean(EntityBean loadedBean, Object id);
|
||||
|
||||
/**
|
||||
* Set back the 'detail' bean that has just been loaded.
|
||||
*/
|
||||
public void setLoadedManyBean(Object loadedBean);
|
||||
public void setLoadedManyBean(EntityBean loadedBean);
|
||||
|
||||
/**
|
||||
* Return the query mode.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
|
||||
/**
|
||||
@@ -32,7 +33,7 @@ public class ExportedProperty {
|
||||
/**
|
||||
* Return the property value from the bean.
|
||||
*/
|
||||
public Object getValue(Object bean){
|
||||
public Object getValue(EntityBean bean){
|
||||
return property.getValue(bean);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.HashMap;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
import com.avaje.ebeaninternal.server.deploy.id.IdBinder;
|
||||
import com.avaje.ebeaninternal.server.deploy.parse.DeployInheritInfo;
|
||||
@@ -223,7 +224,7 @@ public class InheritInfo {
|
||||
/**
|
||||
* Create an EntityBean for this type.
|
||||
*/
|
||||
public Object createBean() {
|
||||
public EntityBean createBean() {
|
||||
return descriptor.createBean();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectGetter;
|
||||
|
||||
/**
|
||||
* For abstract classes that hold the id property we need to
|
||||
* use reflection to get the id values some times.
|
||||
* <p>
|
||||
* This provides the BeanReflectGetter objects to do that.
|
||||
* </p>
|
||||
* @author rbygrave
|
||||
*/
|
||||
public class ReflectGetter {
|
||||
|
||||
/**
|
||||
* Create a reflection based BeanReflectGetter for getting the
|
||||
* id from abstract inheritance hierarchy object.
|
||||
*/
|
||||
public static BeanReflectGetter create(DeployBeanProperty prop) {
|
||||
|
||||
if (!prop.isId()){
|
||||
// not expecting this to ever be used/called
|
||||
return new NonIdGetter(prop.getFullBeanName());
|
||||
|
||||
} else {
|
||||
String property = prop.getFullBeanName();
|
||||
Method readMethod = prop.getReadMethod();
|
||||
if (readMethod == null){
|
||||
String m = "Abstract class with no readMethod for "+property;
|
||||
throw new RuntimeException(m);
|
||||
}
|
||||
return new IdGetter(property, readMethod);
|
||||
}
|
||||
}
|
||||
|
||||
public static class IdGetter implements BeanReflectGetter {
|
||||
|
||||
public static final Object[] NO_ARGS = new Object[0];
|
||||
|
||||
private final Method readMethod;
|
||||
private final String property;
|
||||
|
||||
public IdGetter(String property, Method readMethod) {
|
||||
this.property = property;
|
||||
this.readMethod = readMethod;
|
||||
}
|
||||
|
||||
public Object get(Object bean) {
|
||||
try {
|
||||
return readMethod.invoke(bean, NO_ARGS);
|
||||
} catch (Exception e) {
|
||||
String m = "Error on ["+property+"] using readMethod "+readMethod;
|
||||
throw new RuntimeException(m, e);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getIntercept(Object bean) {
|
||||
return get(bean);
|
||||
}
|
||||
}
|
||||
|
||||
public static class NonIdGetter implements BeanReflectGetter {
|
||||
|
||||
private final String property;
|
||||
|
||||
public NonIdGetter(String property) {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
public Object get(Object bean) {
|
||||
|
||||
String m = "Not expecting this method to be called on ["+property
|
||||
+"] as it is a NON ID property on an abstract class";
|
||||
throw new RuntimeException(m);
|
||||
}
|
||||
|
||||
public Object getIntercept(Object bean) {
|
||||
return get(bean);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflectSetter;
|
||||
|
||||
/**
|
||||
* A place holder for BeanReflectSetter that should never be called.
|
||||
* <p>
|
||||
* This is for properties of classes that are abstract and at the root
|
||||
* of an inheritance hierarchy.
|
||||
* </p>
|
||||
* @author rbygrave
|
||||
*/
|
||||
public class ReflectSetter {
|
||||
|
||||
/**
|
||||
* Creates place holder objects that should never be called.
|
||||
*/
|
||||
public static BeanReflectSetter create(DeployBeanProperty prop) {
|
||||
|
||||
String fullName = prop.getFullBeanName();
|
||||
Method writeMethod = prop.getWriteMethod();
|
||||
return new RefCalled(fullName, writeMethod);
|
||||
}
|
||||
|
||||
static class RefCalled implements BeanReflectSetter {
|
||||
|
||||
final String fullName;
|
||||
final Method writeMethod;
|
||||
|
||||
RefCalled(String fullName, Method writeMethod) {
|
||||
this.fullName = fullName;
|
||||
this.writeMethod = writeMethod;
|
||||
}
|
||||
public void set(Object bean, Object value) {
|
||||
Object[] a = new Object[1];
|
||||
a[0] = value;
|
||||
try {
|
||||
writeMethod.invoke(bean, a);
|
||||
} catch (Exception e) {
|
||||
String beanType = bean == null ? "null" : bean.getClass().toString();
|
||||
String msg = "Error setting value on "+fullName+" value["+value+"] on type["+beanType+"]";
|
||||
throw new RuntimeException(msg, e);
|
||||
}
|
||||
}
|
||||
public void setIntercept(Object bean, Object value) {
|
||||
String msg = "Not expecting setIntercept to be called. Refer Bug 368";
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.deploy;
|
||||
import java.sql.SQLException;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.meta.DeployTableJoin;
|
||||
@@ -122,7 +123,7 @@ public final class TableJoin {
|
||||
}
|
||||
}
|
||||
|
||||
public Object readSet(DbReadContext ctx, Object bean, Class<?> type) throws SQLException {
|
||||
public Object readSet(DbReadContext ctx, EntityBean bean, Class<?> type) throws SQLException {
|
||||
for (int i = 0, x = properties.length; i < x; i++) {
|
||||
properties[i].readSet(ctx, bean, type);
|
||||
}
|
||||
|
||||
+8
-2
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.core.BasicTypeConverter;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
@@ -17,7 +18,7 @@ public class GeneratedCounter implements GeneratedProperty {
|
||||
/**
|
||||
* Always returns a 1.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
Integer i = Integer.valueOf(1);
|
||||
return BasicTypeConverter.convert(i, numberType);
|
||||
}
|
||||
@@ -25,7 +26,7 @@ public class GeneratedCounter implements GeneratedProperty {
|
||||
/**
|
||||
* Increments the current value by one.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
Number currVal = (Number) prop.getValue(bean);
|
||||
Integer nextVal = Integer.valueOf(currVal.intValue() + 1);
|
||||
return BasicTypeConverter.convert(nextVal, numberType);
|
||||
@@ -38,6 +39,11 @@ public class GeneratedCounter implements GeneratedProperty {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include this in every insert setting initial counter value to 1.
|
||||
*/
|
||||
|
||||
+8
-2
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -14,14 +15,14 @@ public class GeneratedCounterInteger implements GeneratedProperty {
|
||||
/**
|
||||
* Always returns a 1.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
return Integer.valueOf(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the current value by one.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
Integer i = (Integer) prop.getValue(bean);
|
||||
return Integer.valueOf(i.intValue() + 1);
|
||||
}
|
||||
@@ -32,6 +33,11 @@ public class GeneratedCounterInteger implements GeneratedProperty {
|
||||
public boolean includeInUpdate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include this in every insert setting initial counter value to 1.
|
||||
|
||||
+8
-2
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -14,14 +15,14 @@ public class GeneratedCounterLong implements GeneratedProperty {
|
||||
/**
|
||||
* Always returns a 1.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
return Long.valueOf(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the current value by one.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
Long i = (Long) prop.getValue(bean);
|
||||
return Long.valueOf(i.longValue() + 1);
|
||||
}
|
||||
@@ -33,6 +34,11 @@ public class GeneratedCounterLong implements GeneratedProperty {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include this in every insert setting initial counter value to 1.
|
||||
*/
|
||||
|
||||
+8
-2
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -12,14 +13,14 @@ public class GeneratedInsertDate implements GeneratedProperty {
|
||||
/**
|
||||
* Return the current time as a Timestamp.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
return new Date(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Just returns the beans original insert timestamp value.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
return prop.getValue(bean);
|
||||
}
|
||||
|
||||
@@ -30,6 +31,11 @@ public class GeneratedInsertDate implements GeneratedProperty {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true.
|
||||
*/
|
||||
|
||||
+8
-2
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -10,14 +11,14 @@ public class GeneratedInsertLong implements GeneratedProperty {
|
||||
/**
|
||||
* Return the current time as a Timestamp.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
return Long.valueOf(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Just returns the beans original insert timestamp value.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
return prop.getValue(bean);
|
||||
}
|
||||
|
||||
@@ -28,6 +29,11 @@ public class GeneratedInsertLong implements GeneratedProperty {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true.
|
||||
*/
|
||||
|
||||
+8
-2
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -12,14 +13,14 @@ public class GeneratedInsertTimestamp implements GeneratedProperty {
|
||||
/**
|
||||
* Return the current time as a Timestamp.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
return new Timestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Just returns the beans original insert timestamp value.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
return prop.getValue(bean);
|
||||
}
|
||||
|
||||
@@ -29,6 +30,11 @@ public class GeneratedInsertTimestamp implements GeneratedProperty {
|
||||
public boolean includeInUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true.
|
||||
|
||||
+9
-2
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -11,12 +12,12 @@ public interface GeneratedProperty {
|
||||
/**
|
||||
* Get the generated insert value for a specific property of a bean.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean);
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean);
|
||||
|
||||
/**
|
||||
* Get the generated update value for a specific property of a bean.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean);
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean);
|
||||
|
||||
/**
|
||||
* Return true if this should always be includes in an update statement.
|
||||
@@ -25,6 +26,12 @@ public interface GeneratedProperty {
|
||||
* </p>
|
||||
*/
|
||||
public boolean includeInUpdate();
|
||||
|
||||
/**
|
||||
* Return true if the property should be included in an update even if
|
||||
* it is not loaded (ie. Last Updated Timestamp).
|
||||
*/
|
||||
public boolean includeInAllUpdates();
|
||||
|
||||
/**
|
||||
* Return true if this should be included in insert statements.
|
||||
|
||||
+8
-2
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -13,14 +14,14 @@ public class GeneratedUpdateDate implements GeneratedProperty {
|
||||
/**
|
||||
* Return now as a Timestamp.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
return new Date(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return now as a Timestamp.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
return new Date(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@@ -30,6 +31,11 @@ public class GeneratedUpdateDate implements GeneratedProperty {
|
||||
public boolean includeInUpdate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include this in every insert.
|
||||
|
||||
+8
-2
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -10,14 +11,14 @@ public class GeneratedUpdateLong implements GeneratedProperty {
|
||||
/**
|
||||
* Return now as a Timestamp.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
return Long.valueOf(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return now as a Timestamp.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
return Long.valueOf(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@@ -28,6 +29,11 @@ public class GeneratedUpdateLong implements GeneratedProperty {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include this in every insert.
|
||||
*/
|
||||
|
||||
+8
-2
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -12,14 +13,14 @@ public class GeneratedUpdateTimestamp implements GeneratedProperty {
|
||||
/**
|
||||
* Return now as a Timestamp.
|
||||
*/
|
||||
public Object getInsertValue(BeanProperty prop, Object bean) {
|
||||
public Object getInsertValue(BeanProperty prop, EntityBean bean) {
|
||||
return new Timestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return now as a Timestamp.
|
||||
*/
|
||||
public Object getUpdateValue(BeanProperty prop, Object bean) {
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean) {
|
||||
return new Timestamp(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@@ -30,6 +31,11 @@ public class GeneratedUpdateTimestamp implements GeneratedProperty {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeInAllUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include this in every insert.
|
||||
*/
|
||||
|
||||
@@ -6,9 +6,7 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
@@ -47,16 +45,6 @@ public interface IdBinder {
|
||||
public Object readData(DataInput dataInput) throws IOException;
|
||||
|
||||
/**
|
||||
* Adds RDN's to the LdapName using the id value.
|
||||
*/
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException;
|
||||
|
||||
/**
|
||||
* Adds RDN's to the LdapName using the id value from the bean.
|
||||
*/
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException;
|
||||
|
||||
/**
|
||||
* Return the name(s) of the Id property(s).
|
||||
* Comma delimited if there is more than one.
|
||||
* <p>
|
||||
@@ -102,7 +90,7 @@ public interface IdBinder {
|
||||
/**
|
||||
* Return the id values for a given bean.
|
||||
*/
|
||||
public Object[] getIdValues(Object bean);
|
||||
public Object[] getIdValues(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Build a string of the logical expressions.
|
||||
@@ -149,7 +137,7 @@ public interface IdBinder {
|
||||
/**
|
||||
* Read the id value from the result set and set it to the bean also returning it.
|
||||
*/
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException;
|
||||
public Object readSet(DbReadContext ctx, EntityBean bean) throws SQLException;
|
||||
|
||||
/**
|
||||
* Ignore the appropriate number of scalar properties for this id.
|
||||
@@ -187,6 +175,6 @@ public interface IdBinder {
|
||||
* If the bean is not null, then the value is set to the bean.
|
||||
* </p>
|
||||
*/
|
||||
public Object convertSetId(Object idValue, Object bean);
|
||||
public Object convertSetId(Object idValue, EntityBean bean);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,11 +6,9 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -99,23 +97,6 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException {
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object v = props[i].getValue(id);
|
||||
Rdn rdn = new Rdn(props[i].getDbColumn(), v);
|
||||
name.add(rdn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException {
|
||||
Object id = embIdProperty.getValue(bean);
|
||||
createLdapNameById(name, id);
|
||||
}
|
||||
|
||||
public BeanDescriptor<?> getIdBeanDescriptor() {
|
||||
return idDesc;
|
||||
}
|
||||
@@ -172,7 +153,7 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
public void addIdInBindValue(SpiExpressionRequest request, Object value) {
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
request.addBindValue(props[i].getValue(value));
|
||||
request.addBindValue(props[i].getValue((EntityBean)value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +219,7 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
String msg = "Failed to split ["+idTermValue+"] using | for id.";
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
Object embId = idDesc.createBean();
|
||||
EntityBean embId = idDesc.createBean();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object v = props[i].getScalarType().parse(split[i]);
|
||||
props[i].setValue(embId, v);
|
||||
@@ -254,7 +235,7 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object v = props[i].getValue(idValue);
|
||||
Object v = props[i].getValue((EntityBean)idValue);
|
||||
String formatValue = props[i].getScalarType().format(v);
|
||||
if (i > 0){
|
||||
sb.append("|");
|
||||
@@ -264,11 +245,11 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Object[] getIdValues(Object bean) {
|
||||
bean = embIdProperty.getValue(bean);
|
||||
public Object[] getIdValues(EntityBean bean) {
|
||||
Object val = embIdProperty.getValue(bean);
|
||||
Object[] bindvalues = new Object[props.length];
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
bindvalues[i] = props[i].getValue(bean);
|
||||
bindvalues[i] = props[i].getValue((EntityBean)val);
|
||||
}
|
||||
return bindvalues;
|
||||
}
|
||||
@@ -277,14 +258,14 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
Object[] bindvalues = new Object[props.length];
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
bindvalues[i] = props[i].getValue(value);
|
||||
bindvalues[i] = props[i].getValue((EntityBean)value);
|
||||
}
|
||||
return bindvalues;
|
||||
}
|
||||
|
||||
public void bindId(DefaultSqlUpdate sqlUpdate, Object value) {
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object embFieldValue = props[i].getValue(value);
|
||||
Object embFieldValue = props[i].getValue((EntityBean)value);
|
||||
sqlUpdate.addParameter(embFieldValue);
|
||||
}
|
||||
}
|
||||
@@ -292,14 +273,14 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
public void bindId(DataBind dataBind, Object value) throws SQLException {
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object embFieldValue = props[i].getValue(value);
|
||||
Object embFieldValue = props[i].getValue((EntityBean)value);
|
||||
props[i].bind(dataBind, embFieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
|
||||
Object embId = idDesc.createBean();
|
||||
EntityBean embId = idDesc.createBean();
|
||||
boolean notNull = true;
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
@@ -319,7 +300,7 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object idValue) throws IOException {
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object embFieldValue = props[i].getValue(idValue);
|
||||
Object embFieldValue = props[i].getValue((EntityBean)idValue);
|
||||
props[i].writeData(dataOutput, embFieldValue);
|
||||
}
|
||||
}
|
||||
@@ -332,7 +313,7 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
public Object read(DbReadContext ctx) throws SQLException {
|
||||
|
||||
Object embId = idDesc.createBean();
|
||||
EntityBean embId = idDesc.createBean();
|
||||
boolean notNull = true;
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
@@ -349,7 +330,7 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
}
|
||||
}
|
||||
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException {
|
||||
public Object readSet(DbReadContext ctx, EntityBean bean) throws SQLException {
|
||||
|
||||
Object embId = read(ctx);
|
||||
if (embId != null) {
|
||||
@@ -443,7 +424,7 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Object convertSetId(Object idValue, Object bean) {
|
||||
public Object convertSetId(Object idValue, EntityBean bean) {
|
||||
|
||||
// can not cast/convert if it is embedded
|
||||
if (bean != null) {
|
||||
|
||||
@@ -6,9 +6,7 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
@@ -47,11 +45,6 @@ public final class IdBinderEmpty implements IdBinder {
|
||||
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
|
||||
}
|
||||
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException {
|
||||
}
|
||||
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException {
|
||||
}
|
||||
|
||||
public int getPropertyCount() {
|
||||
return 0;
|
||||
@@ -107,7 +100,7 @@ public final class IdBinderEmpty implements IdBinder {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getIdValues(Object bean){
|
||||
public Object[] getIdValues(EntityBean bean){
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -126,7 +119,7 @@ public final class IdBinderEmpty implements IdBinder {
|
||||
public void loadIgnore(DbReadContext ctx) {
|
||||
}
|
||||
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException {
|
||||
public Object readSet(DbReadContext ctx, EntityBean bean) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -137,7 +130,7 @@ public final class IdBinderEmpty implements IdBinder {
|
||||
public void appendSelect(DbSqlContext ctx, boolean subQuery) {
|
||||
}
|
||||
|
||||
public Object convertSetId(Object idValue, Object bean){
|
||||
public Object convertSetId(Object idValue, EntityBean bean){
|
||||
return idValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,11 +8,9 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
@@ -83,24 +81,6 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException {
|
||||
|
||||
if (id instanceof Map<?,?> == false){
|
||||
throw new RuntimeException("Expecting a Map for concatinated key");
|
||||
}
|
||||
|
||||
Map<?,?> mapId = (Map<?,?>)id;
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
|
||||
Object v = mapId.get(props[i].getName());
|
||||
if (v == null){
|
||||
throw new RuntimeException("No value in Map for key "+props[i].getName());
|
||||
}
|
||||
|
||||
Rdn rdn = new Rdn(props[i].getDbColumn(), v);
|
||||
name.add(rdn);
|
||||
}
|
||||
}
|
||||
|
||||
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
|
||||
|
||||
@@ -109,16 +89,6 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
}
|
||||
}
|
||||
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException {
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
|
||||
Object v = props[i].getValue(bean);
|
||||
Rdn rdn = new Rdn(props[i].getDbColumn(), v);
|
||||
name.add(rdn);
|
||||
}
|
||||
}
|
||||
|
||||
public int getPropertyCount() {
|
||||
return props.length;
|
||||
}
|
||||
@@ -163,7 +133,7 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
|
||||
public void addIdInBindValue(SpiExpressionRequest request, Object value) {
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
request.addBindValue(props[i].getValue(value));
|
||||
request.addBindValue(props[i].getValue((EntityBean)value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +170,7 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Object[] getIdValues(Object bean){
|
||||
public Object[] getIdValues(EntityBean bean){
|
||||
Object[] bindvalues = new Object[props.length];
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
bindvalues[i] = props[i].getValue(bean);
|
||||
@@ -301,7 +271,7 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
}
|
||||
}
|
||||
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException {
|
||||
public Object readSet(DbReadContext ctx, EntityBean bean) throws SQLException {
|
||||
|
||||
LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
boolean notNull = false;
|
||||
@@ -430,7 +400,7 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Object convertSetId(Object idValue, Object bean) {
|
||||
public Object convertSetId(Object idValue, EntityBean bean) {
|
||||
|
||||
// allow Map or String for concatenated id
|
||||
Map<?,?> mapVal = null;
|
||||
|
||||
@@ -6,10 +6,7 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
@@ -74,16 +71,6 @@ public final class IdBinderSimple implements IdBinder {
|
||||
idProperty.buildSelectExpressionChain(prefix, selectChain);
|
||||
}
|
||||
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException {
|
||||
Rdn rdn = new Rdn(idProperty.getDbColumn(), id);
|
||||
name.add(rdn);
|
||||
}
|
||||
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException {
|
||||
Object id = idProperty.getValue(bean);
|
||||
createLdapNameById(name, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 1.
|
||||
*/
|
||||
@@ -130,7 +117,7 @@ public final class IdBinderSimple implements IdBinder {
|
||||
}
|
||||
}
|
||||
|
||||
public Object[] getIdValues(Object bean){
|
||||
public Object[] getIdValues(EntityBean bean){
|
||||
return new Object[]{idProperty.getValue(bean)};
|
||||
}
|
||||
|
||||
@@ -181,7 +168,7 @@ public final class IdBinderSimple implements IdBinder {
|
||||
idProperty.loadIgnore(ctx);
|
||||
}
|
||||
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException {
|
||||
public Object readSet(DbReadContext ctx, EntityBean bean) throws SQLException {
|
||||
Object id = idProperty.read(ctx);
|
||||
if (id != null){
|
||||
idProperty.setValue(bean, id);
|
||||
@@ -220,7 +207,7 @@ public final class IdBinderSimple implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Object convertSetId(Object idValue, Object bean) {
|
||||
public Object convertSetId(Object idValue, EntityBean bean) {
|
||||
|
||||
if (!idValue.getClass().equals(expectedType)){
|
||||
idValue = scalarType.toBeanType(idValue);
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.deploy.id;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
|
||||
import com.avaje.ebeaninternal.server.deploy.IntersectionRow;
|
||||
@@ -48,22 +49,17 @@ public interface ImportedId {
|
||||
/**
|
||||
* Append to the DML statement to the where clause.
|
||||
*/
|
||||
public void dmlWhere(GenerateDmlRequest request, Object bean);
|
||||
|
||||
/**
|
||||
* Return true if the id value has changed.
|
||||
*/
|
||||
public boolean hasChanged(Object bean, Object oldValues);
|
||||
public void dmlWhere(GenerateDmlRequest request, EntityBean bean);
|
||||
|
||||
/**
|
||||
* Bind the value from the bean.
|
||||
*/
|
||||
public Object bind(BindableRequest request, Object bean, boolean bindNull) throws SQLException;
|
||||
public Object bind(BindableRequest request, EntityBean bean) throws SQLException;
|
||||
|
||||
/**
|
||||
* For inserting into ManyToMany intersection.
|
||||
*/
|
||||
public void buildImport(IntersectionRow row, Object other);
|
||||
public void buildImport(IntersectionRow row, EntityBean other);
|
||||
|
||||
/**
|
||||
* Used to derive a missing concatenated key from multiple imported keys.
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.sql.SQLException;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanFkeyProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
@@ -68,7 +69,7 @@ public class ImportedIdEmbedded implements ImportedId {
|
||||
}
|
||||
}
|
||||
|
||||
public void dmlWhere(GenerateDmlRequest request, Object bean){
|
||||
public void dmlWhere(GenerateDmlRequest request, EntityBean bean){
|
||||
|
||||
Object embeddedId = null;
|
||||
if (bean != null) {
|
||||
@@ -82,10 +83,10 @@ public class ImportedIdEmbedded implements ImportedId {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
EntityBean embedded = (EntityBean)embeddedId;
|
||||
for (int i = 0; i < imported.length; i++) {
|
||||
if (imported[i].owner.isDbUpdatable()) {
|
||||
Object value = imported[i].foreignProperty.getValue(embeddedId);
|
||||
Object value = imported[i].foreignProperty.getValue(embedded);
|
||||
if (value == null){
|
||||
request.appendColumnIsNull(imported[i].localDbColumn);
|
||||
} else {
|
||||
@@ -96,14 +97,7 @@ public class ImportedIdEmbedded implements ImportedId {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasChanged(Object bean, Object oldValues) {
|
||||
Object id = foreignAssocOne.getValue(bean);
|
||||
Object oldId = foreignAssocOne.getValue(oldValues);
|
||||
|
||||
return !ValueUtil.areEqual(id, oldId);
|
||||
}
|
||||
|
||||
public Object bind(BindableRequest request, Object bean, boolean bindNull) throws SQLException {
|
||||
public Object bind(BindableRequest request, EntityBean bean) throws SQLException {
|
||||
|
||||
Object embeddedId = null;
|
||||
|
||||
@@ -114,15 +108,16 @@ public class ImportedIdEmbedded implements ImportedId {
|
||||
if (embeddedId == null){
|
||||
for (int i = 0; i < imported.length; i++) {
|
||||
if (imported[i].owner.isUpdateable()) {
|
||||
request.bind(null, imported[i].foreignProperty, imported[i].localDbColumn, true);
|
||||
request.bind(null, imported[i].foreignProperty, imported[i].localDbColumn);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
EntityBean embedded = (EntityBean)embeddedId;
|
||||
for (int i = 0; i < imported.length; i++) {
|
||||
if (imported[i].owner.isUpdateable()) {
|
||||
Object scalarValue = imported[i].foreignProperty.getValue(embeddedId);
|
||||
request.bind(scalarValue, imported[i].foreignProperty, imported[i].localDbColumn, true);
|
||||
Object scalarValue = imported[i].foreignProperty.getValue(embedded);
|
||||
request.bind(scalarValue, imported[i].foreignProperty, imported[i].localDbColumn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,9 +125,9 @@ public class ImportedIdEmbedded implements ImportedId {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void buildImport(IntersectionRow row, Object other){
|
||||
public void buildImport(IntersectionRow row, EntityBean other){
|
||||
|
||||
Object embeddedId = foreignAssocOne.getValue(other);
|
||||
EntityBean embeddedId = (EntityBean)foreignAssocOne.getValue(other);
|
||||
if (embeddedId == null){
|
||||
String msg = "Foreign Key value null?";
|
||||
throw new PersistenceException(msg);
|
||||
|
||||
@@ -2,13 +2,13 @@ package com.avaje.ebeaninternal.server.deploy.id;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
|
||||
import com.avaje.ebeaninternal.server.deploy.IntersectionRow;
|
||||
import com.avaje.ebeaninternal.server.persist.dml.GenerateDmlRequest;
|
||||
import com.avaje.ebeaninternal.server.persist.dmlbind.BindableRequest;
|
||||
import com.avaje.ebeaninternal.util.ValueUtil;
|
||||
|
||||
/**
|
||||
* Imported concatenated id that is not embedded.
|
||||
@@ -55,7 +55,7 @@ public class ImportedIdMultiple implements ImportedId {
|
||||
}
|
||||
}
|
||||
|
||||
public void dmlWhere(GenerateDmlRequest request, Object bean){
|
||||
public void dmlWhere(GenerateDmlRequest request, EntityBean bean){
|
||||
if (bean == null){
|
||||
for (int i = 0; i < imported.length; i++) {
|
||||
request.appendColumnIsNull(imported[i].localDbColumn);
|
||||
@@ -72,32 +72,19 @@ public class ImportedIdMultiple implements ImportedId {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasChanged(Object bean, Object oldValues) {
|
||||
|
||||
for (int i = 0; i < imported.length; i++) {
|
||||
Object id = imported[i].foreignProperty.getValue(bean);
|
||||
Object oldId = imported[i].foreignProperty.getValue(oldValues);
|
||||
if (!ValueUtil.areEqual(id, oldId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public Object bind(BindableRequest request, Object bean, boolean bindNull) throws SQLException {
|
||||
public Object bind(BindableRequest request, EntityBean bean) throws SQLException {
|
||||
|
||||
for (int i = 0; i < imported.length; i++) {
|
||||
if (imported[i].owner.isUpdateable()) {
|
||||
Object scalarValue = imported[i].foreignProperty.getValue(bean);
|
||||
request.bind(scalarValue, imported[i].foreignProperty, imported[i].localDbColumn, true);
|
||||
request.bind(scalarValue, imported[i].foreignProperty, imported[i].localDbColumn);
|
||||
}
|
||||
}
|
||||
// hmmm, not worrying about this just yet
|
||||
return null;
|
||||
}
|
||||
|
||||
public void buildImport(IntersectionRow row, Object other){
|
||||
public void buildImport(IntersectionRow row, EntityBean other){
|
||||
|
||||
for (int i = 0; i < imported.length; i++) {
|
||||
Object scalarValue = imported[i].foreignProperty.getValue(other);
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.List;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanFkeyProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
@@ -15,7 +16,6 @@ import com.avaje.ebeaninternal.server.deploy.DbSqlContext;
|
||||
import com.avaje.ebeaninternal.server.deploy.IntersectionRow;
|
||||
import com.avaje.ebeaninternal.server.persist.dml.GenerateDmlRequest;
|
||||
import com.avaje.ebeaninternal.server.persist.dmlbind.BindableRequest;
|
||||
import com.avaje.ebeaninternal.util.ValueUtil;
|
||||
|
||||
/**
|
||||
* Single scalar imported id.
|
||||
@@ -90,11 +90,11 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
|
||||
return localDbColumn;
|
||||
}
|
||||
|
||||
private Object getIdValue(Object bean) {
|
||||
return foreignProperty.getValueWithInheritance(bean);
|
||||
}
|
||||
private Object getIdValue(EntityBean bean) {
|
||||
return foreignProperty.getValue(bean);
|
||||
}
|
||||
|
||||
public void buildImport(IntersectionRow row, Object other){
|
||||
public void buildImport(IntersectionRow row, EntityBean other){
|
||||
|
||||
Object value = getIdValue(other);
|
||||
if (value == null){
|
||||
@@ -114,7 +114,7 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
|
||||
request.appendColumn(localDbColumn);
|
||||
}
|
||||
|
||||
public void dmlWhere(GenerateDmlRequest request, Object bean){
|
||||
public void dmlWhere(GenerateDmlRequest request, EntityBean bean){
|
||||
|
||||
if (owner.isDbUpdatable()){
|
||||
Object value = null;
|
||||
@@ -129,25 +129,13 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasChanged(Object bean, Object oldValues) {
|
||||
|
||||
Object id = getIdValue(bean);
|
||||
|
||||
if (oldValues != null){
|
||||
Object oldId = getIdValue(oldValues);
|
||||
return !ValueUtil.areEqual(id, oldId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object bind(BindableRequest request, Object bean, boolean bindNull) throws SQLException {
|
||||
public Object bind(BindableRequest request, EntityBean bean) throws SQLException {
|
||||
|
||||
Object value = null;
|
||||
if (bean != null){
|
||||
value = getIdValue(bean);
|
||||
}
|
||||
request.bind(value, foreignProperty, localDbColumn, bindNull);
|
||||
request.bind(value, foreignProperty, localDbColumn);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
+11
-24
@@ -65,11 +65,6 @@ public class DeployBeanDescriptor<T> {
|
||||
*/
|
||||
private LinkedHashMap<String, DeployBeanProperty> propMap = new LinkedHashMap<String, DeployBeanProperty>();
|
||||
|
||||
/**
|
||||
* The type of bean this describes.
|
||||
*/
|
||||
private final Class<T> beanType;
|
||||
|
||||
private EntityType entityType;
|
||||
|
||||
private final Map<String, DeployNamedQuery> namedQueries = new LinkedHashMap<String, DeployNamedQuery>();
|
||||
@@ -107,7 +102,7 @@ public class DeployBeanDescriptor<T> {
|
||||
/**
|
||||
* The concurrency mode for beans of this type.
|
||||
*/
|
||||
private ConcurrencyMode concurrencyMode = ConcurrencyMode.ALL;
|
||||
private ConcurrencyMode concurrencyMode;
|
||||
|
||||
private boolean updateChangesOnly;
|
||||
|
||||
@@ -134,11 +129,12 @@ public class DeployBeanDescriptor<T> {
|
||||
* faster than reflection at this stage.
|
||||
*/
|
||||
private BeanReflect beanReflect;
|
||||
private String[] properties;
|
||||
|
||||
/**
|
||||
* The EntityBean type used to create new EntityBeans.
|
||||
*/
|
||||
private Class<?> factoryType;
|
||||
private Class<T> beanType;
|
||||
|
||||
private List<BeanPersistController> persistControllers = new ArrayList<BeanPersistController>();
|
||||
private List<BeanPersistListener<T>> persistListeners = new ArrayList<BeanPersistListener<T>>();
|
||||
@@ -331,6 +327,14 @@ public class DeployBeanDescriptor<T> {
|
||||
return namedUpdates;
|
||||
}
|
||||
|
||||
public String[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(String[] props) {
|
||||
this.properties = props;
|
||||
}
|
||||
|
||||
public BeanReflect getBeanReflect() {
|
||||
return beanReflect;
|
||||
}
|
||||
@@ -342,23 +346,6 @@ public class DeployBeanDescriptor<T> {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class type this BeanDescriptor describes.
|
||||
*/
|
||||
public Class<?> getFactoryType() {
|
||||
return factoryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class used to create new EntityBean instances.
|
||||
* <p>
|
||||
* Normally this would be a subclass dynamically generated for this bean.
|
||||
* </p>
|
||||
*/
|
||||
public void setFactoryType(Class<?> factoryType) {
|
||||
this.factoryType = factoryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BeanReflect used to create new instances of an EntityBean. This
|
||||
* could use reflection or code generation to do this.
|
||||
|
||||
@@ -198,6 +198,8 @@ public class DeployBeanProperty {
|
||||
*/
|
||||
private Method writeMethod;
|
||||
|
||||
private int propertyIndex;
|
||||
|
||||
private BeanReflectGetter getter;
|
||||
|
||||
private BeanReflectSetter setter;
|
||||
@@ -410,6 +412,14 @@ public class DeployBeanProperty {
|
||||
this.scalarType = scalarType;
|
||||
}
|
||||
|
||||
public int getPropertyIndex() {
|
||||
return propertyIndex;
|
||||
}
|
||||
|
||||
public void setPropertyIndex(int propertyIndex) {
|
||||
this.propertyIndex = propertyIndex;
|
||||
}
|
||||
|
||||
public BeanReflectGetter getGetter() {
|
||||
return getter;
|
||||
}
|
||||
|
||||
+304
-305
@@ -5,6 +5,9 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.bean.BeanCollection.ModifyListenMode;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptorMap;
|
||||
@@ -20,347 +23,343 @@ import com.avaje.ebeaninternal.server.deploy.TableJoin;
|
||||
*/
|
||||
public class DeployBeanPropertyLists {
|
||||
|
||||
private BeanProperty derivedFirstVersionProp;
|
||||
private static final Logger logger = LoggerFactory.getLogger(DeployBeanPropertyLists.class);
|
||||
|
||||
private final BeanDescriptor<?> desc;
|
||||
private BeanProperty versionProperty;
|
||||
|
||||
private final LinkedHashMap<String, BeanProperty> propertyMap;
|
||||
private final BeanDescriptor<?> desc;
|
||||
|
||||
private final ArrayList<BeanProperty> ids = new ArrayList<BeanProperty>();
|
||||
private final LinkedHashMap<String, BeanProperty> propertyMap;
|
||||
|
||||
private final ArrayList<BeanProperty> version = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> ids = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanProperty> local = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> local = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanProperty> manys = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> nonManys = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> manys = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> nonManys = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanProperty> ones = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> ones = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanProperty> onesExported = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> onesExported = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanProperty> onesImported = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> onesImported = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanProperty> embedded = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> embedded = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanProperty> baseScalar = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> baseScalar = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanPropertyCompound> baseCompound = new ArrayList<BeanPropertyCompound>();
|
||||
private final ArrayList<BeanPropertyCompound> baseCompound = new ArrayList<BeanPropertyCompound>();
|
||||
|
||||
private final ArrayList<BeanProperty> transients = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> transients = new ArrayList<BeanProperty>();
|
||||
|
||||
private final ArrayList<BeanProperty> nonTransients = new ArrayList<BeanProperty>();
|
||||
private final ArrayList<BeanProperty> nonTransients = new ArrayList<BeanProperty>();
|
||||
|
||||
private final TableJoin[] tableJoins;
|
||||
private final TableJoin[] tableJoins;
|
||||
|
||||
private final BeanPropertyAssocOne<?> unidirectional;
|
||||
private final BeanPropertyAssocOne<?> unidirectional;
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public DeployBeanPropertyLists(BeanDescriptorMap owner, BeanDescriptor<?> desc, DeployBeanDescriptor<?> deploy) {
|
||||
this.desc = desc;
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public DeployBeanPropertyLists(BeanDescriptorMap owner, BeanDescriptor<?> desc, DeployBeanDescriptor<?> deploy) {
|
||||
this.desc = desc;
|
||||
|
||||
DeployBeanPropertyAssocOne<?> deployUnidirectional = deploy.getUnidirectional();
|
||||
if (deployUnidirectional == null) {
|
||||
unidirectional = null;
|
||||
DeployBeanPropertyAssocOne<?> deployUnidirectional = deploy.getUnidirectional();
|
||||
if (deployUnidirectional == null) {
|
||||
unidirectional = null;
|
||||
} else {
|
||||
unidirectional = new BeanPropertyAssocOne(owner, desc, deployUnidirectional);
|
||||
}
|
||||
|
||||
this.propertyMap = new LinkedHashMap<String, BeanProperty>();
|
||||
|
||||
Iterator<DeployBeanProperty> deployIt = deploy.propertiesAll();
|
||||
while (deployIt.hasNext()) {
|
||||
DeployBeanProperty deployProp = deployIt.next();
|
||||
BeanProperty beanProp = createBeanProperty(owner, deployProp);
|
||||
propertyMap.put(beanProp.getName(), beanProp);
|
||||
}
|
||||
|
||||
Iterator<BeanProperty> it = propertyMap.values().iterator();
|
||||
|
||||
int order = 0;
|
||||
while (it.hasNext()) {
|
||||
BeanProperty prop = it.next();
|
||||
prop.setDeployOrder(order++);
|
||||
allocateToList(prop);
|
||||
}
|
||||
|
||||
List<DeployTableJoin> deployTableJoins = deploy.getTableJoins();
|
||||
tableJoins = new TableJoin[deployTableJoins.size()];
|
||||
for (int i = 0; i < deployTableJoins.size(); i++) {
|
||||
tableJoins[i] = new TableJoin(deployTableJoins.get(i), propertyMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unidirectional.
|
||||
*/
|
||||
public BeanPropertyAssocOne<?> getUnidirectional() {
|
||||
return unidirectional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the property to a list.
|
||||
*/
|
||||
private void allocateToList(BeanProperty prop) {
|
||||
if (prop.isTransient()) {
|
||||
transients.add(prop);
|
||||
return;
|
||||
}
|
||||
if (prop.isId()) {
|
||||
ids.add(prop);
|
||||
return;
|
||||
} else {
|
||||
nonTransients.add(prop);
|
||||
}
|
||||
|
||||
if (desc.getInheritInfo() != null && prop.isLocal()) {
|
||||
local.add(prop);
|
||||
}
|
||||
|
||||
if (prop instanceof BeanPropertyAssocMany<?>) {
|
||||
manys.add(prop);
|
||||
|
||||
} else {
|
||||
nonManys.add(prop);
|
||||
if (prop instanceof BeanPropertyAssocOne<?>) {
|
||||
if (prop.isEmbedded()) {
|
||||
embedded.add(prop);
|
||||
} else {
|
||||
unidirectional = new BeanPropertyAssocOne(owner, desc, deployUnidirectional);
|
||||
ones.add(prop);
|
||||
BeanPropertyAssocOne<?> assocOne = (BeanPropertyAssocOne<?>) prop;
|
||||
if (assocOne.isOneToOneExported()) {
|
||||
onesExported.add(prop);
|
||||
} else {
|
||||
onesImported.add(prop);
|
||||
}
|
||||
}
|
||||
|
||||
this.propertyMap = new LinkedHashMap<String, BeanProperty>();
|
||||
|
||||
Iterator<DeployBeanProperty> deployIt = deploy.propertiesAll();
|
||||
while (deployIt.hasNext()) {
|
||||
DeployBeanProperty deployProp = deployIt.next();
|
||||
BeanProperty beanProp = createBeanProperty(owner, deployProp);
|
||||
propertyMap.put(beanProp.getName(), beanProp);
|
||||
} else {
|
||||
// its a "base" property...
|
||||
if (prop.isVersion()) {
|
||||
if (versionProperty == null) {
|
||||
versionProperty = prop;
|
||||
} else {
|
||||
logger.warn("Multiple @Version properties - property " + prop.getFullBeanName()
|
||||
+ " not treated as a version property");
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<BeanProperty> it = propertyMap.values().iterator();
|
||||
|
||||
int order = 0;
|
||||
while (it.hasNext()) {
|
||||
BeanProperty prop = it.next();
|
||||
prop.setDeployOrder(order++);
|
||||
allocateToList(prop);
|
||||
}
|
||||
|
||||
List<DeployTableJoin> deployTableJoins = deploy.getTableJoins();
|
||||
tableJoins = new TableJoin[deployTableJoins.size()];
|
||||
for (int i = 0; i < deployTableJoins.size(); i++) {
|
||||
tableJoins[i] = new TableJoin(deployTableJoins.get(i), propertyMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unidirectional.
|
||||
*/
|
||||
public BeanPropertyAssocOne<?> getUnidirectional() {
|
||||
return unidirectional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the property to a list.
|
||||
*/
|
||||
private void allocateToList(BeanProperty prop) {
|
||||
if (prop.isTransient()) {
|
||||
transients.add(prop);
|
||||
return;
|
||||
}
|
||||
if (prop.isId()) {
|
||||
ids.add(prop);
|
||||
return;
|
||||
if (prop instanceof BeanPropertyCompound) {
|
||||
baseCompound.add((BeanPropertyCompound) prop);
|
||||
} else {
|
||||
nonTransients.add(prop);
|
||||
baseScalar.add(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (desc.getInheritInfo() != null && prop.isLocal()) {
|
||||
local.add(prop);
|
||||
public LinkedHashMap<String, BeanProperty> getPropertyMap() {
|
||||
return propertyMap;
|
||||
}
|
||||
|
||||
public TableJoin[] getTableJoin() {
|
||||
return tableJoins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base scalar properties (excludes Id and secondary table
|
||||
* properties).
|
||||
*/
|
||||
public BeanProperty[] getBaseScalar() {
|
||||
return (BeanProperty[]) baseScalar.toArray(new BeanProperty[baseScalar.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyCompound[] getBaseCompound() {
|
||||
return (BeanPropertyCompound[]) baseCompound.toArray(new BeanPropertyCompound[baseCompound.size()]);
|
||||
}
|
||||
|
||||
public BeanProperty getNaturalKey() {
|
||||
String naturalKey = desc.getCacheOptions().getNaturalKey();
|
||||
if (naturalKey != null) {
|
||||
return propertyMap.get(naturalKey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BeanProperty[] getId() {
|
||||
return (BeanProperty[]) ids.toArray(new BeanProperty[ids.size()]);
|
||||
}
|
||||
|
||||
public BeanProperty[] getNonTransients() {
|
||||
return (BeanProperty[]) nonTransients.toArray(new BeanProperty[nonTransients.size()]);
|
||||
}
|
||||
|
||||
public BeanProperty[] getTransients() {
|
||||
return (BeanProperty[]) transients.toArray(new BeanProperty[transients.size()]);
|
||||
}
|
||||
|
||||
public BeanProperty getVersionProperty() {
|
||||
return versionProperty;
|
||||
}
|
||||
|
||||
public BeanProperty[] getLocal() {
|
||||
return (BeanProperty[]) local.toArray(new BeanProperty[local.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getEmbedded() {
|
||||
return (BeanPropertyAssocOne[]) embedded.toArray(new BeanPropertyAssocOne[embedded.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneExported() {
|
||||
return (BeanPropertyAssocOne[]) onesExported.toArray(new BeanPropertyAssocOne[onesExported.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneImported() {
|
||||
return (BeanPropertyAssocOne[]) onesImported.toArray(new BeanPropertyAssocOne[onesImported.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOnes() {
|
||||
return (BeanPropertyAssocOne[]) ones.toArray(new BeanPropertyAssocOne[ones.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneExportedSave() {
|
||||
return getOne(false, Mode.Save);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneExportedDelete() {
|
||||
return getOne(false, Mode.Delete);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneImportedSave() {
|
||||
return getOne(true, Mode.Save);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneImportedDelete() {
|
||||
return getOne(true, Mode.Delete);
|
||||
}
|
||||
|
||||
public BeanProperty[] getNonMany() {
|
||||
return (BeanProperty[]) nonManys.toArray(new BeanProperty[nonManys.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocMany<?>[] getMany() {
|
||||
return (BeanPropertyAssocMany[]) manys.toArray(new BeanPropertyAssocMany[manys.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocMany<?>[] getManySave() {
|
||||
return getMany(Mode.Save);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocMany<?>[] getManyDelete() {
|
||||
return getMany(Mode.Delete);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocMany<?>[] getManyToMany() {
|
||||
return getMany2Many();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mode used to determine which BeanPropertyAssoc to include.
|
||||
*/
|
||||
private enum Mode {
|
||||
Save, Delete, Validate;
|
||||
}
|
||||
|
||||
private BeanPropertyAssocOne<?>[] getOne(boolean imported, Mode mode) {
|
||||
ArrayList<BeanPropertyAssocOne<?>> list = new ArrayList<BeanPropertyAssocOne<?>>();
|
||||
for (int i = 0; i < ones.size(); i++) {
|
||||
BeanPropertyAssocOne<?> prop = (BeanPropertyAssocOne<?>) ones.get(i);
|
||||
if (imported != prop.isOneToOneExported()) {
|
||||
switch (mode) {
|
||||
case Save:
|
||||
if (prop.getCascadeInfo().isSave()) {
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
case Delete:
|
||||
if (prop.getCascadeInfo().isDelete()) {
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
case Validate:
|
||||
if (prop.getCascadeInfo().isValidate()) {
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop instanceof BeanPropertyAssocMany<?>) {
|
||||
manys.add(prop);
|
||||
return (BeanPropertyAssocOne[]) list.toArray(new BeanPropertyAssocOne[list.size()]);
|
||||
}
|
||||
|
||||
} else {
|
||||
nonManys.add(prop);
|
||||
if (prop instanceof BeanPropertyAssocOne<?>) {
|
||||
if (prop.isEmbedded()) {
|
||||
embedded.add(prop);
|
||||
} else {
|
||||
ones.add(prop);
|
||||
BeanPropertyAssocOne<?> assocOne = (BeanPropertyAssocOne<?>) prop;
|
||||
if (assocOne.isOneToOneExported()) {
|
||||
onesExported.add(prop);
|
||||
} else {
|
||||
onesImported.add(prop);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// its a "base" property...
|
||||
if (prop.isVersion()) {
|
||||
version.add(prop);
|
||||
if (derivedFirstVersionProp == null) {
|
||||
derivedFirstVersionProp = prop;
|
||||
}
|
||||
}
|
||||
if (prop instanceof BeanPropertyCompound) {
|
||||
baseCompound.add((BeanPropertyCompound) prop);
|
||||
} else {
|
||||
baseScalar.add(prop);
|
||||
}
|
||||
}
|
||||
private BeanPropertyAssocMany<?>[] getMany2Many() {
|
||||
ArrayList<BeanPropertyAssocMany<?>> list = new ArrayList<BeanPropertyAssocMany<?>>();
|
||||
for (int i = 0; i < manys.size(); i++) {
|
||||
BeanPropertyAssocMany<?> prop = (BeanPropertyAssocMany<?>) manys.get(i);
|
||||
if (prop.isManyToMany()) {
|
||||
list.add(prop);
|
||||
}
|
||||
}
|
||||
|
||||
return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[list.size()]);
|
||||
}
|
||||
|
||||
private BeanPropertyAssocMany<?>[] getMany(Mode mode) {
|
||||
ArrayList<BeanPropertyAssocMany<?>> list = new ArrayList<BeanPropertyAssocMany<?>>();
|
||||
for (int i = 0; i < manys.size(); i++) {
|
||||
BeanPropertyAssocMany<?> prop = (BeanPropertyAssocMany<?>) manys.get(i);
|
||||
|
||||
switch (mode) {
|
||||
case Save:
|
||||
if (prop.getCascadeInfo().isSave() || prop.isManyToMany()
|
||||
|| ModifyListenMode.REMOVALS.equals(prop.getModifyListenMode())) {
|
||||
// Note ManyToMany always included as we always 'save'
|
||||
// the relationship via insert/delete of intersection table
|
||||
// REMOVALS means including PrivateOwned relationships
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
case Delete:
|
||||
if (prop.getCascadeInfo().isDelete() || ModifyListenMode.REMOVALS.equals(prop.getModifyListenMode())) {
|
||||
// REMOVALS means including PrivateOwned relationships
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
case Validate:
|
||||
if (prop.getCascadeInfo().isValidate()) {
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BeanProperty getFirstVersion() {
|
||||
return derivedFirstVersionProp;
|
||||
}
|
||||
return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[list.size()]);
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, BeanProperty> getPropertyMap() {
|
||||
return propertyMap;
|
||||
}
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private BeanProperty createBeanProperty(BeanDescriptorMap owner, DeployBeanProperty deployProp) {
|
||||
|
||||
public TableJoin[] getTableJoin() {
|
||||
return tableJoins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base scalar properties (excludes Id and secondary table
|
||||
* properties).
|
||||
*/
|
||||
public BeanProperty[] getBaseScalar() {
|
||||
return (BeanProperty[]) baseScalar.toArray(new BeanProperty[baseScalar.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyCompound[] getBaseCompound() {
|
||||
return (BeanPropertyCompound[]) baseCompound.toArray(new BeanPropertyCompound[baseCompound.size()]);
|
||||
if (deployProp instanceof DeployBeanPropertyAssocOne) {
|
||||
return new BeanPropertyAssocOne(owner, desc, (DeployBeanPropertyAssocOne) deployProp);
|
||||
}
|
||||
|
||||
public BeanProperty getNaturalKey() {
|
||||
String naturalKey = desc.getCacheOptions().getNaturalKey();
|
||||
if (naturalKey != null){
|
||||
return propertyMap.get(naturalKey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BeanProperty[] getId() {
|
||||
return (BeanProperty[]) ids.toArray(new BeanProperty[ids.size()]);
|
||||
}
|
||||
|
||||
public BeanProperty[] getNonTransients() {
|
||||
return (BeanProperty[]) nonTransients.toArray(new BeanProperty[nonTransients.size()]);
|
||||
}
|
||||
|
||||
public BeanProperty[] getTransients() {
|
||||
return (BeanProperty[]) transients.toArray(new BeanProperty[transients.size()]);
|
||||
}
|
||||
|
||||
public BeanProperty[] getVersion() {
|
||||
return (BeanProperty[]) version.toArray(new BeanProperty[version.size()]);
|
||||
}
|
||||
|
||||
public BeanProperty[] getLocal() {
|
||||
return (BeanProperty[]) local.toArray(new BeanProperty[local.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getEmbedded() {
|
||||
return (BeanPropertyAssocOne[]) embedded.toArray(new BeanPropertyAssocOne[embedded.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneExported() {
|
||||
return (BeanPropertyAssocOne[]) onesExported.toArray(new BeanPropertyAssocOne[onesExported.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneImported() {
|
||||
return (BeanPropertyAssocOne[]) onesImported.toArray(new BeanPropertyAssocOne[onesImported.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOnes() {
|
||||
return (BeanPropertyAssocOne[]) ones.toArray(new BeanPropertyAssocOne[ones.size()]);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneExportedSave() {
|
||||
return getOne(false, Mode.Save);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneExportedDelete() {
|
||||
return getOne(false, Mode.Delete);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneImportedSave() {
|
||||
return getOne(true, Mode.Save);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocOne<?>[] getOneImportedDelete() {
|
||||
return getOne(true, Mode.Delete);
|
||||
}
|
||||
|
||||
public BeanProperty[] getNonMany() {
|
||||
return (BeanProperty[]) nonManys.toArray(new BeanProperty[nonManys.size()]);
|
||||
if (deployProp instanceof DeployBeanPropertySimpleCollection<?>) {
|
||||
return new BeanPropertySimpleCollection(owner, desc, (DeployBeanPropertySimpleCollection) deployProp);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocMany<?>[] getMany() {
|
||||
return (BeanPropertyAssocMany[]) manys.toArray(new BeanPropertyAssocMany[manys.size()]);
|
||||
if (deployProp instanceof DeployBeanPropertyAssocMany) {
|
||||
return new BeanPropertyAssocMany(owner, desc, (DeployBeanPropertyAssocMany) deployProp);
|
||||
}
|
||||
|
||||
if (deployProp instanceof DeployBeanPropertyCompound) {
|
||||
return new BeanPropertyCompound(owner, desc, (DeployBeanPropertyCompound) deployProp);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocMany<?>[] getManySave() {
|
||||
return getMany(Mode.Save);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocMany<?>[] getManyDelete() {
|
||||
return getMany(Mode.Delete);
|
||||
}
|
||||
|
||||
public BeanPropertyAssocMany<?>[] getManyToMany() {
|
||||
return getMany2Many();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mode used to determine which BeanPropertyAssoc to include.
|
||||
*/
|
||||
private enum Mode {
|
||||
Save, Delete, Validate;
|
||||
}
|
||||
|
||||
private BeanPropertyAssocOne<?>[] getOne(boolean imported, Mode mode) {
|
||||
ArrayList<BeanPropertyAssocOne<?>> list = new ArrayList<BeanPropertyAssocOne<?>>();
|
||||
for (int i = 0; i < ones.size(); i++) {
|
||||
BeanPropertyAssocOne<?> prop = (BeanPropertyAssocOne<?>) ones.get(i);
|
||||
if (imported != prop.isOneToOneExported()) {
|
||||
switch (mode) {
|
||||
case Save:
|
||||
if (prop.getCascadeInfo().isSave()) {
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
case Delete:
|
||||
if (prop.getCascadeInfo().isDelete()) {
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
case Validate:
|
||||
if (prop.getCascadeInfo().isValidate()) {
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (BeanPropertyAssocOne[]) list.toArray(new BeanPropertyAssocOne[list.size()]);
|
||||
}
|
||||
|
||||
private BeanPropertyAssocMany<?>[] getMany2Many() {
|
||||
ArrayList<BeanPropertyAssocMany<?>> list = new ArrayList<BeanPropertyAssocMany<?>>();
|
||||
for (int i = 0; i < manys.size(); i++) {
|
||||
BeanPropertyAssocMany<?> prop = (BeanPropertyAssocMany<?>) manys.get(i);
|
||||
if (prop.isManyToMany()) {
|
||||
list.add(prop);
|
||||
}
|
||||
}
|
||||
|
||||
return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[list.size()]);
|
||||
}
|
||||
|
||||
private BeanPropertyAssocMany<?>[] getMany(Mode mode) {
|
||||
ArrayList<BeanPropertyAssocMany<?>> list = new ArrayList<BeanPropertyAssocMany<?>>();
|
||||
for (int i = 0; i < manys.size(); i++) {
|
||||
BeanPropertyAssocMany<?> prop = (BeanPropertyAssocMany<?>) manys.get(i);
|
||||
|
||||
switch (mode) {
|
||||
case Save:
|
||||
if (prop.getCascadeInfo().isSave() || prop.isManyToMany()
|
||||
|| ModifyListenMode.REMOVALS.equals(prop.getModifyListenMode())) {
|
||||
// Note ManyToMany always included as we always 'save'
|
||||
// the relationship via insert/delete of intersection table
|
||||
// REMOVALS means including PrivateOwned relationships
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
case Delete:
|
||||
if (prop.getCascadeInfo().isDelete()
|
||||
|| ModifyListenMode.REMOVALS.equals(prop.getModifyListenMode())) {
|
||||
// REMOVALS means including PrivateOwned relationships
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
case Validate:
|
||||
if (prop.getCascadeInfo().isValidate()) {
|
||||
list.add(prop);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[list.size()]);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private BeanProperty createBeanProperty(BeanDescriptorMap owner, DeployBeanProperty deployProp) {
|
||||
|
||||
if (deployProp instanceof DeployBeanPropertyAssocOne) {
|
||||
|
||||
return new BeanPropertyAssocOne(owner, desc, (DeployBeanPropertyAssocOne) deployProp);
|
||||
}
|
||||
if (deployProp instanceof DeployBeanPropertySimpleCollection<?>) {
|
||||
|
||||
return new BeanPropertySimpleCollection(owner, desc, (DeployBeanPropertySimpleCollection)deployProp);
|
||||
}
|
||||
if (deployProp instanceof DeployBeanPropertyAssocMany) {
|
||||
|
||||
return new BeanPropertyAssocMany(owner, desc, (DeployBeanPropertyAssocMany) deployProp);
|
||||
}
|
||||
if (deployProp instanceof DeployBeanPropertyCompound) {
|
||||
|
||||
return new BeanPropertyCompound(owner, desc, (DeployBeanPropertyCompound) deployProp);
|
||||
}
|
||||
|
||||
return new BeanProperty(owner, desc, deployProp);
|
||||
}
|
||||
return new BeanProperty(owner, desc, deployProp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import com.avaje.ebean.Query.UseIndex;
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
@@ -54,32 +52,15 @@ public class AnnotationClass extends AnnotationParser {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isXmlElement(Class<?> cls) {
|
||||
XmlRootElement rootElement = cls.getAnnotation(XmlRootElement.class);
|
||||
if (rootElement != null) {
|
||||
return true;
|
||||
}
|
||||
XmlType xmlType = cls.getAnnotation(XmlType.class);
|
||||
if (xmlType != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void read(Class<?> cls) {
|
||||
|
||||
Entity entity = cls.getAnnotation(Entity.class);
|
||||
if (entity != null) {
|
||||
// checkDefaultConstructor();
|
||||
if (entity.name().equals("")) {
|
||||
descriptor.setName(cls.getSimpleName());
|
||||
|
||||
} else {
|
||||
descriptor.setName(entity.name());
|
||||
}
|
||||
} else if (isXmlElement(cls)) {
|
||||
descriptor.setName(cls.getSimpleName());
|
||||
descriptor.setEntityType(EntityType.XMLELEMENT);
|
||||
}
|
||||
|
||||
Embeddable embeddable = cls.getAnnotation(Embeddable.class);
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.avaje.ebeaninternal.server.el;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
|
||||
/**
|
||||
* Comparator based on a ElGetValue.
|
||||
*/
|
||||
@@ -21,15 +23,15 @@ public final class ElComparatorProperty<T> implements Comparator<T>, ElComparato
|
||||
|
||||
public int compare(T o1, T o2) {
|
||||
|
||||
Object val1 = elGetValue.elGetValue(o1);
|
||||
Object val2 = elGetValue.elGetValue(o2);
|
||||
Object val1 = elGetValue.elGetValue((EntityBean)o1);
|
||||
Object val2 = elGetValue.elGetValue((EntityBean)o2);
|
||||
|
||||
return compareValues(val1, val2);
|
||||
}
|
||||
|
||||
public int compareValue(Object value, T o2) {
|
||||
|
||||
Object val2 = elGetValue.elGetValue(o2);
|
||||
Object val2 = elGetValue.elGetValue((EntityBean)o2);
|
||||
|
||||
return compareValues(value, val2);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
|
||||
|
||||
/**
|
||||
* Contains the various ElMatcher implementations.
|
||||
@@ -26,7 +28,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
String v = (String)elGetValue.elGetValue(bean);
|
||||
String v = (String)elGetValue.elGetValue((EntityBean)bean);
|
||||
return pattern.matcher(v).matches();
|
||||
}
|
||||
}
|
||||
@@ -53,7 +55,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
String v = (String)elGetValue.elGetValue(bean);
|
||||
String v = (String)elGetValue.elGetValue((EntityBean)bean);
|
||||
return value.equalsIgnoreCase(v);
|
||||
}
|
||||
}
|
||||
@@ -73,7 +75,7 @@ class ElMatchBuilder {
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
|
||||
String v = (String)elGetValue.elGetValue(bean);
|
||||
String v = (String)elGetValue.elGetValue((EntityBean)bean);
|
||||
return charMatch.startsWith(v);
|
||||
}
|
||||
}
|
||||
@@ -93,7 +95,7 @@ class ElMatchBuilder {
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
|
||||
String v = (String)elGetValue.elGetValue(bean);
|
||||
String v = (String)elGetValue.elGetValue((EntityBean)bean);
|
||||
return charMatch.endsWith(v);
|
||||
}
|
||||
}
|
||||
@@ -104,7 +106,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
String v = (String)elGetValue.elGetValue(bean);
|
||||
String v = (String)elGetValue.elGetValue((EntityBean)bean);
|
||||
return value.startsWith(v);
|
||||
}
|
||||
}
|
||||
@@ -115,7 +117,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
String v = (String)elGetValue.elGetValue(bean);
|
||||
String v = (String)elGetValue.elGetValue((EntityBean)bean);
|
||||
return value.endsWith(v);
|
||||
}
|
||||
}
|
||||
@@ -129,7 +131,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
return (null == elGetValue.elGetValue(bean));
|
||||
return (null == elGetValue.elGetValue((EntityBean)bean));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +144,7 @@ class ElMatchBuilder {
|
||||
}
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
return (null != elGetValue.elGetValue(bean));
|
||||
return (null != elGetValue.elGetValue((EntityBean)bean));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +175,7 @@ class ElMatchBuilder {
|
||||
|
||||
public boolean isMatch(T bean) {
|
||||
|
||||
Object value = elGetValue.elGetValue(bean);
|
||||
Object value = elGetValue.elGetValue((EntityBean)bean);
|
||||
if (value == null){
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public class ElPropertyChain implements ElPropertyValue {
|
||||
return lastElPropertyValue.isLocalEncrypted();
|
||||
}
|
||||
|
||||
public Object[] getAssocOneIdValues(Object bean) {
|
||||
public Object[] getAssocOneIdValues(EntityBean bean) {
|
||||
// Don't navigate the object graph as bean
|
||||
// is assumed to be the appropriate type
|
||||
return lastElPropertyValue.getAssocOneIdValues(bean);
|
||||
@@ -225,10 +225,10 @@ public class ElPropertyChain implements ElPropertyValue {
|
||||
return lastElPropertyValue.elConvertType(value);
|
||||
}
|
||||
|
||||
public Object elGetValue(Object bean) {
|
||||
public Object elGetValue(EntityBean bean) {
|
||||
|
||||
for (int i = 0; i < chain.length; i++) {
|
||||
bean = chain[i].elGetValue(bean);
|
||||
bean = (EntityBean)chain[i].elGetValue(bean);
|
||||
if (bean == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -237,24 +237,22 @@ public class ElPropertyChain implements ElPropertyValue {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object elGetReference(Object bean) {
|
||||
public Object elGetReference(EntityBean bean) {
|
||||
|
||||
Object prevBean = bean;
|
||||
EntityBean prevBean = bean;
|
||||
for (int i = 0; i < last; i++) {
|
||||
// always return non null prevBean
|
||||
prevBean = chain[i].elGetReference(prevBean);
|
||||
prevBean = (EntityBean)chain[i].elGetReference(prevBean);
|
||||
}
|
||||
// try the last step in the chain
|
||||
bean = chain[last].elGetValue(prevBean);
|
||||
|
||||
return bean;
|
||||
return chain[last].elGetValue(prevBean);
|
||||
}
|
||||
|
||||
|
||||
public void elSetLoaded(Object bean) {
|
||||
public void elSetLoaded(EntityBean bean) {
|
||||
|
||||
for (int i = 0; i < last; i++) {
|
||||
bean = chain[i].elGetValue(bean);
|
||||
bean = (EntityBean)chain[i].elGetValue(bean);
|
||||
if (bean == null){
|
||||
break;
|
||||
}
|
||||
@@ -264,10 +262,10 @@ public class ElPropertyChain implements ElPropertyValue {
|
||||
}
|
||||
}
|
||||
|
||||
public void elSetReference(Object bean) {
|
||||
public void elSetReference(EntityBean bean) {
|
||||
|
||||
for (int i = 0; i < last; i++) {
|
||||
bean = chain[i].elGetValue(bean);
|
||||
bean = (EntityBean)chain[i].elGetValue(bean);
|
||||
if (bean == null){
|
||||
break;
|
||||
}
|
||||
@@ -277,18 +275,18 @@ public class ElPropertyChain implements ElPropertyValue {
|
||||
}
|
||||
}
|
||||
|
||||
public void elSetValue(Object bean, Object value, boolean populate, boolean reference){
|
||||
public void elSetValue(EntityBean bean, Object value, boolean populate, boolean reference){
|
||||
|
||||
Object prevBean = bean;
|
||||
EntityBean prevBean = bean;
|
||||
if (populate){
|
||||
for (int i = 0; i < last; i++) {
|
||||
// always return non null prevBean
|
||||
prevBean = chain[i].elGetReference(prevBean);
|
||||
prevBean = (EntityBean)chain[i].elGetReference(prevBean);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < last; i++) {
|
||||
// always return non null prevBean
|
||||
prevBean = chain[i].elGetValue(prevBean);
|
||||
prevBean = (EntityBean)chain[i].elGetValue(prevBean);
|
||||
if (prevBean == null){
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.el;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.text.StringFormatter;
|
||||
import com.avaje.ebean.text.StringParser;
|
||||
|
||||
@@ -14,7 +15,7 @@ public interface ElPropertyValue extends ElPropertyDeploy {
|
||||
/**
|
||||
* Return the Id values for the given bean value.
|
||||
*/
|
||||
public Object[] getAssocOneIdValues(Object bean);
|
||||
public Object[] getAssocOneIdValues(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Return the Id expression string.
|
||||
@@ -89,13 +90,13 @@ public interface ElPropertyValue extends ElPropertyDeploy {
|
||||
/**
|
||||
* Return the value from a given entity bean.
|
||||
*/
|
||||
public Object elGetValue(Object bean);
|
||||
public Object elGetValue(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Return the value ensuring objects prior to the top scalar property are
|
||||
* automatically populated.
|
||||
*/
|
||||
public Object elGetReference(Object bean);
|
||||
public Object elGetReference(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Set a value given a root level bean.
|
||||
@@ -103,12 +104,12 @@ public interface ElPropertyValue extends ElPropertyDeploy {
|
||||
* If populate then
|
||||
* </p>
|
||||
*/
|
||||
public void elSetValue(Object bean, Object value, boolean populate, boolean reference);
|
||||
public void elSetValue(EntityBean bean, Object value, boolean populate, boolean reference);
|
||||
|
||||
/**
|
||||
* Make the owning bean of this property a reference (as in not new/dirty).
|
||||
*/
|
||||
public void elSetReference(Object bean);
|
||||
public void elSetReference(EntityBean bean);
|
||||
|
||||
/**
|
||||
* Convert the value to the expected type.
|
||||
|
||||
+3
-2
@@ -5,6 +5,7 @@ import java.util.Iterator;
|
||||
|
||||
import com.avaje.ebean.ExampleExpression;
|
||||
import com.avaje.ebean.LikeType;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.event.BeanQueryRequest;
|
||||
import com.avaje.ebeaninternal.api.ManyWhereJoins;
|
||||
import com.avaje.ebeaninternal.api.SpiExpression;
|
||||
@@ -42,7 +43,7 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
/**
|
||||
* The example bean containing the properties.
|
||||
*/
|
||||
private final Object entity;
|
||||
private final EntityBean entity;
|
||||
|
||||
/**
|
||||
* Set to true to use case insensitive expressions.
|
||||
@@ -77,7 +78,7 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
* @param likeType
|
||||
* the type of Like wild card used
|
||||
*/
|
||||
public DefaultExampleExpression(FilterExprPath pathPrefix, Object entity, boolean caseInsensitive, LikeType likeType) {
|
||||
public DefaultExampleExpression(FilterExprPath pathPrefix, EntityBean entity, boolean caseInsensitive, LikeType likeType) {
|
||||
this.pathPrefix = pathPrefix;
|
||||
this.entity = entity;
|
||||
this.caseInsensitive = caseInsensitive;
|
||||
|
||||
+11
-3
@@ -11,6 +11,7 @@ import com.avaje.ebean.ExpressionList;
|
||||
import com.avaje.ebean.Junction;
|
||||
import com.avaje.ebean.LikeType;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionFactory;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
|
||||
@@ -135,11 +136,18 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
return new NullExpression(prefix, propertyName, true);
|
||||
}
|
||||
|
||||
private EntityBean checkEntityBean(Object bean) {
|
||||
if (bean == null || (bean instanceof EntityBean == false)) {
|
||||
throw new IllegalStateException("Expecting an EntityBean");
|
||||
}
|
||||
return (EntityBean)bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive {@link #exampleLike(Object)}
|
||||
*/
|
||||
public ExampleExpression iexampleLike(Object example) {
|
||||
return new DefaultExampleExpression(prefix, example, true, LikeType.RAW);
|
||||
return new DefaultExampleExpression(prefix, checkEntityBean(example), true, LikeType.RAW);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,14 +155,14 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* LikeType.RAW (you need to add you own wildcards % and _).
|
||||
*/
|
||||
public ExampleExpression exampleLike(Object example) {
|
||||
return new DefaultExampleExpression(prefix, example, false, LikeType.RAW);
|
||||
return new DefaultExampleExpression(prefix, checkEntityBean(example), false, LikeType.RAW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the query by Example expression specifying more options.
|
||||
*/
|
||||
public ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType) {
|
||||
return new DefaultExampleExpression(prefix, example, caseInsensitive, likeType);
|
||||
return new DefaultExampleExpression(prefix, checkEntityBean(example), caseInsensitive, likeType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.avaje.ebeaninternal.server.expression;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.event.BeanQueryRequest;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
@@ -35,7 +36,7 @@ class InExpression extends AbstractExpression {
|
||||
|
||||
} else {
|
||||
// extract the id values from the bean
|
||||
Object[] ids = prop.getAssocOneIdValues(values[i]);
|
||||
Object[] ids = prop.getAssocOneIdValues((EntityBean)values[i]);
|
||||
if (ids != null) {
|
||||
for (int j = 0; j < ids.length; j++) {
|
||||
request.addBindValue(ids[j]);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.expression;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.event.BeanQueryRequest;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
@@ -47,7 +48,7 @@ public class SimpleExpression extends AbstractExpression implements LuceneAwareE
|
||||
ElPropertyValue prop = getElProp(request);
|
||||
if (prop != null) {
|
||||
if (prop.isAssocId()) {
|
||||
Object[] ids = prop.getAssocOneIdValues(value);
|
||||
Object[] ids = prop.getAssocOneIdValues((EntityBean)value);
|
||||
if (ids != null) {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
request.addBindValue(ids[i]);
|
||||
|
||||
@@ -180,7 +180,9 @@ public class DLoadBeanContext implements LoadBeanContext, BeanLoader {
|
||||
}
|
||||
}
|
||||
|
||||
LoadBeanRequest req = new LoadBeanRequest(this, batch, null, batchSize, true, ebi.getLazyLoadProperty(), hitCache);
|
||||
int lazyLoadIndex = ebi.getLazyLoadProperty();
|
||||
String lazyLoadProp = ebi.getProperty(lazyLoadIndex);
|
||||
LoadBeanRequest req = new LoadBeanRequest(this, batch, null, batchSize, true, lazyLoadProp, hitCache);
|
||||
parent.getEbeanServer().loadBean(req);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.List;
|
||||
|
||||
import com.avaje.ebean.bean.BeanCollection;
|
||||
import com.avaje.ebean.bean.BeanCollectionLoader;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.ObjectGraphNode;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebeaninternal.api.LoadManyContext;
|
||||
@@ -123,7 +124,7 @@ public class DLoadManyContext implements LoadManyContext, BeanCollectionLoader {
|
||||
synchronized (weakList) {
|
||||
boolean hitCache = desc.isBeanCaching() && !onlyIds && !parent.isExcludeBeanCache();
|
||||
if (hitCache){
|
||||
Object ownerBean = bc.getOwnerBean();
|
||||
EntityBean ownerBean = bc.getOwnerBean();
|
||||
BeanDescriptor<? extends Object> parentDesc = desc.getBeanDescriptor(ownerBean.getClass());
|
||||
Object parentId = parentDesc.getId(ownerBean);
|
||||
if (parentDesc.cacheLoadMany(property, bc, parentId, parent.isReadOnly())) {
|
||||
|
||||
@@ -168,7 +168,7 @@ public final class BatchControl {
|
||||
// special case where the same bean instance has been added
|
||||
// to the batch more than once
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Bean instance already in this batch: " + request.getBean());
|
||||
logger.debug("Bean instance already in this batch: " + request.getEntityBean());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class BatchedBeanHolder {
|
||||
*/
|
||||
public ArrayList<PersistRequest> getList(PersistRequestBean<?> request) {
|
||||
|
||||
Integer objHashCode = Integer.valueOf(System.identityHashCode(request.getBean()));
|
||||
Integer objHashCode = Integer.valueOf(System.identityHashCode(request.getEntityBean()));
|
||||
|
||||
if (!beanHashCodes.add(objHashCode)) {
|
||||
// special case where the same bean instance has already been
|
||||
|
||||
@@ -2,19 +2,20 @@ package com.avaje.ebeaninternal.server.persist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.CallableSql;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.SqlUpdate;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.Update;
|
||||
import com.avaje.ebean.annotation.ConcurrencyMode;
|
||||
import com.avaje.ebean.bean.BeanCollection;
|
||||
import com.avaje.ebean.bean.BeanCollection.ModifyListenMode;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
@@ -38,8 +39,6 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.deploy.IntersectionRow;
|
||||
import com.avaje.ebeaninternal.server.deploy.ManyType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Persister implementation using DML.
|
||||
@@ -157,20 +156,18 @@ public final class DefaultPersister implements Persister {
|
||||
/**
|
||||
* Force an Update using the given bean.
|
||||
*/
|
||||
public void forceUpdate(Object bean, Set<String> updateProps, Transaction t, boolean deleteMissingChildren, boolean updateNullProperties) {
|
||||
public void forceUpdate(EntityBean bean, Set<String> updateProps, Transaction t, boolean deleteMissingChildren, boolean updateNullProperties) {
|
||||
|
||||
if (bean == null) {
|
||||
throw new NullPointerException(Message.msg("bean.isnull"));
|
||||
EntityBean entityBean = (EntityBean)bean;
|
||||
EntityBeanIntercept ebi = entityBean._ebean_getIntercept();
|
||||
if (ebi.isNew()) {
|
||||
ebi.setNewBeanForUpdate();
|
||||
}
|
||||
|
||||
if (updateProps == null) {
|
||||
// checking to see if this is just a 'normal' update
|
||||
if (bean instanceof EntityBean) {
|
||||
EntityBeanIntercept ebi = ((EntityBean) bean)._ebean_getIntercept();
|
||||
if (ebi.isDirty() || ebi.isLoaded()) {
|
||||
// a 'normal' update using 'dirty' properties from internal bean state.
|
||||
// if not dirty we still update in case any cascading save occurs
|
||||
PersistRequestBean<?> req = createRequest(bean, t, null);
|
||||
req.setStatelessUpdate(true, deleteMissingChildren, updateNullProperties);
|
||||
try {
|
||||
req.initTransIfRequired();
|
||||
update(req);
|
||||
@@ -182,76 +179,26 @@ public final class DefaultPersister implements Persister {
|
||||
req.rollbackTransIfRequired();
|
||||
throw ex;
|
||||
}
|
||||
|
||||
} else if (ebi.isReference()) {
|
||||
// just return as no point in cascading (no modified beans/lists)
|
||||
return;
|
||||
((SpiTransaction)t).logSql("-- No update as bean is just a reference bean");
|
||||
return;
|
||||
|
||||
} else {
|
||||
((SpiTransaction)t).logSql("-- No update as bean is not dirty");
|
||||
}
|
||||
|
||||
// loadedProps set by Ebean JSON / XML Marshalling
|
||||
updateProps = ebi.getLoadedProps();
|
||||
}
|
||||
}
|
||||
|
||||
BeanManager<?> mgr = getBeanManager(bean);
|
||||
if (mgr == null) {
|
||||
throw new PersistenceException(errNotRegistered(bean.getClass()));
|
||||
}
|
||||
|
||||
forceUpdateStateless(bean, t, null, mgr, updateProps, deleteMissingChildren, updateNullProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a 'stateless' update determining which properties to update.
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void forceUpdateStateless(Object bean, Transaction t, Object parentBean, BeanManager<?> mgr, Set<String> updateProps,
|
||||
boolean deleteMissingChildren, boolean updateNullProperties) {
|
||||
|
||||
BeanDescriptor<?> descriptor = mgr.getBeanDescriptor();
|
||||
|
||||
// determine concurrency mode based on version property not null
|
||||
ConcurrencyMode mode = descriptor.determineConcurrencyMode(bean);
|
||||
|
||||
if (updateProps == null) {
|
||||
// determine based on null treatment (all properties updated or just the non-null ones)
|
||||
updateProps = updateNullProperties ? null : descriptor.determineLoadedProperties(bean);
|
||||
|
||||
} else if (updateProps.isEmpty()) {
|
||||
// in this case means we want to include all properties in the update
|
||||
updateProps = null;
|
||||
|
||||
} else if (ConcurrencyMode.VERSION.equals(mode)) {
|
||||
// check that the version property is included
|
||||
String verName = descriptor.firstVersionProperty().getName();
|
||||
if (!updateProps.contains(verName)) {
|
||||
// defensively copy the updateProps and add the version property name
|
||||
updateProps = new HashSet<String>(updateProps);
|
||||
updateProps.add(verName);
|
||||
}
|
||||
}
|
||||
|
||||
PersistRequestBean<?> req = new PersistRequestBean(server, bean, parentBean, mgr, (SpiTransaction) t, persistExecute, updateProps, mode);
|
||||
req.setStatelessUpdate(true, deleteMissingChildren, updateNullProperties);
|
||||
|
||||
try {
|
||||
req.initTransIfRequired();
|
||||
update(req);
|
||||
req.commitTransIfRequired();
|
||||
|
||||
} catch (RuntimeException ex) {
|
||||
req.rollbackTransIfRequired();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void save(Object bean, Transaction t) {
|
||||
public void save(EntityBean bean, Transaction t) {
|
||||
saveRecurse(bean, t, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly specify to insert this bean.
|
||||
*/
|
||||
public void forceInsert(Object bean, Transaction t) {
|
||||
public void forceInsert(EntityBean bean, Transaction t) {
|
||||
|
||||
PersistRequestBean<?> req = createRequest(bean, t, null);
|
||||
try {
|
||||
@@ -324,7 +271,8 @@ public final class DefaultPersister implements Persister {
|
||||
|
||||
try {
|
||||
request.setType(PersistRequest.Type.INSERT);
|
||||
|
||||
request.setNotNullAsLoaded();
|
||||
|
||||
if (request.isPersistCascade()) {
|
||||
// save associated One beans recursively first
|
||||
saveAssocOne(request);
|
||||
@@ -383,7 +331,7 @@ public final class DefaultPersister implements Persister {
|
||||
/**
|
||||
* Delete the bean with the explicit transaction.
|
||||
*/
|
||||
public void delete(Object bean, Transaction t) {
|
||||
public void delete(EntityBean bean, Transaction t) {
|
||||
|
||||
PersistRequestBean<?> req = createRequest(bean, t, null);
|
||||
if (req.isRegisteredForDeleteBean()) {
|
||||
@@ -408,7 +356,7 @@ public final class DefaultPersister implements Persister {
|
||||
|
||||
private void deleteList(List<?> beanList, Transaction t) {
|
||||
for (int i = 0; i < beanList.size(); i++) {
|
||||
Object bean = beanList.get(i);
|
||||
EntityBean bean = (EntityBean)beanList.get(i);
|
||||
delete(bean, t);
|
||||
}
|
||||
}
|
||||
@@ -472,7 +420,7 @@ public final class DefaultPersister implements Persister {
|
||||
if (t.isLogSummary()) {
|
||||
t.logSummary("-- DeleteById of " + descriptor.getName() + " id[" + id + "] requires fetch of foreign key values");
|
||||
}
|
||||
Object bean = server.findUnique(q, t);
|
||||
EntityBean bean = (EntityBean)server.findUnique(q, t);
|
||||
if (bean == null) {
|
||||
return 0;
|
||||
} else {
|
||||
@@ -601,7 +549,7 @@ public final class DefaultPersister implements Persister {
|
||||
*/
|
||||
private void saveAssocMany(boolean insertedParent, PersistRequestBean<?> request) {
|
||||
|
||||
Object parentBean = request.getBean();
|
||||
EntityBean parentBean = request.getEntityBean();
|
||||
BeanDescriptor<?> desc = request.getBeanDescriptor();
|
||||
SpiTransaction t = request.getTransaction();
|
||||
|
||||
@@ -639,14 +587,14 @@ public final class DefaultPersister implements Persister {
|
||||
private static class SaveManyPropRequest {
|
||||
private final boolean insertedParent;
|
||||
private final BeanPropertyAssocMany<?> many;
|
||||
private final Object parentBean;
|
||||
private final EntityBean parentBean;
|
||||
private final SpiTransaction t;
|
||||
private final boolean cascade;
|
||||
private final boolean statelessUpdate;
|
||||
private final boolean deleteMissingChildren;
|
||||
private final boolean updateNullProperties;
|
||||
|
||||
private SaveManyPropRequest(boolean insertedParent, BeanPropertyAssocMany<?> many, Object parentBean, PersistRequestBean<?> request) {
|
||||
private SaveManyPropRequest(boolean insertedParent, BeanPropertyAssocMany<?> many, EntityBean parentBean, PersistRequestBean<?> request) {
|
||||
this.insertedParent = insertedParent;
|
||||
this.many = many;
|
||||
this.cascade = many.getCascadeInfo().isSave();
|
||||
@@ -657,7 +605,7 @@ public final class DefaultPersister implements Persister {
|
||||
this.updateNullProperties = request.isUpdateNullProperties();
|
||||
}
|
||||
|
||||
private SaveManyPropRequest(BeanPropertyAssocMany<?> many, Object parentBean, SpiTransaction t) {
|
||||
private SaveManyPropRequest(BeanPropertyAssocMany<?> many, EntityBean parentBean, SpiTransaction t) {
|
||||
this.insertedParent = false;
|
||||
this.many = many;
|
||||
this.parentBean = parentBean;
|
||||
@@ -700,7 +648,7 @@ public final class DefaultPersister implements Persister {
|
||||
return many;
|
||||
}
|
||||
|
||||
private Object getParentBean() {
|
||||
private EntityBean getParentBean() {
|
||||
return parentBean;
|
||||
}
|
||||
|
||||
@@ -800,7 +748,7 @@ public final class DefaultPersister implements Persister {
|
||||
// set it to the appropriate property on the
|
||||
// detail bean before we save it
|
||||
boolean isMap = ManyType.JAVA_MAP.equals(prop.getManyType());
|
||||
Object parentBean = saveMany.getParentBean();
|
||||
EntityBean parentBean = (EntityBean)saveMany.getParentBean();
|
||||
Object mapKeyValue = null;
|
||||
|
||||
boolean saveSkippable = prop.isSaveRecurseSkippable();
|
||||
@@ -814,59 +762,58 @@ public final class DefaultPersister implements Persister {
|
||||
detailBean = entry.getValue();
|
||||
}
|
||||
|
||||
if (prop.isManyToMany()) {
|
||||
if (detailBean instanceof EntityBean) {
|
||||
skipSavingThisBean = ((EntityBean) detailBean)._ebean_getIntercept().isReference();
|
||||
}
|
||||
if (detailBean instanceof EntityBean == false) {
|
||||
skipSavingThisBean = true;
|
||||
logger.debug("Skip non entity bean");
|
||||
|
||||
} else {
|
||||
// set the 'parent/master' bean to the detailBean as long
|
||||
// as we don't make it 'dirty' in doing so
|
||||
if (detailBean instanceof EntityBean) {
|
||||
EntityBeanIntercept ebi = ((EntityBean) detailBean)._ebean_getIntercept();
|
||||
if (ebi.isNewOrDirty()) {
|
||||
// set the parent bean to detailBean
|
||||
prop.setJoinValuesToChild(parentBean, detailBean, mapKeyValue);
|
||||
} else if (ebi.isReference()) {
|
||||
// we can skip this one
|
||||
skipSavingThisBean = true;
|
||||
EntityBean detail = (EntityBean)detailBean;
|
||||
if (prop.isManyToMany()) {
|
||||
skipSavingThisBean = detail._ebean_getIntercept().isReference();
|
||||
} else {
|
||||
EntityBeanIntercept ebi = detail._ebean_getIntercept();
|
||||
if (ebi.isNewOrDirty()) {
|
||||
skipSavingThisBean = false;
|
||||
// set the parent bean to detailBean
|
||||
prop.setJoinValuesToChild(parentBean, detail, mapKeyValue);
|
||||
|
||||
} else if (ebi.isReference()) {
|
||||
// we can skip this one
|
||||
skipSavingThisBean = true;
|
||||
|
||||
} else {
|
||||
// unmodified so skip depending on prop.isSaveRecurseSkippable();
|
||||
skipSavingThisBean = saveSkippable;
|
||||
}
|
||||
} else {
|
||||
// set the parent bean to detailBean
|
||||
prop.setJoinValuesToChild(parentBean, detailBean, mapKeyValue);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// unmodified so skip depending on prop.isSaveRecurseSkippable();
|
||||
skipSavingThisBean = saveSkippable;
|
||||
}
|
||||
}
|
||||
|
||||
if (skipSavingThisBean) {
|
||||
// unmodified bean that does not recurse its save
|
||||
// so we can skip the save for this bean.
|
||||
// Reset skipSavingThisBean for the next detailBean
|
||||
skipSavingThisBean = false;
|
||||
if (skipSavingThisBean) {
|
||||
// unmodified bean that does not recurse its save
|
||||
// so we can skip the save for this bean.
|
||||
// Reset skipSavingThisBean for the next detailBean
|
||||
skipSavingThisBean = false;
|
||||
|
||||
} else if (!saveMany.isStatelessUpdate()) {
|
||||
// normal save recurse
|
||||
saveRecurse(detailBean, t, parentBean);
|
||||
} else if (!saveMany.isStatelessUpdate()) {
|
||||
// normal save recurse
|
||||
saveRecurse(detailBean, t, parentBean);
|
||||
|
||||
} else {
|
||||
if (targetDescriptor.isStatelessUpdate(detailBean)) {
|
||||
// update based on the value of Version/Id properties
|
||||
// cascade update in stateless mode
|
||||
forceUpdate(detailBean, null, t, deleteMissingChildren, updateNullProperties);
|
||||
} else {
|
||||
// cascade insert
|
||||
forceInsert(detailBean, t);
|
||||
}
|
||||
}
|
||||
|
||||
if (detailIds != null) {
|
||||
// remember the Id (other details not in the collection) will be removed
|
||||
Object id = targetDescriptor.getId(detailBean);
|
||||
if (!DmlUtil.isNullOrZero(id)) {
|
||||
detailIds.add(id);
|
||||
}
|
||||
} else {
|
||||
if (targetDescriptor.isStatelessUpdate(detail)) {
|
||||
// update based on the value of Version/Id properties
|
||||
// cascade update in stateless mode
|
||||
forceUpdate(detail, null, t, deleteMissingChildren, updateNullProperties);
|
||||
} else {
|
||||
// cascade insert
|
||||
forceInsert(detail, t);
|
||||
}
|
||||
}
|
||||
if (detailIds != null) {
|
||||
// remember the Id (other details not in the collection) will be removed
|
||||
Object id = targetDescriptor.getId(detail);
|
||||
if (!DmlUtil.isNullOrZero(id)) {
|
||||
detailIds.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -878,14 +825,14 @@ public final class DefaultPersister implements Persister {
|
||||
|
||||
}
|
||||
|
||||
public int deleteManyToManyAssociations(Object ownerBean, String propertyName, Transaction t) {
|
||||
public int deleteManyToManyAssociations(EntityBean ownerBean, String propertyName, Transaction t) {
|
||||
|
||||
BeanDescriptor<?> descriptor = beanDescriptorManager.getBeanDescriptor(ownerBean.getClass());
|
||||
BeanPropertyAssocMany<?> prop = (BeanPropertyAssocMany<?>) descriptor.getBeanProperty(propertyName);
|
||||
return deleteAssocManyIntersection(ownerBean, prop, t);
|
||||
}
|
||||
|
||||
public void saveManyToManyAssociations(Object ownerBean, String propertyName, Transaction t) {
|
||||
public void saveManyToManyAssociations(EntityBean ownerBean, String propertyName, Transaction t) {
|
||||
|
||||
BeanDescriptor<?> descriptor = beanDescriptorManager.getBeanDescriptor(ownerBean.getClass());
|
||||
BeanPropertyAssocMany<?> prop = (BeanPropertyAssocMany<?>) descriptor.getBeanProperty(propertyName);
|
||||
@@ -893,7 +840,7 @@ public final class DefaultPersister implements Persister {
|
||||
saveAssocManyIntersection(new SaveManyPropRequest(prop, ownerBean, (SpiTransaction) t), false);
|
||||
}
|
||||
|
||||
public void saveAssociation(Object parentBean, String propertyName, Transaction t) {
|
||||
public void saveAssociation(EntityBean parentBean, String propertyName, Transaction t) {
|
||||
|
||||
BeanDescriptor<?> descriptor = beanDescriptorManager.getBeanDescriptor(parentBean.getClass());
|
||||
SpiTransaction trans = (SpiTransaction) t;
|
||||
@@ -978,7 +925,8 @@ public final class DefaultPersister implements Persister {
|
||||
t.depth(+1);
|
||||
|
||||
if (additions != null && !additions.isEmpty()) {
|
||||
for (Object otherBean : additions) {
|
||||
for (Object other : additions) {
|
||||
EntityBean otherBean = (EntityBean)other;
|
||||
// the object from the 'other' side of the ManyToMany
|
||||
if (deletions != null && deletions.remove(otherBean)) {
|
||||
String m = "Inserting and Deleting same object? " + otherBean;
|
||||
@@ -1002,7 +950,8 @@ public final class DefaultPersister implements Persister {
|
||||
}
|
||||
}
|
||||
if (deletions != null && !deletions.isEmpty()) {
|
||||
for (Object otherDelete : deletions) {
|
||||
for (Object other : deletions) {
|
||||
EntityBean otherDelete = (EntityBean)other;
|
||||
// the object from the 'other' side of the ManyToMany
|
||||
// build a intersection row for 'delete'
|
||||
IntersectionRow intRow = prop.buildManyToManyMapBean(saveManyPropRequest.getParentBean(), otherDelete);
|
||||
@@ -1015,7 +964,7 @@ public final class DefaultPersister implements Persister {
|
||||
t.depth(-1);
|
||||
}
|
||||
|
||||
private int deleteAssocManyIntersection(Object bean, BeanPropertyAssocMany<?> many, Transaction t) {
|
||||
private int deleteAssocManyIntersection(EntityBean bean, BeanPropertyAssocMany<?> many, Transaction t) {
|
||||
|
||||
// delete all intersection rows for this bean
|
||||
IntersectionRow intRow = many.buildManyToManyDeleteChildren(bean);
|
||||
@@ -1036,7 +985,7 @@ public final class DefaultPersister implements Persister {
|
||||
t.depth(-1);
|
||||
|
||||
BeanDescriptor<?> desc = request.getBeanDescriptor();
|
||||
Object parentBean = request.getBean();
|
||||
EntityBean parentBean = request.getEntityBean();
|
||||
|
||||
BeanPropertyAssocOne<?>[] expOnes = desc.propertiesOneExportedDelete();
|
||||
if (expOnes.length > 0) {
|
||||
@@ -1079,7 +1028,8 @@ public final class DefaultPersister implements Persister {
|
||||
if (modifyRemovals != null && !modifyRemovals.isEmpty()) {
|
||||
|
||||
// delete the orphans that have been removed from the collection
|
||||
for (Object detailBean : modifyRemovals) {
|
||||
for (Object detail : modifyRemovals) {
|
||||
EntityBean detailBean = (EntityBean)detail;
|
||||
if (manys[i].hasId(detailBean)) {
|
||||
deleteRecurse(detailBean, t);
|
||||
}
|
||||
@@ -1104,7 +1054,7 @@ public final class DefaultPersister implements Persister {
|
||||
* collection (and should not be deleted).
|
||||
* </p>
|
||||
*/
|
||||
private void deleteManyDetails(SpiTransaction t, BeanDescriptor<?> desc, Object parentBean,
|
||||
private void deleteManyDetails(SpiTransaction t, BeanDescriptor<?> desc, EntityBean parentBean,
|
||||
BeanPropertyAssocMany<?> many, ArrayList<Object> excludeDetailIds) {
|
||||
|
||||
if (many.getCascadeInfo().isDelete()) {
|
||||
@@ -1142,7 +1092,7 @@ public final class DefaultPersister implements Persister {
|
||||
|
||||
// check for partial objects
|
||||
if (request.isLoadedProperty(prop)) {
|
||||
Object detailBean = prop.getValue(request.getBean());
|
||||
Object detailBean = prop.getValue(request.getEntityBean());
|
||||
if (detailBean != null) {
|
||||
if (isReference(detailBean)) {
|
||||
// skip saving a reference
|
||||
@@ -1206,9 +1156,12 @@ public final class DefaultPersister implements Persister {
|
||||
// handled by DeleteUnloadedForeignKeys that was built
|
||||
// via getDeleteUnloadedForeignKeys();
|
||||
} else {
|
||||
Object detailBean = prop.getValue(request.getBean());
|
||||
if (detailBean != null && prop.hasId(detailBean)) {
|
||||
deleteRecurse(detailBean, request.getTransaction());
|
||||
Object detailBean = prop.getValue(request.getEntityBean());
|
||||
if (detailBean != null) {
|
||||
EntityBean detail = (EntityBean)detailBean;
|
||||
if (prop.hasId(detail)) {
|
||||
deleteRecurse(detail, request.getTransaction());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1230,7 +1183,7 @@ public final class DefaultPersister implements Persister {
|
||||
return;
|
||||
}
|
||||
|
||||
Object bean = request.getBean();
|
||||
EntityBean bean = request.getEntityBean();
|
||||
Object uid = idProp.getValue(bean);
|
||||
|
||||
if (DmlUtil.isNullOrZero(uid)) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.persist;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
@@ -29,7 +30,7 @@ public class DeleteUnloadedForeignKeys {
|
||||
|
||||
private final PersistRequestBean<?> request;
|
||||
|
||||
private Object beanWithForeignKeys;
|
||||
private EntityBean beanWithForeignKeys;
|
||||
|
||||
public DeleteUnloadedForeignKeys(SpiEbeanServer server, PersistRequestBean<?> request) {
|
||||
this.server = server;
|
||||
@@ -70,7 +71,7 @@ public class DeleteUnloadedForeignKeys {
|
||||
if (t.isLogSummary()) {
|
||||
t.logSummary("-- Ebean fetching foreign key values for delete of " + descriptor.getName() + " id:" + id);
|
||||
}
|
||||
beanWithForeignKeys = server.findUnique(q, t);
|
||||
beanWithForeignKeys = (EntityBean)server.findUnique(q, t);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +85,7 @@ public class DeleteUnloadedForeignKeys {
|
||||
Object detailBean = prop.getValue(beanWithForeignKeys);
|
||||
|
||||
// if bean exists with a unique id then delete it
|
||||
if (detailBean != null && prop.hasId(detailBean)) {
|
||||
if (detailBean != null && prop.hasId((EntityBean)detailBean)) {
|
||||
server.delete(detailBean, request.getTransaction());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,19 +53,9 @@ public class DeleteHandler extends DmlHandler {
|
||||
int rowCount = dataBind.executeUpdate();
|
||||
checkRowCount(rowCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncluded(BeanProperty prop) {
|
||||
return prop.isDbUpdatable() && super.isIncluded(prop);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludedWhere(BeanProperty prop) {
|
||||
return prop.isDbUpdatable() && (loadedProps == null || loadedProps.contains(prop.getName()));
|
||||
}
|
||||
|
||||
public void registerDerivedRelationship(DerivedRelationshipData assocBean) {
|
||||
throw new RuntimeException("Never called on delete");
|
||||
}
|
||||
public void registerDerivedRelationship(DerivedRelationshipData assocBean) {
|
||||
throw new RuntimeException("Never called on delete");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.avaje.ebeaninternal.server.persist.dml;
|
||||
|
||||
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.core.PersistRequestBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.persist.dmlbind.Bindable;
|
||||
@@ -23,21 +23,17 @@ public final class DeleteMeta {
|
||||
|
||||
private final Bindable version;
|
||||
|
||||
private final Bindable all;
|
||||
|
||||
private final String tableName;
|
||||
|
||||
private final boolean emptyStringAsNull;
|
||||
|
||||
public DeleteMeta(boolean emptyStringAsNull, BeanDescriptor<?> desc, BindableId id, Bindable version, Bindable all) {
|
||||
public DeleteMeta(boolean emptyStringAsNull, BeanDescriptor<?> desc, BindableId id, Bindable version) {
|
||||
this.emptyStringAsNull = emptyStringAsNull;
|
||||
this.tableName = desc.getBaseTable();
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.all = all;
|
||||
|
||||
sqlNone = genSql(ConcurrencyMode.NONE);
|
||||
sqlVersion = genSql(ConcurrencyMode.VERSION);
|
||||
this.sqlNone = genSql(ConcurrencyMode.NONE);
|
||||
this.sqlVersion = genSql(ConcurrencyMode.VERSION);
|
||||
}
|
||||
|
||||
public boolean isEmptyStringAsNull() {
|
||||
@@ -56,18 +52,13 @@ public final class DeleteMeta {
|
||||
*/
|
||||
public void bind(PersistRequestBean<?> persist, DmlHandler bind) throws SQLException {
|
||||
|
||||
Object bean = persist.getBean();
|
||||
EntityBean bean = persist.getEntityBean();
|
||||
|
||||
id.dmlBind(bind, false, bean);
|
||||
id.dmlBind(bind, bean);
|
||||
|
||||
switch (persist.getConcurrencyMode()) {
|
||||
case VERSION:
|
||||
version.dmlBind(bind, false, bean);
|
||||
break;
|
||||
|
||||
case ALL:
|
||||
Object oldBean = persist.getOldValues();
|
||||
all.dmlBindWhere(bind, true, oldBean);
|
||||
version.dmlBind(bind, bean);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -91,9 +82,6 @@ public final class DeleteMeta {
|
||||
case VERSION:
|
||||
return sqlVersion;
|
||||
|
||||
case ALL:
|
||||
return genDynamicWhere(request.getLoadedProperties(), request.getOldValues());
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Invalid mode " + request.determineConcurrencyMode());
|
||||
}
|
||||
@@ -109,37 +97,15 @@ public final class DeleteMeta {
|
||||
request.append(" where ");
|
||||
|
||||
request.setWhereIdMode();
|
||||
id.dmlAppend(request, false);
|
||||
id.dmlAppend(request);
|
||||
|
||||
if (ConcurrencyMode.VERSION.equals(conMode)) {
|
||||
if (version == null) {
|
||||
return null;
|
||||
}
|
||||
version.dmlAppend(request, false);
|
||||
|
||||
} else if (ConcurrencyMode.ALL.equals(conMode)) {
|
||||
throw new RuntimeException("Never called for ConcurrencyMode.ALL");
|
||||
version.dmlAppend(request);
|
||||
}
|
||||
|
||||
return request.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the sql dynamically for where using IS NULL for binding null
|
||||
* values.
|
||||
*/
|
||||
private String genDynamicWhere(Set<String> includedProps, Object oldBean) throws SQLException {
|
||||
|
||||
// always has a preceding id property(s) so the first
|
||||
// option is always ' and ' and not blank.
|
||||
|
||||
GenerateDmlRequest request = new GenerateDmlRequest(emptyStringAsNull, includedProps, oldBean);
|
||||
|
||||
request.append(sqlNone);
|
||||
|
||||
request.setWhereMode();
|
||||
all.dmlWhere(request, true, oldBean);
|
||||
|
||||
|
||||
return request.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,13 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequestBean;
|
||||
import com.avaje.ebeaninternal.server.core.PstmtBatch;
|
||||
@@ -18,8 +20,6 @@ import com.avaje.ebeaninternal.server.persist.BatchedPstmtHolder;
|
||||
import com.avaje.ebeaninternal.server.persist.dmlbind.BindableRequest;
|
||||
import com.avaje.ebeaninternal.server.transaction.TransactionManager;
|
||||
import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Base class for Handler implementations.
|
||||
@@ -35,8 +35,6 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
|
||||
protected final StringBuilder bindLog;
|
||||
|
||||
protected final Set<String> loadedProps;
|
||||
|
||||
protected final SpiTransaction transaction;
|
||||
|
||||
protected final boolean emptyStringToNull;
|
||||
@@ -52,12 +50,9 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
|
||||
protected ArrayList<UpdateGenValue> updateGenValues;
|
||||
|
||||
private Set<String> additionalProps;
|
||||
|
||||
protected DmlHandler(PersistRequestBean<?> persistRequest, boolean emptyStringToNull) {
|
||||
this.persistRequest = persistRequest;
|
||||
this.emptyStringToNull = emptyStringToNull;
|
||||
this.loadedProps = persistRequest.getLoadedProperties();
|
||||
this.transaction = persistRequest.getTransaction();
|
||||
this.logLevelSql = transaction.isLogSql();
|
||||
if (logLevelSql) {
|
||||
@@ -148,20 +143,6 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIncluded(BeanProperty prop) {
|
||||
return (loadedProps == null || loadedProps.contains(prop.getName()));
|
||||
}
|
||||
|
||||
public boolean isIncludedWhere(BeanProperty prop) {
|
||||
if (prop.isDbEncrypted()) {
|
||||
// update without a version property ...
|
||||
// for encrypted properties only include if it was
|
||||
// also an updated/modified property
|
||||
return isIncluded(prop);
|
||||
}
|
||||
return prop.isDbUpdatable() && (loadedProps == null || loadedProps.contains(prop.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind a raw value. Used to bind the discriminator column.
|
||||
*/
|
||||
@@ -194,80 +175,36 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
/**
|
||||
* Bind the value to the preparedStatement.
|
||||
*/
|
||||
public Object bind(Object value, BeanProperty prop, String propName, boolean bindNull)
|
||||
throws SQLException {
|
||||
return bindInternal(logLevelSql, value, prop, propName, bindNull);
|
||||
public Object bind(Object value, BeanProperty prop, String propName) throws SQLException {
|
||||
return bindInternal(logLevelSql, value, prop, propName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the value to the preparedStatement without logging.
|
||||
*/
|
||||
public Object bindNoLog(Object value, BeanProperty prop, String propName, boolean bindNull)
|
||||
throws SQLException {
|
||||
return bindInternal(false, value, prop, propName, bindNull);
|
||||
public Object bindNoLog(Object value, BeanProperty prop, String propName) throws SQLException {
|
||||
return bindInternal(false, value, prop, propName);
|
||||
}
|
||||
|
||||
private Object bindInternal(boolean log, Object value, BeanProperty prop, String propName,
|
||||
boolean bindNull) throws SQLException {
|
||||
private Object bindInternal(boolean log, Object value, BeanProperty prop, String propName) throws SQLException {
|
||||
|
||||
if (!bindNull) {
|
||||
if (emptyStringToNull && (value instanceof String) && ((String) value).length() == 0) {
|
||||
// support Oracle conversion of empty string to null
|
||||
// value = prop.getDbNullValue(value);
|
||||
value = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bindNull && value == null) {
|
||||
// where will have IS NULL clause so don't actually bind
|
||||
if (log) {
|
||||
bindLog.append("null, ");
|
||||
}
|
||||
} else {
|
||||
if (log) {
|
||||
if (prop.isLob()) {
|
||||
bindLog.append("[LOB]");
|
||||
} else {
|
||||
String sv = String.valueOf(value);
|
||||
if (sv.length() > 50) {
|
||||
sv = sv.substring(0, 47) + "...";
|
||||
}
|
||||
bindLog.append(sv);
|
||||
if (log) {
|
||||
if (prop.isLob()) {
|
||||
bindLog.append("[LOB]");
|
||||
} else {
|
||||
String sv = String.valueOf(value);
|
||||
if (sv.length() > 50) {
|
||||
sv = sv.substring(0, 47) + "...";
|
||||
}
|
||||
bindLog.append(",");
|
||||
bindLog.append(sv);
|
||||
}
|
||||
// do the actual binding to PreparedStatement
|
||||
prop.bind(dataBind, value);
|
||||
bindLog.append(",");
|
||||
}
|
||||
// do the actual binding to PreparedStatement
|
||||
prop.bind(dataBind, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* For generated properties set on insert register as additional loaded
|
||||
* properties if required.
|
||||
*/
|
||||
public final void registerAdditionalProperty(String propertyName) {
|
||||
if (loadedProps != null && !loadedProps.contains(propertyName)) {
|
||||
if (additionalProps == null) {
|
||||
additionalProps = new HashSet<String>();
|
||||
}
|
||||
additionalProps.add(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set any additional (generated) properties to the set of loaded properties
|
||||
* if required.
|
||||
*/
|
||||
protected void setAdditionalProperties() {
|
||||
if (additionalProps != null) {
|
||||
// additional generated properties set on insert
|
||||
// added to the set of loaded properties
|
||||
additionalProps.addAll(loadedProps);
|
||||
persistRequest.setLoadedProps(additionalProps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a generated value on a update. This can not be set to the bean
|
||||
* until after the where clause has been bound for concurrency checking.
|
||||
@@ -277,12 +214,11 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
* generation.
|
||||
* </p>
|
||||
*/
|
||||
public void registerUpdateGenValue(BeanProperty prop, Object bean, Object value) {
|
||||
public void registerUpdateGenValue(BeanProperty prop, EntityBean bean, Object value) {
|
||||
if (updateGenValues == null) {
|
||||
updateGenValues = new ArrayList<UpdateGenValue>();
|
||||
}
|
||||
updateGenValues.add(new UpdateGenValue(prop, bean, value));
|
||||
registerAdditionalProperty(prop.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,6 +239,7 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
*/
|
||||
protected PreparedStatement getPstmt(SpiTransaction t, String sql, boolean genKeys)
|
||||
throws SQLException {
|
||||
|
||||
Connection conn = t.getInternalConnection();
|
||||
if (genKeys) {
|
||||
// the Id generated is always the first column
|
||||
@@ -353,11 +290,11 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest {
|
||||
|
||||
private final BeanProperty property;
|
||||
|
||||
private final Object bean;
|
||||
private final EntityBean bean;
|
||||
|
||||
private final Object value;
|
||||
|
||||
private UpdateGenValue(BeanProperty property, Object bean, Object value) {
|
||||
private UpdateGenValue(BeanProperty property, EntityBean bean, Object value) {
|
||||
this.property = property;
|
||||
this.bean = bean;
|
||||
this.value = value;
|
||||
|
||||
@@ -15,8 +15,4 @@ public enum DmlMode {
|
||||
*/
|
||||
UPDATE,
|
||||
|
||||
/**
|
||||
* The Update or Delete WHERE.
|
||||
*/
|
||||
WHERE
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.persist.dml;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBeanIntercept;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
|
||||
/**
|
||||
@@ -15,10 +14,8 @@ public class GenerateDmlRequest {
|
||||
|
||||
private final StringBuilder sb = new StringBuilder(100);
|
||||
|
||||
private final Set<String> includeProps;
|
||||
private final Set<String> includeWhereProps;
|
||||
|
||||
private final Object oldValues;
|
||||
private final EntityBeanIntercept ebi;
|
||||
private final boolean changesOnly;
|
||||
|
||||
private StringBuilder insertBindBuffer;
|
||||
|
||||
@@ -28,29 +25,21 @@ public class GenerateDmlRequest {
|
||||
private int insertMode;
|
||||
|
||||
private int bindColumnCount;
|
||||
|
||||
/**
|
||||
* Create with includeWhereProps same as includeProps.
|
||||
*/
|
||||
public GenerateDmlRequest(boolean emptyStringAsNull, Set<String> includeProps, Object oldValues) {
|
||||
this(emptyStringAsNull, includeProps, includeProps, oldValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from a PersistRequestBean.
|
||||
*/
|
||||
public GenerateDmlRequest(boolean emptyStringAsNull, Set<String> includeProps, Set<String> includeWhereProps, Object oldValues) {
|
||||
public GenerateDmlRequest(boolean emptyStringAsNull, EntityBeanIntercept ebi, boolean changesOnly) {//, Object oldValues) {
|
||||
this.emptyStringAsNull = emptyStringAsNull;
|
||||
this.includeProps = includeProps;
|
||||
this.includeWhereProps = includeWhereProps;
|
||||
this.oldValues = oldValues;
|
||||
this.ebi = ebi;
|
||||
this.changesOnly = changesOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create for generating standard all properties DML/SQL.
|
||||
*/
|
||||
public GenerateDmlRequest(boolean emptyStringAsNull) {
|
||||
this(emptyStringAsNull, null, null, null);
|
||||
this(emptyStringAsNull, null, false);
|
||||
}
|
||||
|
||||
public GenerateDmlRequest append(String s) {
|
||||
@@ -66,14 +55,21 @@ public class GenerateDmlRequest {
|
||||
* Return true if this property should be included in the set clause.
|
||||
*/
|
||||
public boolean isIncluded(BeanProperty prop) {
|
||||
return (includeProps == null || includeProps.contains(prop.getName()));
|
||||
if (ebi == null) {
|
||||
return true;
|
||||
}
|
||||
if (changesOnly) {
|
||||
return ebi.isChangedProperty(prop.getPropertyIndex());
|
||||
} else {
|
||||
return ebi.isLoadedProperty(prop.getPropertyIndex());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this property should be included in the where clause.
|
||||
*/
|
||||
public boolean isIncludedWhere(BeanProperty prop) {
|
||||
return (includeWhereProps == null || includeWhereProps.contains(prop.getName()));
|
||||
return ebi == null || ebi.isLoadedProperty(prop.getPropertyIndex());
|
||||
}
|
||||
|
||||
public void appendColumnIsNull(String column) {
|
||||
@@ -81,28 +77,29 @@ public class GenerateDmlRequest {
|
||||
}
|
||||
|
||||
public void appendColumn(String column) {
|
||||
String bind = (insertMode > 0) ? "?" : "=?";
|
||||
appendColumn(column, bind);
|
||||
//String bind = (insertMode > 0) ? "?" : "=?";
|
||||
appendColumn(column, "?");
|
||||
}
|
||||
|
||||
public void appendColumn(String column, String suffik) {
|
||||
appendColumn(column, "", suffik);
|
||||
public void appendColumn(String column, String bind) {
|
||||
appendColumn(column, "", bind);
|
||||
}
|
||||
|
||||
public void appendColumn(String column, String expr, String suffik) {
|
||||
public void appendColumn(String column, String expr, String bind) {
|
||||
|
||||
++bindColumnCount;
|
||||
|
||||
sb.append(prefix);
|
||||
sb.append(column);
|
||||
sb.append(expr);
|
||||
//sb.append(expr);
|
||||
if (insertMode > 0) {
|
||||
if (insertMode++ > 1) {
|
||||
insertBindBuffer.append(",");
|
||||
}
|
||||
insertBindBuffer.append(suffik);
|
||||
insertBindBuffer.append(bind);
|
||||
} else {
|
||||
sb.append(suffik);
|
||||
sb.append("=");
|
||||
sb.append(bind);
|
||||
}
|
||||
|
||||
if (prefix2 != null) {
|
||||
@@ -145,8 +142,4 @@ public class GenerateDmlRequest {
|
||||
this.prefix2 = ", ";
|
||||
}
|
||||
|
||||
public Object getOldValues() {
|
||||
return oldValues;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,14 +5,17 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.DerivedRelationshipData;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
import com.avaje.ebeaninternal.server.core.Message;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequestBean;
|
||||
@@ -20,8 +23,6 @@ import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.persist.DmlUtil;
|
||||
import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Insert bean handler.
|
||||
@@ -59,18 +60,13 @@ public class InsertHandler extends DmlHandler {
|
||||
this.concatinatedKey = meta.isConcatinatedKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncluded(BeanProperty prop) {
|
||||
return prop.isDbInsertable() && (super.isIncluded(prop));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and bind the insert statement.
|
||||
*/
|
||||
public void bind() throws SQLException {
|
||||
|
||||
BeanDescriptor<?> desc = persistRequest.getBeanDescriptor();
|
||||
Object bean = persistRequest.getBean();
|
||||
EntityBean bean = persistRequest.getEntityBean();
|
||||
|
||||
Object idValue = desc.getId(bean);
|
||||
|
||||
@@ -142,20 +138,28 @@ public class InsertHandler extends DmlHandler {
|
||||
}
|
||||
|
||||
checkRowCount(rc);
|
||||
setAdditionalProperties();
|
||||
//setAdditionalProperties();
|
||||
executeDerivedRelationships();
|
||||
|
||||
persistRequest.postInsert();
|
||||
}
|
||||
|
||||
protected void executeDerivedRelationships() {
|
||||
List<DerivedRelationshipData> derivedRelationships = persistRequest.getDerivedRelationships();
|
||||
if (derivedRelationships != null) {
|
||||
|
||||
SpiEbeanServer ebeanServer = (SpiEbeanServer)persistRequest.getEbeanServer();
|
||||
|
||||
for (int i = 0; i < derivedRelationships.size(); i++) {
|
||||
DerivedRelationshipData derivedRelationshipData = derivedRelationships.get(i);
|
||||
|
||||
EbeanServer ebeanServer = persistRequest.getEbeanServer();
|
||||
HashSet<String> updateProps = new HashSet<String>();
|
||||
updateProps.add(derivedRelationshipData.getLogicalName());
|
||||
ebeanServer.update(derivedRelationshipData.getBean(), updateProps, transaction, false, true);
|
||||
BeanDescriptor<?> beanDescriptor = ebeanServer.getBeanDescriptor(derivedRelationshipData.getBean().getClass());
|
||||
|
||||
BeanProperty prop = beanDescriptor.getBeanProperty(derivedRelationshipData.getLogicalName());
|
||||
EntityBean entityBean = (EntityBean)derivedRelationshipData.getBean();
|
||||
entityBean._ebean_getIntercept().markPropertyAsChanged(prop.getPropertyIndex());
|
||||
|
||||
ebeanServer.update(entityBean, transaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.avaje.ebeaninternal.server.persist.dml;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Set;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequestBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -53,7 +53,7 @@ public final class InsertMeta {
|
||||
this.all = all;
|
||||
this.shadowFKey = shadowFKey;
|
||||
|
||||
this.sqlWithId = genSql(false, null);
|
||||
this.sqlWithId = genSql(false);
|
||||
|
||||
// only available for single Id property
|
||||
if (id.isConcatenated()) {
|
||||
@@ -68,7 +68,7 @@ public final class InsertMeta {
|
||||
// insert sql for db identity or sequence insert
|
||||
this.concatinatedKey = false;
|
||||
this.identityDbColumns = new String[]{id.getIdentityColumn()};
|
||||
this.sqlNullId = genSql(true, null);
|
||||
this.sqlNullId = genSql(true);
|
||||
this.supportsGetGeneratedKeys = dbPlatform.getDbIdentity().isSupportsGetGeneratedKeys();
|
||||
this.selectLastInsertedId = desc.getSelectLastInsertedId();
|
||||
}
|
||||
@@ -131,18 +131,18 @@ public final class InsertMeta {
|
||||
/**
|
||||
* Bind the request based on whether the id value(s) are null.
|
||||
*/
|
||||
public void bind(DmlHandler request, Object bean, boolean withId) throws SQLException {
|
||||
public void bind(DmlHandler request, EntityBean bean, boolean withId) throws SQLException {
|
||||
|
||||
if (withId) {
|
||||
id.dmlBind(request, false, bean);
|
||||
id.dmlBind(request, bean);
|
||||
}
|
||||
if (shadowFKey != null){
|
||||
shadowFKey.dmlBind(request, false, bean);
|
||||
shadowFKey.dmlBind(request, bean);
|
||||
}
|
||||
if (discriminator != null){
|
||||
discriminator.dmlBind(request, false, bean);
|
||||
discriminator.dmlBind(request, bean);
|
||||
}
|
||||
all.dmlBind(request, false, bean);
|
||||
all.dmlBind(request, bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,27 +157,27 @@ public final class InsertMeta {
|
||||
}
|
||||
}
|
||||
|
||||
private String genSql(boolean nullId, Set<String> loadedProps) {
|
||||
private String genSql(boolean nullId) {
|
||||
|
||||
GenerateDmlRequest request = new GenerateDmlRequest(emptyStringToNull, loadedProps, null);
|
||||
GenerateDmlRequest request = new GenerateDmlRequest(emptyStringToNull, null, true);
|
||||
request.setInsertSetMode();
|
||||
|
||||
request.append("insert into ").append(tableName);
|
||||
request.append(" (");
|
||||
|
||||
if (!nullId) {
|
||||
id.dmlInsert(request, false);
|
||||
id.dmlAppend(request);
|
||||
}
|
||||
|
||||
if (shadowFKey != null){
|
||||
shadowFKey.dmlInsert(request, false);
|
||||
shadowFKey.dmlAppend(request);
|
||||
}
|
||||
|
||||
if (discriminator != null){
|
||||
discriminator.dmlInsert(request, false);
|
||||
discriminator.dmlAppend(request);
|
||||
}
|
||||
|
||||
all.dmlInsert(request, false);
|
||||
all.dmlAppend(request);
|
||||
|
||||
request.append(") values (");
|
||||
request.append(request.getInsertBindBuffer());
|
||||
|
||||
@@ -66,16 +66,9 @@ public class MetaFactory {
|
||||
|
||||
Bindable ver = versionFact.create(desc);
|
||||
|
||||
List<Bindable> allList = new ArrayList<Bindable>();
|
||||
|
||||
baseFact.create(allList, desc, DmlMode.WHERE, false);
|
||||
embeddedFact.create(allList, desc, DmlMode.WHERE, false);
|
||||
assocOneFact.create(allList, desc, DmlMode.WHERE);
|
||||
|
||||
BindableList setBindable = new BindableList(setList);
|
||||
BindableList allBindable = new BindableList(allList);
|
||||
|
||||
return new UpdateMeta(emptyStringAsNull, desc, setBindable, id, ver, allBindable);
|
||||
return new UpdateMeta(emptyStringAsNull, desc, setBindable, id, ver);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,15 +80,7 @@ public class MetaFactory {
|
||||
|
||||
Bindable ver = versionFact.create(desc);
|
||||
|
||||
List<Bindable> allList = new ArrayList<Bindable>();
|
||||
|
||||
baseFact.create(allList, desc, DmlMode.WHERE, false);
|
||||
embeddedFact.create(allList, desc, DmlMode.WHERE, false);
|
||||
assocOneFact.create(allList, desc, DmlMode.WHERE);
|
||||
|
||||
Bindable allBindable = new BindableList(allList);
|
||||
|
||||
return new DeleteMeta(emptyStringAsNull, desc, id, ver, allBindable);
|
||||
return new DeleteMeta(emptyStringAsNull, desc, id, ver);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.avaje.ebeaninternal.api.DerivedRelationshipData;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
import com.avaje.ebeaninternal.api.SpiUpdatePlan;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequestBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
|
||||
/**
|
||||
@@ -18,10 +17,7 @@ import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
*/
|
||||
public class UpdateHandler extends DmlHandler {
|
||||
|
||||
|
||||
private final UpdateMeta meta;
|
||||
|
||||
private Set<String> updatedProperties;
|
||||
|
||||
private boolean emptySetClause;
|
||||
|
||||
@@ -41,8 +37,6 @@ public class UpdateHandler extends DmlHandler {
|
||||
emptySetClause = true;
|
||||
return;
|
||||
}
|
||||
|
||||
updatedProperties = updatePlan.getProperties();
|
||||
|
||||
sql = updatePlan.getSql();
|
||||
|
||||
@@ -79,18 +73,11 @@ public class UpdateHandler extends DmlHandler {
|
||||
if (!emptySetClause){
|
||||
int rowCount = dataBind.executeUpdate();
|
||||
checkRowCount(rowCount);
|
||||
setAdditionalProperties();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncluded(BeanProperty prop) {
|
||||
|
||||
return prop.isDbUpdatable() && (updatedProperties == null || updatedProperties.contains(prop.getName()));
|
||||
}
|
||||
|
||||
public void registerDerivedRelationship(DerivedRelationshipData derivedRelationship) {
|
||||
persistRequest.getTransaction().registerDerivedRelationship(derivedRelationship);
|
||||
}
|
||||
public void registerDerivedRelationship(DerivedRelationshipData derivedRelationship) {
|
||||
persistRequest.getTransaction().registerDerivedRelationship(derivedRelationship);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@ package com.avaje.ebeaninternal.server.persist.dml;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebean.annotation.ConcurrencyMode;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebean.bean.EntityBeanIntercept;
|
||||
import com.avaje.ebeaninternal.api.SpiUpdatePlan;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequestBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
import com.avaje.ebeaninternal.server.persist.dmlbind.Bindable;
|
||||
import com.avaje.ebeaninternal.server.persist.dmlbind.BindableId;
|
||||
import com.avaje.ebeaninternal.server.persist.dmlbind.BindableList;
|
||||
@@ -28,7 +29,6 @@ public final class UpdateMeta {
|
||||
private final BindableList set;
|
||||
private final BindableId id;
|
||||
private final Bindable version;
|
||||
private final Bindable all;
|
||||
|
||||
private final String tableName;
|
||||
|
||||
@@ -37,20 +37,18 @@ public final class UpdateMeta {
|
||||
|
||||
private final boolean emptyStringAsNull;
|
||||
|
||||
public UpdateMeta(boolean emptyStringAsNull, BeanDescriptor<?> desc, BindableList set, BindableId id, Bindable version, Bindable all) {
|
||||
public UpdateMeta(boolean emptyStringAsNull, BeanDescriptor<?> desc, BindableList set, BindableId id, Bindable version) {
|
||||
this.emptyStringAsNull = emptyStringAsNull;
|
||||
this.tableName = desc.getBaseTable();
|
||||
this.set = set;
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.all = all;
|
||||
|
||||
this.sqlNone = genSql(ConcurrencyMode.NONE, null, null);
|
||||
this.sqlVersion = genSql(ConcurrencyMode.VERSION, null, null);
|
||||
this.sqlNone = genSql(ConcurrencyMode.NONE, null, set);
|
||||
this.sqlVersion = genSql(ConcurrencyMode.VERSION, null, set);
|
||||
|
||||
this.modeNoneUpdatePlan = new UpdatePlan(ConcurrencyMode.NONE, sqlNone, set);
|
||||
this.modeVersionUpdatePlan = new UpdatePlan(ConcurrencyMode.VERSION, sqlVersion, set);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,19 +70,15 @@ public final class UpdateMeta {
|
||||
*/
|
||||
public void bind(PersistRequestBean<?> persist, DmlHandler bind, SpiUpdatePlan updatePlan) throws SQLException {
|
||||
|
||||
Object bean = persist.getBean();
|
||||
EntityBean bean = persist.getEntityBean();
|
||||
|
||||
updatePlan.bindSet(bind, bean);
|
||||
|
||||
id.dmlBind(bind, false, bean);
|
||||
id.dmlBind(bind, bean);
|
||||
|
||||
switch (persist.getConcurrencyMode()) {
|
||||
case VERSION:
|
||||
version.dmlBind(bind, false, bean);
|
||||
break;
|
||||
case ALL:
|
||||
Object oldBean = persist.getOldValues();
|
||||
all.dmlBindWhere(bind, true, oldBean);
|
||||
version.dmlBind(bind, bean);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -110,14 +104,6 @@ public final class UpdateMeta {
|
||||
case VERSION:
|
||||
return modeVersionUpdatePlan;
|
||||
|
||||
case ALL:
|
||||
Object oldValues = request.getOldValues();
|
||||
if (oldValues == null) {
|
||||
throw new PersistenceException("OldValues are null?");
|
||||
}
|
||||
String sql = genDynamicWhere(request.getUpdatedProperties(), request.getLoadedProperties(), oldValues);
|
||||
return new UpdatePlan(ConcurrencyMode.ALL, sql, set);
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Invalid mode " + mode);
|
||||
}
|
||||
@@ -125,26 +111,33 @@ public final class UpdateMeta {
|
||||
|
||||
private SpiUpdatePlan getDynamicUpdatePlan(ConcurrencyMode mode, PersistRequestBean<?> persistRequest) {
|
||||
|
||||
Set<String> updatedProps = persistRequest.getUpdatedProperties();
|
||||
|
||||
if (ConcurrencyMode.ALL.equals(mode)) {
|
||||
// due to is null in where clause we won't bother trying to
|
||||
// cache plans for ConcurrencyMode.ALL
|
||||
String sql = genSql(mode, persistRequest, null);
|
||||
if (sql == null) {
|
||||
// changed properties must have been updatable=false
|
||||
return UpdatePlan.EMPTY_SET_CLAUSE;
|
||||
// we can use a cached UpdatePlan for the changed properties
|
||||
|
||||
EntityBeanIntercept ebi = persistRequest.getEntityBeanIntercept();
|
||||
int hash = ebi.getChangedPropertiesHash();
|
||||
|
||||
BeanDescriptor<?> beanDescriptor = persistRequest.getBeanDescriptor();
|
||||
|
||||
BeanPropertyAssocOne<?>[] propertiesEmbedded = beanDescriptor.propertiesEmbedded();
|
||||
for (int i=0; i< propertiesEmbedded.length; i++) {
|
||||
EntityBean embeddedBean = (EntityBean)propertiesEmbedded[i].getValue(persistRequest.getEntityBean());
|
||||
if (embeddedBean == null) {
|
||||
hash = hash * 31;
|
||||
} else {
|
||||
return new UpdatePlan(null, mode, sql, set, updatedProps);
|
||||
hash = hash * 31 + embeddedBean._ebean_getIntercept().getChangedPropertiesHash();
|
||||
}
|
||||
}
|
||||
|
||||
BeanProperty versionProperty = beanDescriptor.getVersionProperty();
|
||||
if (versionProperty != null) {
|
||||
if (ebi.isLoadedProperty(versionProperty.getPropertyIndex())) {
|
||||
hash = hash * 31 + 7;
|
||||
}
|
||||
}
|
||||
|
||||
// we can use a cached UpdatePlan for the changed properties
|
||||
int hash = mode.hashCode();
|
||||
hash = hash * 31 + (updatedProps == null ? 0 : updatedProps.hashCode());
|
||||
Integer key = Integer.valueOf(hash);
|
||||
|
||||
BeanDescriptor<?> beanDescriptor = persistRequest.getBeanDescriptor();
|
||||
SpiUpdatePlan updatePlan = beanDescriptor.getUpdatePlan(key);
|
||||
if (updatePlan != null) {
|
||||
return updatePlan;
|
||||
@@ -154,18 +147,13 @@ public final class UpdateMeta {
|
||||
|
||||
// build a bindableList that only contains the changed properties
|
||||
List<Bindable> list = new ArrayList<Bindable>();
|
||||
if (updatedProps == null) {
|
||||
// update all the properties
|
||||
set.addAll(list);
|
||||
} else {
|
||||
set.addChanged(persistRequest, list);
|
||||
}
|
||||
set.addToUpdate(persistRequest, list);
|
||||
BindableList bindableList = new BindableList(list);
|
||||
|
||||
// build the SQL for this update statement
|
||||
String sql = genSql(mode, persistRequest, bindableList);
|
||||
|
||||
updatePlan = new UpdatePlan(key, mode, sql, bindableList, null);
|
||||
updatePlan = new UpdatePlan(key, mode, sql, bindableList);
|
||||
|
||||
// add the UpdatePlan to the cache
|
||||
beanDescriptor.putUpdatePlan(key, updatePlan);
|
||||
@@ -188,12 +176,8 @@ public final class UpdateMeta {
|
||||
request.append("update ").append(tableName).append(" set ");
|
||||
|
||||
request.setUpdateSetMode();
|
||||
if (bindableList != null) {
|
||||
bindableList.dmlAppend(request, false);
|
||||
} else {
|
||||
set.dmlAppend(request, true);
|
||||
}
|
||||
|
||||
bindableList.dmlAppend(request);
|
||||
|
||||
if (request.getBindColumnCount() == 0) {
|
||||
// update properties must have been updatable=false
|
||||
// with the result that nothing is in the set clause
|
||||
@@ -203,38 +187,15 @@ public final class UpdateMeta {
|
||||
request.append(" where ");
|
||||
|
||||
request.setWhereIdMode();
|
||||
id.dmlAppend(request, false);
|
||||
id.dmlAppend(request);
|
||||
|
||||
if (ConcurrencyMode.VERSION.equals(conMode)) {
|
||||
if (version == null) {
|
||||
return null;
|
||||
}
|
||||
version.dmlAppend(request, false);
|
||||
|
||||
} else if (ConcurrencyMode.ALL.equals(conMode)) {
|
||||
|
||||
all.dmlWhere(request, true, request.getOldValues());
|
||||
version.dmlAppend(request);
|
||||
}
|
||||
|
||||
return request.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the sql dynamically for where using IS NULL for binding null
|
||||
* values.
|
||||
*/
|
||||
private String genDynamicWhere(Set<String> loadedProps, Set<String> whereProps, Object oldBean) {
|
||||
|
||||
// always has a preceding id property(s) so the first
|
||||
// option is always ' and ' and not blank.
|
||||
|
||||
GenerateDmlRequest request = new GenerateDmlRequest(emptyStringAsNull, loadedProps, whereProps, oldBean);
|
||||
|
||||
request.append(sqlNone);
|
||||
|
||||
request.setWhereMode();
|
||||
all.dmlWhere(request, true, oldBean);
|
||||
|
||||
|
||||
return request.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.avaje.ebeaninternal.server.persist.dml;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Set;
|
||||
|
||||
import com.avaje.ebean.annotation.ConcurrencyMode;
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.SpiUpdatePlan;
|
||||
import com.avaje.ebeaninternal.server.persist.dmlbind.Bindable;
|
||||
|
||||
@@ -15,12 +15,12 @@ import com.avaje.ebeaninternal.server.persist.dmlbind.Bindable;
|
||||
*/
|
||||
public class UpdatePlan implements SpiUpdatePlan {
|
||||
|
||||
/**
|
||||
* Special plan used when there is nothing in the set clause and the update
|
||||
* should in fact be skipped. Occurs when the updated properties have
|
||||
* updatable=false in their deployment.
|
||||
*/
|
||||
public static final UpdatePlan EMPTY_SET_CLAUSE = new UpdatePlan();
|
||||
/**
|
||||
* Special plan used when there is nothing in the set clause and the update
|
||||
* should in fact be skipped. Occurs when the updated properties have
|
||||
* updatable=false in their deployment.
|
||||
*/
|
||||
public static final UpdatePlan EMPTY_SET_CLAUSE = new UpdatePlan();
|
||||
|
||||
private final Integer key;
|
||||
|
||||
@@ -30,10 +30,6 @@ public class UpdatePlan implements SpiUpdatePlan {
|
||||
|
||||
private final Bindable set;
|
||||
|
||||
private final Set<String> properties;
|
||||
|
||||
private final boolean checkIncludes;
|
||||
|
||||
private final long timeCreated;
|
||||
|
||||
private final boolean emptySetClause;
|
||||
@@ -45,22 +41,19 @@ public class UpdatePlan implements SpiUpdatePlan {
|
||||
*/
|
||||
public UpdatePlan(ConcurrencyMode mode, String sql, Bindable set) {
|
||||
|
||||
this(null, mode, sql, set, null);
|
||||
this(null, mode, sql, set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a cachable UpdatePlan with a given key.
|
||||
*/
|
||||
public UpdatePlan(Integer key, ConcurrencyMode mode, String sql,
|
||||
Bindable set, Set<String> properties) {
|
||||
public UpdatePlan(Integer key, ConcurrencyMode mode, String sql, Bindable set) {
|
||||
|
||||
this.emptySetClause = false;
|
||||
this.emptySetClause = (sql == null);
|
||||
this.key = key;
|
||||
this.mode = mode;
|
||||
this.sql = sql;
|
||||
this.set = set;
|
||||
this.properties = properties;
|
||||
this.checkIncludes = properties != null;
|
||||
this.timeCreated = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@@ -73,8 +66,6 @@ public class UpdatePlan implements SpiUpdatePlan {
|
||||
this.mode = ConcurrencyMode.NONE;
|
||||
this.sql = null;
|
||||
this.set = null;
|
||||
this.properties = null;
|
||||
this.checkIncludes = false;
|
||||
this.timeCreated = 0;
|
||||
}
|
||||
|
||||
@@ -86,9 +77,9 @@ public class UpdatePlan implements SpiUpdatePlan {
|
||||
/**
|
||||
* Run the prepared statement binding for the 'update set' properties.
|
||||
*/
|
||||
public void bindSet(DmlHandler bind, Object bean) throws SQLException {
|
||||
public void bindSet(DmlHandler bind, EntityBean bean) throws SQLException {
|
||||
|
||||
set.dmlBind(bind, checkIncludes, bean);
|
||||
set.dmlBind(bind, bean);
|
||||
|
||||
// not strictly 'thread safe' but object assignment is atomic
|
||||
Long touched = Long.valueOf(System.currentTimeMillis());
|
||||
@@ -139,15 +130,4 @@ public class UpdatePlan implements SpiUpdatePlan {
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of changed properties.
|
||||
* <p>
|
||||
* This can return null when all properties in the set are being bound in
|
||||
* the update statement.
|
||||
* </p>
|
||||
*/
|
||||
public Set<String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.persist.dmlbind;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequestBean;
|
||||
import com.avaje.ebeaninternal.server.persist.dml.GenerateDmlRequest;
|
||||
|
||||
@@ -25,32 +26,17 @@ public interface Bindable {
|
||||
* For Updates including only changed properties add the Bindable to the
|
||||
* list if it should be included in the 'update set'.
|
||||
*/
|
||||
public void addChanged(PersistRequestBean<?> request, List<Bindable> list);
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list);
|
||||
|
||||
/**
|
||||
* append sql to the buffer with prefix and suffix options.
|
||||
*/
|
||||
public void dmlInsert(GenerateDmlRequest request, boolean checkIncludes);
|
||||
|
||||
/**
|
||||
* append sql to the buffer with prefix and suffix options.
|
||||
*/
|
||||
public void dmlAppend(GenerateDmlRequest request, boolean checkIncludes);
|
||||
|
||||
/**
|
||||
* For WHERE clauses append sql to the buffer with prefix and suffix
|
||||
* options. These need to take into account binding of null values.
|
||||
*/
|
||||
public void dmlWhere(GenerateDmlRequest request, boolean checkIncludes, Object bean);
|
||||
public void dmlAppend(GenerateDmlRequest request);
|
||||
|
||||
/**
|
||||
* 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 dmlBind(BindableRequest request, boolean checkIncludes, Object bean)
|
||||
throws SQLException;
|
||||
|
||||
public void dmlBindWhere(BindableRequest request, boolean checkIncludes, Object bean)
|
||||
throws SQLException;
|
||||
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException;
|
||||
|
||||
}
|
||||
|
||||
+33
-65
@@ -3,6 +3,7 @@ package com.avaje.ebeaninternal.server.persist.dmlbind;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import com.avaje.ebean.bean.EntityBean;
|
||||
import com.avaje.ebeaninternal.api.DerivedRelationshipData;
|
||||
import com.avaje.ebeaninternal.server.core.PersistRequestBean;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocOne;
|
||||
@@ -14,75 +15,42 @@ import com.avaje.ebeaninternal.server.persist.dml.GenerateDmlRequest;
|
||||
*/
|
||||
public class BindableAssocOne implements Bindable {
|
||||
|
||||
private final BeanPropertyAssocOne<?> assocOne;
|
||||
private final BeanPropertyAssocOne<?> assocOne;
|
||||
|
||||
private final ImportedId importedId;
|
||||
private final ImportedId importedId;
|
||||
|
||||
public BindableAssocOne(BeanPropertyAssocOne<?> assocOne) {
|
||||
this.assocOne = assocOne;
|
||||
this.importedId = assocOne.getImportedId();
|
||||
public BindableAssocOne(BeanPropertyAssocOne<?> assocOne) {
|
||||
this.assocOne = assocOne;
|
||||
this.importedId = assocOne.getImportedId();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "BindableAssocOne " + assocOne;
|
||||
}
|
||||
|
||||
public void addToUpdate(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.isAddToUpdate(assocOne)) {
|
||||
list.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "BindableAssocOne " + assocOne;
|
||||
}
|
||||
|
||||
public void addChanged(PersistRequestBean<?> request, List<Bindable> list) {
|
||||
if (request.hasChanged(assocOne)) {
|
||||
list.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void dmlInsert(GenerateDmlRequest request, boolean checkIncludes) {
|
||||
dmlAppend(request, checkIncludes);
|
||||
}
|
||||
|
||||
public void dmlAppend(GenerateDmlRequest request, boolean checkIncludes) {
|
||||
if (checkIncludes && !request.isIncluded(assocOne)) {
|
||||
return;
|
||||
}
|
||||
importedId.dmlAppend(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for dynamic where clause generation.
|
||||
*/
|
||||
public void dmlWhere(GenerateDmlRequest request, boolean checkIncludes, Object bean) {
|
||||
if (checkIncludes && !request.isIncludedWhere(assocOne)) {
|
||||
return;
|
||||
}
|
||||
Object assocBean = assocOne.getValue(bean);
|
||||
importedId.dmlWhere(request, assocBean);
|
||||
}
|
||||
|
||||
public void dmlBind(BindableRequest request, boolean checkIncludes, Object bean) throws SQLException {
|
||||
if (checkIncludes && !request.isIncluded(assocOne)) {
|
||||
return;
|
||||
}
|
||||
dmlBind(request, bean, true);
|
||||
}
|
||||
|
||||
public void dmlBindWhere(BindableRequest request, boolean checkIncludes, Object bean) throws SQLException {
|
||||
if (checkIncludes && !request.isIncludedWhere(assocOne)) {
|
||||
return;
|
||||
}
|
||||
dmlBind(request, bean, false);
|
||||
}
|
||||
|
||||
private void dmlBind(BindableRequest request, Object bean, boolean bindNull)
|
||||
throws SQLException {
|
||||
|
||||
Object assocBean = assocOne.getValue(bean);
|
||||
Object boundValue = importedId.bind(request, assocBean, bindNull);
|
||||
if (bindNull && boundValue == null && assocBean != null){
|
||||
// this is the scenario for a derived foreign key
|
||||
// which will require an additional update
|
||||
// register for post insert of assocBean
|
||||
// update of bean set ... importedId.getLogicalName();
|
||||
// value of assocBean.getId
|
||||
DerivedRelationshipData d = new DerivedRelationshipData(assocBean, assocOne.getName(), bean);
|
||||
request.registerDerivedRelationship(d);
|
||||
}
|
||||
public void dmlAppend(GenerateDmlRequest request) {
|
||||
importedId.dmlAppend(request);
|
||||
}
|
||||
|
||||
public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException {
|
||||
|
||||
EntityBean assocBean = (EntityBean)assocOne.getValue(bean);
|
||||
Object boundValue = importedId.bind(request, assocBean);
|
||||
if (boundValue == null && assocBean != null) {
|
||||
// this is the scenario for a derived foreign key
|
||||
// which will require an additional update
|
||||
// register for post insert of assocBean
|
||||
// update of bean set ... importedId.getLogicalName();
|
||||
// value of assocBean.getId
|
||||
DerivedRelationshipData d = new DerivedRelationshipData(assocBean, assocOne.getName(), bean);
|
||||
request.registerDerivedRelationship(d);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user