#358 - ENH: Add ServerConfig updateAllPropertiesInBatch with a default of true

This commit is contained in:
Robin Bygrave
2015-07-27 22:59:18 +12:00
parent 962d7f601d
commit 3fa8f04a4c
12 changed files with 149 additions and 57 deletions
@@ -243,7 +243,12 @@ public class ServerConfig {
* Behaviour of update to include on the change properties.
*/
private boolean updateChangesOnly = true;
/**
* Behaviour of updates in JDBC batch to by default include all properties.
*/
private boolean updateAllPropertiesInBatch = true;
/**
* Default behaviour for updates when cascade save on a O2M or M2M to delete any missing children.
*/
@@ -1516,7 +1521,26 @@ public class ServerConfig {
public void setUpdateChangesOnly(boolean updateChangesOnly) {
this.updateChangesOnly = updateChangesOnly;
}
/**
* Returns true if updates in JDBC batch default to include all properties by default.
*/
public boolean isUpdateAllPropertiesInBatch() {
return updateAllPropertiesInBatch;
}
/**
* Set to false if by default updates in JDBC batch should not include all properties.
* <p>
* This mode can be explicitly set per transaction.
* </p>
*
* @see com.avaje.ebean.Transaction#setUpdateAllLoadedProperties(boolean)
*/
public void setUpdateAllPropertiesInBatch(boolean updateAllPropertiesInBatch) {
this.updateAllPropertiesInBatch = updateAllPropertiesInBatch;
}
/**
* Return true if updates by default delete missing children when cascading save to a OneToMany or
* ManyToMany. When not set this defaults to true.
@@ -1860,6 +1884,7 @@ public class ServerConfig {
collectQueryStatsByNode = p.getBoolean("collectQueryStatsByNode", collectQueryStatsByNode);
collectQueryOrigins = p.getBoolean("collectQueryOrigins", collectQueryOrigins);
updateAllPropertiesInBatch = p.getBoolean("updateAllPropertiesInBatch", updateAllPropertiesInBatch);
updateChangesOnly = p.getBoolean("updateChangesOnly", updateChangesOnly);
boolean defaultDeleteMissingChildren = p.getBoolean("defaultDeleteMissingChildren", updatesDeleteMissingChildren);
@@ -158,7 +158,7 @@ public class ScopedTransaction implements SpiTransaction {
}
@Override
public boolean isUpdateAllLoadedProperties() {
public Boolean isUpdateAllLoadedProperties() {
return transaction.isUpdateAllLoadedProperties();
}
@@ -32,7 +32,12 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL
* Return true if query origins should be collected.
*/
boolean isCollectQueryOrigins();
/**
* Return true if updates in JDBC batch should include all columns if unspecified on the transaction.
*/
boolean isUpdateAllPropertiesInBatch();
/**
* Return the server configuration.
*/
@@ -101,8 +101,9 @@ public interface SpiTransaction extends Transaction {
/**
* Return true if this transaction has updateAllLoadedProperties set.
* If null is returned the server default is used (set on ServerConfig).
*/
boolean isUpdateAllLoadedProperties();
Boolean isUpdateAllLoadedProperties();
/**
* Return the batchSize specifically set for this transaction or 0.
@@ -148,6 +148,8 @@ public final class DefaultServer implements SpiEbeanServer {
*/
private List<SpiEbeanPlugin> ebeanPlugins;
private final boolean updateAllPropertiesInBatch;
private final boolean collectQueryOrigins;
private final boolean collectQueryStatsByNode;
@@ -182,6 +184,7 @@ public final class DefaultServer implements SpiEbeanServer {
this.beanDescriptorManager = config.getBeanDescriptorManager();
beanDescriptorManager.setEbeanServer(this);
this.updateAllPropertiesInBatch = serverConfig.isUpdateAllPropertiesInBatch();
this.collectQueryOrigins = serverConfig.isCollectQueryOrigins();
this.collectQueryStatsByNode = serverConfig.isCollectQueryStatsByNode();
this.maxCallStack = serverConfig.getMaxCallStack();
@@ -252,6 +255,11 @@ public final class DefaultServer implements SpiEbeanServer {
return collectQueryOrigins;
}
@Override
public boolean isUpdateAllPropertiesInBatch() {
return updateAllPropertiesInBatch;
}
public int getLazyLoadBatchSize() {
return lazyLoadBatchSize;
}
@@ -117,6 +117,11 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
*/
private boolean batchOnCascadeSet;
/**
* Set for updates to determine if all loaded properties are included in the update.
*/
private boolean requestUpdateAllLoadedProps;
public PersistRequestBean(SpiEbeanServer server, T bean, Object parentBean, BeanManager<T> mgr, SpiTransaction t,
PersistExecute persistExecute, PersistRequest.Type type, boolean saveRecurse) {
@@ -544,6 +549,9 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
// if bean persisted again then should result in an update
intercept.setLoaded();
if (isInsert()) {
postInsert();
}
addEvent();
@@ -644,7 +652,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Return true if the property should be included in the update.
*/
public boolean isAddToUpdate(BeanProperty prop) {
if (transaction.isUpdateAllLoadedProperties()) {
if (requestUpdateAllLoadedProps) {
return intercept.isLoadedProperty(prop.getPropertyIndex());
} else {
return intercept.isDirtyProperty(prop.getPropertyIndex());
@@ -655,7 +663,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
return transaction.getDerivedRelationship(bean);
}
public void postInsert() {
private 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++) {
@@ -710,4 +718,24 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
return updatedManysOnly;
}
/**
* Determine if all loaded properties should be used for an update.
* <p>
* Takes into account transaction setting and JDBC batch.
* </p>
*/
public boolean determineUpdateAllLoadedProperties() {
Boolean txnUpdateAll = transaction.isUpdateAllLoadedProperties();
if (txnUpdateAll != null) {
// use the setting explicitly set on the transaction
requestUpdateAllLoadedProps = txnUpdateAll;
} else {
// if using batch use the server default setting
requestUpdateAllLoadedProps = isBatchThisRequest() && ebeanServer.isUpdateAllPropertiesInBatch();
}
return requestUpdateAllLoadedProps;
}
}
@@ -137,7 +137,6 @@ public class InsertHandler extends DmlHandler {
checkRowCount(rc);
executeDerivedRelationships();
persistRequest.postInsert();
}
protected void executeDerivedRelationships() {
@@ -90,12 +90,12 @@ public final class UpdateMeta {
*/
public SpiUpdatePlan getUpdatePlan(PersistRequestBean<?> request) {
ConcurrencyMode mode = request.determineConcurrencyMode();
if (request.isDynamicUpdateSql()) {
return getDynamicUpdatePlan(mode, request);
return getDynamicUpdatePlan(request);
}
// 'full bean' update...
ConcurrencyMode mode = request.determineConcurrencyMode();
switch (mode) {
case NONE:
return modeNoneUpdatePlan;
@@ -108,14 +108,12 @@ public final class UpdateMeta {
}
}
private SpiUpdatePlan getDynamicUpdatePlan(ConcurrencyMode mode, PersistRequestBean<?> persistRequest) {
// we can use a cached UpdatePlan for the changed properties
private SpiUpdatePlan getDynamicUpdatePlan(PersistRequestBean<?> persistRequest) {
EntityBeanIntercept ebi = persistRequest.getEntityBeanIntercept();
int hash;
if (persistRequest.getTransaction().isUpdateAllLoadedProperties()) {
if (persistRequest.determineUpdateAllLoadedProperties()) {
hash = ebi.getLoadedPropertyHash();
} else {
hash = ebi.getDirtyPropertyHash();
@@ -132,6 +130,7 @@ public final class UpdateMeta {
Integer key = Integer.valueOf(hash);
// check if we can use a cached UpdatePlan
SpiUpdatePlan updatePlan = beanDescriptor.getUpdatePlan(key);
if (updatePlan != null) {
return updatePlan;
@@ -144,6 +143,8 @@ public final class UpdateMeta {
set.addToUpdate(persistRequest, list);
BindableList bindableList = new BindableList(list);
ConcurrencyMode mode = persistRequest.determineConcurrencyMode();
// build the SQL for this update statement
String sql = genSql(mode, persistRequest, bindableList);
@@ -91,7 +91,7 @@ public class JdbcTransaction implements SpiTransaction {
protected boolean localReadOnly;
protected boolean updateAllLoadedProperties;
protected Boolean updateAllLoadedProperties;
protected PersistBatch oldBatchMode;
@@ -400,7 +400,7 @@ public class JdbcTransaction implements SpiTransaction {
this.updateAllLoadedProperties = updateAllLoadedProperties;
}
public boolean isUpdateAllLoadedProperties() {
public Boolean isUpdateAllLoadedProperties() {
return updateAllLoadedProperties;
}