Support EntityBeanIntercept as an interface with InterceptReadWrite and InterceptReadOnly options

With the view that we can optimise the readOnly + disableLazyLoad case by using InterceptReadOnly which doesn't need to support any of the flags used as part of mutation.
This commit is contained in:
Rob Bygrave committed 2022-04-04 13:30:26 +12:00
1 parent d55223f9f5
commit 5ab02715ef
25 files changed
+1797 -869

No files matched your search

@@ -86,7 +86,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
private final ConcurrentHashMap<String, ElPropertyDeploy> elDeployCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, ElComparator<T>> comparatorCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, STreeProperty> dynamicProperty = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Map<String,String>> pathMaps = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Map<String, String>> pathMaps = new ConcurrentHashMap<>();
private final Map<String, SpiRawSql> namedRawSql;
private final Map<String, String> namedQuery;
@@ -1765,6 +1765,14 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return createEntityBean(false);
}
@Override
public EntityBean createEntityBean2(boolean readOnlyNoIntercept) {
if (readOnlyNoIntercept) {
return (EntityBean) prototypeEntityBean._ebean_newInstanceReadOnly();
}
return createEntityBean(false);
}
/**
* Create an entity bean for JSON marshalling (which differs for the element collection case).
*/
@@ -2673,7 +2681,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
public PartitionMeta partitionMeta() {
return partitionMeta;
}
/**
* Return the tablespace details of the bean.
*/
@@ -2879,7 +2887,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
for (BeanPropertyAssocMany<?> many : propertiesManySave) {
if (ebi.isLoadedProperty(many.propertyIndex())) {
final Object value = many.getValue(bean);
if (value instanceof BeanCollection && ((BeanCollection<?>)value).hasModifications() || value != null) {
if (value instanceof BeanCollection && ((BeanCollection<?>) value).hasModifications() || value != null) {
return true;
}
}
@@ -2,6 +2,7 @@ package io.ebeaninternal.server.deploy;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.bean.InterceptReadWrite;
final class ElementEntityBean implements EntityBean {
@@ -13,7 +14,7 @@ final class ElementEntityBean implements EntityBean {
ElementEntityBean(String[] properties) {
this.properties = properties;
this.intercept = new EntityBeanIntercept(this);
this.intercept = new InterceptReadWrite(this);
}
@Override
@@ -79,6 +79,11 @@ public interface STreeType {
*/
EntityBean createEntityBean();
/**
* Create a new entity bean instance with option for read only optimisation.
*/
EntityBean createEntityBean2(boolean readOnlyNoIntercept);
/**
* Put the entity bean into the persistence context.
*/
@@ -50,6 +50,7 @@ public final class SqlTreeBuilder {
*/
private final boolean rawNoId;
private final boolean disableLazyLoad;
private final boolean readOnly;
private final SpiQuery.TemporalMode temporalMode;
private SqlTreeNode rootNode;
private boolean sqlDistinct;
@@ -63,6 +64,7 @@ public final class SqlTreeBuilder {
this.desc = request.descriptor();
this.rawNoId = rawNoId;
this.disableLazyLoad = request.query().isDisableLazyLoading();
this.readOnly = Boolean.TRUE.equals(request.query().isReadOnly());
this.query = null;
this.subQuery = false;
this.distinctOnPlatform = false;
@@ -88,6 +90,7 @@ public final class SqlTreeBuilder {
this.query = request.query();
this.temporalMode = SpiQuery.TemporalMode.of(query);
this.disableLazyLoad = query.isDisableLazyLoading();
this.readOnly = Boolean.TRUE.equals(query.isReadOnly());
this.subQuery = Type.SQ_EXISTS == query.getType()
|| Type.SQ_IN == query.getType()
|| Type.ID_LIST == query.getType()
@@ -308,13 +311,13 @@ public final class SqlTreeBuilder {
if (baseTable == null) {
baseTable = desc.baseTable(temporalMode);
}
return new SqlTreeNodeRoot(desc, props, myList, withId, includeJoin, lazyLoadMany, temporalMode, disableLazyLoad, sqlDistinct, baseTable);
return new SqlTreeNodeRoot(desc, props, myList, withId, includeJoin, lazyLoadMany, temporalMode, disableLazyLoad, readOnly, sqlDistinct, baseTable);
} else if (prop instanceof STreePropertyAssocMany) {
return new SqlTreeNodeManyRoot(prefix, (STreePropertyAssocMany) prop, props, myList, withId(), temporalMode, disableLazyLoad);
return new SqlTreeNodeManyRoot(prefix, (STreePropertyAssocMany) prop, props, myList, withId(), temporalMode, disableLazyLoad, readOnly);
} else {
return new SqlTreeNodeBean(prefix, prop, props, myList, withId(), temporalMode, disableLazyLoad);
return new SqlTreeNodeBean(prefix, prop, props, myList, withId(), temporalMode, disableLazyLoad, readOnly);
}
}
@@ -28,6 +28,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
final boolean readId;
private final boolean readIdNormal;
private final boolean disableLazyLoad;
private final boolean readOnlyNoIntercept;
private final InheritInfo inheritInfo;
final String prefix;
private final Map<String, String> pathMap;
@@ -49,6 +50,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
this.readId = node.readId;
this.readIdNormal = readId && !temporalVersions;
this.disableLazyLoad = node.disableLazyLoad;
this.readOnlyNoIntercept = disableLazyLoad && node.readOnly;
this.partialObject = node.partialObject;
this.properties = node.properties;
this.pathMap = node.pathMap;
@@ -145,7 +147,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
void initBeanType() throws SQLException {
localDesc = desc;
localBean = desc.createEntityBean();
localBean = desc.createEntityBean2(readOnlyNoIntercept);
localIdBinder = idBinder;
}
@@ -38,6 +38,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
final boolean readId;
final boolean readIdNormal;
final boolean disableLazyLoad;
final boolean readOnly;
final InheritInfo inheritInfo;
final String prefix;
final Map<String, String> pathMap;
@@ -57,16 +58,16 @@ class SqlTreeNodeBean implements SqlTreeNode {
* Construct for leaf node.
*/
SqlTreeNodeBean(String prefix, STreePropertyAssoc beanProp, SqlTreeProperties props,
List<SqlTreeNode> myChildren, boolean withId, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad) {
this(prefix, beanProp, beanProp.target(), props, myChildren, withId, null, temporalMode, disableLazyLoad);
List<SqlTreeNode> myChildren, boolean withId, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad, boolean readOnly) {
this(prefix, beanProp, beanProp.target(), props, myChildren, withId, null, temporalMode, disableLazyLoad, readOnly);
}
/**
* Construct for root node.
*/
SqlTreeNodeBean(STreeType desc, SqlTreeProperties props, List<SqlTreeNode> myList, boolean withId,
STreePropertyAssocMany many, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad) {
this(null, null, desc, props, myList, withId, many, temporalMode, disableLazyLoad);
STreePropertyAssocMany many, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad, boolean readOnly) {
this(null, null, desc, props, myList, withId, many, temporalMode, disableLazyLoad, readOnly);
}
/**
@@ -74,7 +75,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
*/
private SqlTreeNodeBean(String prefix, STreePropertyAssoc beanProp, STreeType desc, SqlTreeProperties props,
List<SqlTreeNode> myChildren, boolean withId, STreePropertyAssocMany lazyLoadParent,
SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad) {
SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad, boolean readOnly) {
this.lazyLoadParent = lazyLoadParent;
this.lazyLoadParentIdBinder = (lazyLoadParent == null) ? null : lazyLoadParent.idBinder();
this.prefix = prefix;
@@ -91,6 +92,7 @@ class SqlTreeNodeBean implements SqlTreeNode {
this.readId = !aggregationRoot && withId && desc.hasId();
this.readIdNormal = readId && !temporalVersions;
this.disableLazyLoad = disableLazyLoad || !readIdNormal || desc.isRawSqlBased();
this.readOnly = readOnly;
this.partialObject = props.isPartialObject();
this.properties = props.getProps();
this.children = myChildren == null ? Collections.emptyList() : myChildren;
@@ -10,8 +10,8 @@ final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
final STreePropertyAssocMany manyProp;
SqlTreeNodeManyRoot(String prefix, STreePropertyAssocMany prop, SqlTreeProperties props, List<SqlTreeNode> myList,
boolean withId, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad) {
super(prefix, prop, props, myList, withId, temporalMode, disableLazyLoad);
boolean withId, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad, boolean readOnly) {
super(prefix, prop, props, myList, withId, temporalMode, disableLazyLoad, readOnly);
this.manyProp = prop;
}
@@ -20,9 +20,9 @@ final class SqlTreeNodeRoot extends SqlTreeNodeBean {
* Specify for SqlSelect to include an Id property or not.
*/
SqlTreeNodeRoot(STreeType desc, SqlTreeProperties props, List<SqlTreeNode> myList, boolean withId, TableJoin includeJoin,
STreePropertyAssocMany many, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad, boolean sqlDistinct, String baseTable) {
STreePropertyAssocMany many, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad, boolean readOnly, boolean sqlDistinct, String baseTable) {
super(desc, props, myList, withId, many, temporalMode, disableLazyLoad);
super(desc, props, myList, withId, many, temporalMode, disableLazyLoad, readOnly);
this.includeJoin = includeJoin;
this.sqlDistinct = sqlDistinct;
this.baseTable = baseTable;
@@ -1 +1 @@
ebean-version: 129
ebean-version: 141
+1
View File
@@ -0,0 +1 @@
synthetic: false