#1738 - Refactor SqlTreeNodeBean load method

This commit is contained in:
rob bygrave
2019-06-28 22:35:36 +12:00
parent 5404dab5a3
commit 93cc0399f1
@@ -218,28 +218,20 @@ class SqlTreeNodeBean implements SqlTreeNode {
}
/**
* read the properties from the resultSet.
* Load that takes into account inheritance.
*/
@Override
public EntityBean load(DbReadContext ctx, EntityBean parentBean, EntityBean contextParent) throws SQLException {
private class LoadInherit extends Load {
Object lazyLoadParentId = null;
if (lazyLoadParentIdBinder != null) {
lazyLoadParentId = lazyLoadParentIdBinder.read(ctx);
LoadInherit(DbReadContext ctx, EntityBean parentBean, EntityBean contextParent) {
super(ctx, parentBean, contextParent);
}
Class<?> localType;
STreeType localDesc;
IdBinder localIdBinder;
EntityBean localBean;
if (inheritInfo != null) {
@Override
void initBeanType() throws SQLException {
InheritInfo localInfo = inheritInfo.readType(ctx);
if (localInfo == null) {
// the bean must be null
localIdBinder = idBinder;
localBean = null;
localType = null;
localDesc = desc;
} else {
localBean = localInfo.createEntityBean();
@@ -247,65 +239,10 @@ class SqlTreeNodeBean implements SqlTreeNode {
localIdBinder = localInfo.getIdBinder();
localDesc = localInfo.desc();
}
} else {
localType = null;
localDesc = desc;
localBean = desc.createEntityBean();
localIdBinder = idBinder;
}
Mode queryMode = ctx.getQueryMode();
PersistenceContext persistenceContext = (!readId || temporalVersions) ? null : ctx.getPersistenceContext();
// bean already existing in the persistence context
EntityBean contextBean = null;
if (readId) {
Object id = localIdBinder.readSet(ctx, localBean);
if (id == null) {
// bean must be null...
localBean = null;
// ... but there may exist as reference bean in parent which has to be marked as deleted.
if (parentBean != null && nodeBeanProp instanceof STreePropertyAssocOne) {
contextBean = ((STreePropertyAssocOne)nodeBeanProp).getValueAsEntityBean(parentBean);
if (contextBean != null) {
desc.markAsDeleted(contextBean);
}
}
} else if (!temporalVersions) {
// check the PersistenceContext to see if the bean already exists
contextBean = (EntityBean) localDesc.contextPutIfAbsent(persistenceContext, id, localBean);
if (contextBean == null) {
// bean just added to the persistenceContext
contextBean = localBean;
} else {
// bean already exists in persistenceContext
if (isLoadContextBeanNeeded(queryMode, contextBean)) {
// refresh it anyway (lazy loading for example)
localBean = contextBean;
} else {
// ignore the DB data...
localBean = null;
}
}
}
}
ctx.setCurrentPrefix(prefix, pathMap);
ctx.propagateState(localBean);
SqlBeanLoad sqlBeanLoad = new SqlBeanLoad(ctx, localType, localBean, queryMode);
if (inheritInfo == null) {
// normal behavior with no inheritance
for (STreeProperty property : properties) {
property.load(sqlBeanLoad);
}
} else {
@Override
void loadProperties() {
// take account of inheritance and due to subclassing approach
// need to get a 'local' version of the property
for (STreeProperty property : properties) {
@@ -313,82 +250,220 @@ class SqlTreeNodeBean implements SqlTreeNode {
localDesc.inheritanceLoad(sqlBeanLoad, property, ctx);
}
}
}
boolean lazyLoadMany = false;
if (localBean == null && queryMode == Mode.LAZYLOAD_MANY) {
// batch lazy load many into existing contextBean
localBean = contextBean;
lazyLoadMany = true;
/**
* Load a bean instance.
*/
private class Load {
final DbReadContext ctx;
final EntityBean parentBean;
final EntityBean contextParent;
Object lazyLoadParentId;
Class<?> localType;
STreeType localDesc;
IdBinder localIdBinder;
EntityBean localBean;
Mode queryMode;
PersistenceContext persistenceContext;
Object id;
EntityBean contextBean;
SqlBeanLoad sqlBeanLoad;
boolean lazyLoadMany;
Load(DbReadContext ctx, EntityBean parentBean, EntityBean contextParent) {
this.ctx = ctx;
this.parentBean = parentBean;
this.contextParent = contextParent;
}
// recursively continue reading...
for (SqlTreeNode aChildren : children) {
// read each child... and let them set their
// values back to this localBean
aChildren.load(ctx, localBean, contextBean);
void initLazyParent() throws SQLException {
if (lazyLoadParentIdBinder != null) {
lazyLoadParentId = lazyLoadParentIdBinder.read(ctx);
}
}
if (queryMode == Mode.LAZYLOAD_MANY && isRoot()) {
return contextBean;
void initBeanType() throws SQLException {
localDesc = desc;
localBean = desc.createEntityBean();
localIdBinder = idBinder;
}
if (!lazyLoadMany && localBean != null) {
ctx.setCurrentPrefix(prefix, pathMap);
if (readId && !temporalVersions) {
createListProxies(localDesc, ctx, localBean, disableLazyLoad);
}
if (temporalMode == SpiQuery.TemporalMode.DRAFT) {
localDesc.setDraft(localBean);
}
localDesc.postLoad(localBean);
void initPersistenceContext() {
queryMode = ctx.getQueryMode();
persistenceContext = (!readId || temporalVersions) ? null : ctx.getPersistenceContext();
}
EntityBeanIntercept ebi = localBean._ebean_getIntercept();
ebi.setPersistenceContext(persistenceContext);
if (Mode.LAZYLOAD_BEAN == queryMode) {
// Lazy Load does not reset the dirty state
ebi.setLoadedLazy();
} else if (readId) {
// normal bean loading
ebi.setLoaded();
}
if (disableLazyLoad) {
// bean does not have an Id or is SqlSelect based
ebi.setDisableLazyLoad(true);
} else if (partialObject) {
if (readId) {
// register for lazy loading
ctx.register(null, ebi);
void readId() throws SQLException {
if (readId) {
id = localIdBinder.readSet(ctx, localBean);
if (id == null) {
readIdNullBean();
} else if (!temporalVersions) {
readIdBean();
}
}
}
private void readIdBean() {
// check the PersistenceContext to see if the bean already exists
contextBean = (EntityBean) localDesc.contextPutIfAbsent(persistenceContext, id, localBean);
if (contextBean == null) {
// bean just added to the persistenceContext
contextBean = localBean;
} else {
ebi.setFullyLoadedBean(true);
}
if (ctx.isAutoTuneProfiling() && !disableLazyLoad) {
// collect autoTune profiling for this bean...
ctx.profileBean(ebi, prefix);
// bean already exists in persistenceContext
if (isLoadContextBeanNeeded(queryMode, contextBean)) {
// refresh it anyway (lazy loading for example)
localBean = contextBean;
} else {
// ignore the DB data...
localBean = null;
}
}
}
if (parentBean != null) {
// set this back to the parentBean
nodeBeanProp.setValue(parentBean, contextBean);
private void readIdNullBean() {
// bean must be null...
localBean = null;
// ... but there may exist as reference bean in parent which has to be marked as deleted.
if (parentBean != null && nodeBeanProp instanceof STreePropertyAssocOne) {
contextBean = ((STreePropertyAssocOne)nodeBeanProp).getValueAsEntityBean(parentBean);
if (contextBean != null) {
desc.markAsDeleted(contextBean);
}
}
}
if (!readId || temporalVersions) {
// a bean with no Id (never found in context)
if (lazyLoadParentId != null) {
ctx.setLazyLoadedChildBean(localBean, lazyLoadParentId);
}
return localBean;
void initSqlLoadBean() {
ctx.setCurrentPrefix(prefix, pathMap);
ctx.propagateState(localBean);
sqlBeanLoad = new SqlBeanLoad(ctx, localType, localBean, queryMode);
}
} else {
if (lazyLoadParentId != null) {
ctx.setLazyLoadedChildBean(contextBean, lazyLoadParentId);
void loadProperties() {
for (STreeProperty property : properties) {
property.load(sqlBeanLoad);
}
}
void loadChildren() throws SQLException {
//boolean lazyLoadMany = false;
if (localBean == null && queryMode == Mode.LAZYLOAD_MANY) {
// batch lazy load many into existing contextBean
localBean = contextBean;
lazyLoadMany = true;
}
// recursively continue reading...
for (SqlTreeNode aChildren : children) {
// read each child... and let them set their
// values back to this localBean
aChildren.load(ctx, localBean, contextBean);
}
}
boolean isLazyLoadManyRoot() {
return queryMode == Mode.LAZYLOAD_MANY && isRoot();
}
EntityBean getContextBean() {
return contextBean;
}
void postLoad() {
if (!lazyLoadMany && localBean != null) {
ctx.setCurrentPrefix(prefix, pathMap);
if (readId && !temporalVersions) {
createListProxies(localDesc, ctx, localBean, disableLazyLoad);
}
if (temporalMode == SpiQuery.TemporalMode.DRAFT) {
localDesc.setDraft(localBean);
}
localDesc.postLoad(localBean);
EntityBeanIntercept ebi = localBean._ebean_getIntercept();
ebi.setPersistenceContext(persistenceContext);
if (Mode.LAZYLOAD_BEAN == queryMode) {
// Lazy Load does not reset the dirty state
ebi.setLoadedLazy();
} else if (readId) {
// normal bean loading
ebi.setLoaded();
}
if (disableLazyLoad) {
// bean does not have an Id or is SqlSelect based
ebi.setDisableLazyLoad(true);
} else if (partialObject) {
if (readId) {
// register for lazy loading
ctx.register(null, ebi);
}
} else {
ebi.setFullyLoadedBean(true);
}
if (ctx.isAutoTuneProfiling() && !disableLazyLoad) {
// collect autoTune profiling for this bean...
ctx.profileBean(ebi, prefix);
}
}
}
void setBeanToParent() {
if (parentBean != null) {
// set this back to the parentBean
nodeBeanProp.setValue(parentBean, contextBean);
}
}
EntityBean complete() {
if (!readId || temporalVersions) {
// a bean with no Id (never found in context)
if (lazyLoadParentId != null) {
ctx.setLazyLoadedChildBean(localBean, lazyLoadParentId);
}
return localBean;
} else {
if (lazyLoadParentId != null) {
ctx.setLazyLoadedChildBean(contextBean, lazyLoadParentId);
}
return contextBean;
}
}
void initialise() throws SQLException {
initLazyParent();
initBeanType();
initPersistenceContext();
readId();
initSqlLoadBean();
loadProperties();
loadChildren();
}
}
/**
* read the properties from the resultSet.
*/
@Override
public EntityBean load(DbReadContext ctx, EntityBean parentBean, EntityBean contextParent) throws SQLException {
Load load = (inheritInfo != null) ? new LoadInherit(ctx, parentBean, contextParent) : new Load(ctx, parentBean, contextParent);
load.initialise();
if (load.isLazyLoadManyRoot()) {
return load.getContextBean();
}
load.postLoad();
load.setBeanToParent();
return load.complete();
}
/**