mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 22:41:35 +00:00
Merge branch 'master' into wip/h2database-v2
This commit is contained in:
commit
17df5a2c16
36 files changed
+681
-582
No files matched your search
@@ -31,6 +31,10 @@ jobs:
|
|||||||
path:
|
path:
|
||||||
~/.m2
|
~/.m2
|
||||||
key: build-${{ env.cache-name }}
|
key: build-${{ env.cache-name }}
|
||||||
|
- name: Maven version
|
||||||
|
run: mvn --version
|
||||||
|
# - name: Maven single test
|
||||||
|
# run: mvn --batch-mode clean verify -Dtest="io.ebeaninternal.server.core.DefaultServer_getReferenceTest" -DfailIfNoTests=false
|
||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: mvn package
|
run: mvn clean package
|
||||||
|
|
||||||
@@ -49,6 +49,3 @@ Goto [https://ebean.io/docs/](https://ebean.io/docs/)
|
|||||||
|
|
||||||
[Maven central - all related projects](http://search.maven.org/#search%7Cga%7C1%7Cebean "maven central all related projects")
|
[Maven central - all related projects](http://search.maven.org/#search%7Cga%7C1%7Cebean "maven central all related projects")
|
||||||
|
|
||||||
## Other versions
|
|
||||||
* [](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-agent) - ebean-agent
|
|
||||||
* [](https://maven-badges.herokuapp.com/maven-central/io.ebean/ebean-maven-plugin) - ebean-maven-plugin
|
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:12.11.3</tile>
|
<tile>io.ebean.tile:enhancement:12.14.1</tile>
|
||||||
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ public final class CQuery<T> implements DbReadContext, CancelableQuery, SpiProfi
|
|||||||
// set the generated sql back to the query
|
// set the generated sql back to the query
|
||||||
// so its available to the user...
|
// so its available to the user...
|
||||||
query.setGeneratedSql(queryPlan.getSql());
|
query.setGeneratedSql(queryPlan.getSql());
|
||||||
SqlTree sqlTree = queryPlan.getSqlTree();
|
SqlTreePlan sqlTree = queryPlan.getSqlTree();
|
||||||
this.rootNode = sqlTree.getRootNode();
|
this.rootNode = sqlTree.getRootNode();
|
||||||
this.manyProperty = sqlTree.getManyProperty();
|
this.manyProperty = sqlTree.getManyProperty();
|
||||||
this.sql = queryPlan.getSql();
|
this.sql = queryPlan.getSql();
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ final class CQueryBuilder {
|
|||||||
sql = buildUpdateSql(request, rootTableAlias, predicates, sqlTree);
|
sql = buildUpdateSql(request, rootTableAlias, predicates, sqlTree);
|
||||||
}
|
}
|
||||||
// cache the query plan
|
// cache the query plan
|
||||||
queryPlan = new CQueryPlan(request, sql, sqlTree, predicates.getLogWhereSql());
|
queryPlan = new CQueryPlan(request, sql, sqlTree.plan(), predicates.getLogWhereSql());
|
||||||
request.putQueryPlan(queryPlan);
|
request.putQueryPlan(queryPlan);
|
||||||
return new CQueryUpdate(request, predicates, queryPlan);
|
return new CQueryUpdate(request, predicates, queryPlan);
|
||||||
}
|
}
|
||||||
@@ -197,7 +197,7 @@ final class CQueryBuilder {
|
|||||||
SqlTree sqlTree = createSqlTree(request, predicates);
|
SqlTree sqlTree = createSqlTree(request, predicates);
|
||||||
SqlLimitResponse s = buildSql(null, request, predicates, sqlTree);
|
SqlLimitResponse s = buildSql(null, request, predicates, sqlTree);
|
||||||
|
|
||||||
queryPlan = new CQueryPlan(request, s.getSql(), sqlTree, predicates.getLogWhereSql());
|
queryPlan = new CQueryPlan(request, s.getSql(), sqlTree.plan(), predicates.getLogWhereSql());
|
||||||
request.putQueryPlan(queryPlan);
|
request.putQueryPlan(queryPlan);
|
||||||
return new CQueryFetchSingleAttribute(request, predicates, queryPlan, query.isCountDistinct());
|
return new CQueryFetchSingleAttribute(request, predicates, queryPlan, query.isCountDistinct());
|
||||||
}
|
}
|
||||||
@@ -288,7 +288,7 @@ final class CQueryBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// cache the query plan
|
// cache the query plan
|
||||||
queryPlan = new CQueryPlan(request, sql, sqlTree, predicates.getLogWhereSql());
|
queryPlan = new CQueryPlan(request, sql, sqlTree.plan(), predicates.getLogWhereSql());
|
||||||
request.putQueryPlan(queryPlan);
|
request.putQueryPlan(queryPlan);
|
||||||
return new CQueryRowCount(queryPlan, request, predicates);
|
return new CQueryRowCount(queryPlan, request, predicates);
|
||||||
}
|
}
|
||||||
@@ -343,7 +343,7 @@ final class CQueryBuilder {
|
|||||||
if (rawSql) {
|
if (rawSql) {
|
||||||
queryPlan = new CQueryPlanRawSql(request, res, sqlTree, predicates.getLogWhereSql());
|
queryPlan = new CQueryPlanRawSql(request, res, sqlTree, predicates.getLogWhereSql());
|
||||||
} else {
|
} else {
|
||||||
queryPlan = new CQueryPlan(request, res, sqlTree, false, predicates.getLogWhereSql());
|
queryPlan = new CQueryPlan(request, res, sqlTree.plan(), false, predicates.getLogWhereSql());
|
||||||
}
|
}
|
||||||
BeanDescriptor<T> desc = request.descriptor();
|
BeanDescriptor<T> desc = request.descriptor();
|
||||||
if (desc.isReadAuditing()) {
|
if (desc.isReadAuditing()) {
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class CQueryPlan implements SpiQueryPlan {
|
|||||||
private final String sql;
|
private final String sql;
|
||||||
private final String hash;
|
private final String hash;
|
||||||
private final String logWhereSql;
|
private final String logWhereSql;
|
||||||
private final SqlTree sqlTree;
|
private final SqlTreePlan sqlTree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypted properties required additional binding.
|
* Encrypted properties required additional binding.
|
||||||
@@ -76,7 +76,7 @@ public class CQueryPlan implements SpiQueryPlan {
|
|||||||
/**
|
/**
|
||||||
* Create a query plan based on a OrmQueryRequest.
|
* Create a query plan based on a OrmQueryRequest.
|
||||||
*/
|
*/
|
||||||
CQueryPlan(OrmQueryRequest<?> request, SqlLimitResponse sqlRes, SqlTree sqlTree, boolean rawSql, String logWhereSql) {
|
CQueryPlan(OrmQueryRequest<?> request, SqlLimitResponse sqlRes, SqlTreePlan sqlTree, boolean rawSql, String logWhereSql) {
|
||||||
this.server = request.server();
|
this.server = request.server();
|
||||||
this.dataTimeZone = server.dataTimeZone();
|
this.dataTimeZone = server.dataTimeZone();
|
||||||
this.beanType = request.descriptor().type();
|
this.beanType = request.descriptor().type();
|
||||||
@@ -101,7 +101,7 @@ public class CQueryPlan implements SpiQueryPlan {
|
|||||||
/**
|
/**
|
||||||
* Create a query plan for a raw sql query.
|
* Create a query plan for a raw sql query.
|
||||||
*/
|
*/
|
||||||
CQueryPlan(OrmQueryRequest<?> request, String sql, SqlTree sqlTree, String logWhereSql) {
|
CQueryPlan(OrmQueryRequest<?> request, String sql, SqlTreePlan sqlTree, String logWhereSql) {
|
||||||
this.server = request.server();
|
this.server = request.server();
|
||||||
this.dataTimeZone = server.dataTimeZone();
|
this.dataTimeZone = server.dataTimeZone();
|
||||||
this.beanType = request.descriptor().type();
|
this.beanType = request.descriptor().type();
|
||||||
@@ -249,7 +249,7 @@ public class CQueryPlan implements SpiQueryPlan {
|
|||||||
return rawSql ? planKey.getPartialKey() + "_" + hash : planKey.getPartialKey();
|
return rawSql ? planKey.getPartialKey() + "_" + hash : planKey.getPartialKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
final SqlTree getSqlTree() {
|
final SqlTreePlan getSqlTree() {
|
||||||
return sqlTree;
|
return sqlTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ final class CQueryPlanRawSql extends CQueryPlan {
|
|||||||
private final int[] rsetIndexPositions;
|
private final int[] rsetIndexPositions;
|
||||||
|
|
||||||
CQueryPlanRawSql(OrmQueryRequest<?> request, SqlLimitResponse sqlRes, SqlTree sqlTree, String logWhereSql) {
|
CQueryPlanRawSql(OrmQueryRequest<?> request, SqlLimitResponse sqlRes, SqlTree sqlTree, String logWhereSql) {
|
||||||
super(request, sqlRes, sqlTree, true, logWhereSql);
|
super(request, sqlRes, sqlTree.plan(), true, logWhereSql);
|
||||||
this.rsetIndexPositions = createIndexPositions(request, sqlTree);
|
this.rsetIndexPositions = createIndexPositions(request, sqlTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ final class SqlTree {
|
|||||||
this.noJoins = !includeJoins;
|
this.noJoins = !includeJoins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SqlTreePlan plan() {
|
||||||
|
return new SqlTreePlan(rootNode.createLoad(), manyProperty, encryptedProps, dependentTables());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the query mandates SQL Distinct due to ToMany inclusion.
|
* Return true if the query mandates SQL Distinct due to ToMany inclusion.
|
||||||
*/
|
*/
|
||||||
@@ -123,10 +127,6 @@ final class SqlTree {
|
|||||||
return inheritanceWhereSql;
|
return inheritanceWhereSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
SqlTreeRoot getRootNode() {
|
|
||||||
return (SqlTreeRoot)rootNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the property that is associated with the many. There can only be one
|
* Return the property that is associated with the many. There can only be one
|
||||||
* per SqlSelect. This can be null.
|
* per SqlSelect. This can be null.
|
||||||
@@ -135,10 +135,6 @@ final class SqlTree {
|
|||||||
return manyProperty;
|
return manyProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
STreeProperty[] getEncryptedProps() {
|
|
||||||
return encryptedProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the query has a many join.
|
* Return true if the query has a many join.
|
||||||
*/
|
*/
|
||||||
@@ -153,7 +149,7 @@ final class SqlTree {
|
|||||||
/**
|
/**
|
||||||
* Return the tables that are joined in this query.
|
* Return the tables that are joined in this query.
|
||||||
*/
|
*/
|
||||||
Set<String> dependentTables() {
|
private Set<String> dependentTables() {
|
||||||
Set<String> tables = new LinkedHashSet<>();
|
Set<String> tables = new LinkedHashSet<>();
|
||||||
rootNode.dependentTables(tables);
|
rootNode.dependentTables(tables);
|
||||||
return tables;
|
return tables;
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
|
import io.ebean.bean.EntityBean;
|
||||||
|
import io.ebean.core.type.ScalarDataReader;
|
||||||
|
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tree node that loads an entity bean type.
|
||||||
|
*/
|
||||||
|
interface SqlTreeLoad {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the appropriate information from the SqlSelectReader.
|
||||||
|
* <p>
|
||||||
|
* At a high level this actually controls the reading of the data from the
|
||||||
|
* jdbc resultSet and putting it into the bean etc.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
EntityBean load(DbReadContext ctx, EntityBean localBean, EntityBean contextBean) throws SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the reader for the single attribute query.
|
||||||
|
*/
|
||||||
|
ScalarDataReader<?> getSingleAttributeReader();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,373 @@
|
|||||||
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
|
import io.ebean.bean.BeanCollection;
|
||||||
|
import io.ebean.bean.EntityBean;
|
||||||
|
import io.ebean.bean.EntityBeanIntercept;
|
||||||
|
import io.ebean.bean.PersistenceContext;
|
||||||
|
import io.ebean.core.type.ScalarDataReader;
|
||||||
|
import io.ebeaninternal.api.SpiQuery;
|
||||||
|
import io.ebeaninternal.api.SpiQuery.Mode;
|
||||||
|
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||||
|
import io.ebeaninternal.server.deploy.InheritInfo;
|
||||||
|
import io.ebeaninternal.server.deploy.id.IdBinder;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normal bean included in the query.
|
||||||
|
*/
|
||||||
|
class SqlTreeLoadBean implements SqlTreeLoad {
|
||||||
|
|
||||||
|
final STreeType desc;
|
||||||
|
final IdBinder idBinder;
|
||||||
|
final SqlTreeLoad[] children;
|
||||||
|
private final boolean partialObject;
|
||||||
|
private final STreeProperty[] properties;
|
||||||
|
private final STreePropertyAssoc nodeBeanProp;
|
||||||
|
final boolean readId;
|
||||||
|
private final boolean readIdNormal;
|
||||||
|
private final boolean disableLazyLoad;
|
||||||
|
private final InheritInfo inheritInfo;
|
||||||
|
final String prefix;
|
||||||
|
private final Map<String, String> pathMap;
|
||||||
|
final STreePropertyAssocMany lazyLoadParent;
|
||||||
|
private final SpiQuery.TemporalMode temporalMode;
|
||||||
|
private final boolean temporalVersions;
|
||||||
|
final IdBinder lazyLoadParentIdBinder;
|
||||||
|
|
||||||
|
SqlTreeLoadBean(SqlTreeNodeBean node) {
|
||||||
|
this.lazyLoadParent = node.lazyLoadParent;
|
||||||
|
this.lazyLoadParentIdBinder = node.lazyLoadParentIdBinder;
|
||||||
|
this.prefix = node.prefix;
|
||||||
|
this.desc = node.desc;
|
||||||
|
this.inheritInfo = desc.inheritInfo();
|
||||||
|
this.idBinder = desc.idBinder();
|
||||||
|
this.temporalMode = node.temporalMode;
|
||||||
|
this.temporalVersions = node.temporalVersions;
|
||||||
|
this.nodeBeanProp = node.nodeBeanProp;
|
||||||
|
this.readId = node.readId;//!aggregationRoot && withId && desc.hasId();
|
||||||
|
this.readIdNormal = readId && !temporalVersions;
|
||||||
|
this.disableLazyLoad = node.disableLazyLoad;// disableLazyLoad || !readIdNormal || desc.isRawSqlBased();
|
||||||
|
this.partialObject = node.partialObject;//props.isPartialObject();
|
||||||
|
this.properties = node.properties;//props.getProps();
|
||||||
|
this.pathMap = node.pathMap;//createPathMap(prefix, desc);
|
||||||
|
this.children = node.createLoadChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isRoot() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ScalarDataReader<?> getSingleAttributeReader() {
|
||||||
|
if (properties == null || properties.length == 0) {
|
||||||
|
// if we have no property ask first children (in a distinct select with join)
|
||||||
|
if (children.length == 0) {
|
||||||
|
// expected to be a findIds query
|
||||||
|
return desc.idBinder().getBeanProperty();
|
||||||
|
}
|
||||||
|
return children[0].getSingleAttributeReader();
|
||||||
|
}
|
||||||
|
if (properties[0] instanceof STreePropertyAssocOne) {
|
||||||
|
STreePropertyAssocOne assocOne = (STreePropertyAssocOne)properties[0];
|
||||||
|
if (assocOne.isAssocId()) {
|
||||||
|
return assocOne.idReader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return properties[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load that takes into account inheritance.
|
||||||
|
*/
|
||||||
|
private final class LoadInherit extends Load {
|
||||||
|
|
||||||
|
private LoadInherit(DbReadContext ctx, EntityBean parentBean) {
|
||||||
|
super(ctx, parentBean);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void initBeanType() throws SQLException {
|
||||||
|
InheritInfo localInfo = readId ? inheritInfo.readType(ctx) : desc.inheritInfo();
|
||||||
|
if (localInfo == null) {
|
||||||
|
// the bean must be null
|
||||||
|
localIdBinder = idBinder;
|
||||||
|
localDesc = desc;
|
||||||
|
} else {
|
||||||
|
localBean = localInfo.createEntityBean();
|
||||||
|
localType = localInfo.getType();
|
||||||
|
localIdBinder = localInfo.getIdBinder();
|
||||||
|
localDesc = localInfo.desc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void loadProperties() {
|
||||||
|
// take account of inheritance
|
||||||
|
for (STreeProperty property : properties) {
|
||||||
|
localDesc.inheritanceLoad(sqlBeanLoad, property, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a bean instance.
|
||||||
|
*/
|
||||||
|
class Load {
|
||||||
|
|
||||||
|
final DbReadContext ctx;
|
||||||
|
final EntityBean parentBean;
|
||||||
|
|
||||||
|
Object lazyLoadParentId;
|
||||||
|
Class<?> localType;
|
||||||
|
STreeType localDesc;
|
||||||
|
IdBinder localIdBinder;
|
||||||
|
EntityBean localBean;
|
||||||
|
|
||||||
|
Mode queryMode;
|
||||||
|
PersistenceContext persistenceContext;
|
||||||
|
Object id;
|
||||||
|
EntityBean contextBean;
|
||||||
|
SqlBeanLoad sqlBeanLoad;
|
||||||
|
boolean lazyLoadMany;
|
||||||
|
|
||||||
|
private Load(DbReadContext ctx, EntityBean parentBean) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.parentBean = parentBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initLazyParent() throws SQLException {
|
||||||
|
if (lazyLoadParentIdBinder != null) {
|
||||||
|
lazyLoadParentId = lazyLoadParentIdBinder.read(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initBeanType() throws SQLException {
|
||||||
|
localDesc = desc;
|
||||||
|
localBean = desc.createEntityBean();
|
||||||
|
localIdBinder = idBinder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPersistenceContext() {
|
||||||
|
queryMode = ctx.getQueryMode();
|
||||||
|
persistenceContext = (!readIdNormal) ? null : ctx.getPersistenceContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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 {
|
||||||
|
// bean already exists in persistenceContext
|
||||||
|
|
||||||
|
if (queryMode.isLoadContextBean()) {
|
||||||
|
// if explicitly set loadContextBean to true, then reload
|
||||||
|
localBean = contextBean;
|
||||||
|
} else if (!contextBean._ebean_getIntercept().isFullyLoadedBean()) {
|
||||||
|
// reload if contextBean is partial object
|
||||||
|
localBean = contextBean;
|
||||||
|
// and switch to lazyLoad query mode in order not to overwrite
|
||||||
|
// existing properties in SqlBeanLoad::load
|
||||||
|
queryMode = Mode.LAZYLOAD_BEAN;
|
||||||
|
} else {
|
||||||
|
// ignore the DB data...
|
||||||
|
localBean = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSqlLoadBean() {
|
||||||
|
ctx.setCurrentPrefix(prefix, pathMap);
|
||||||
|
ctx.propagateState(localBean);
|
||||||
|
sqlBeanLoad = new SqlBeanLoad(ctx, localType, localBean, queryMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadProperties() {
|
||||||
|
for (STreeProperty property : properties) {
|
||||||
|
property.load(sqlBeanLoad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadChildren() throws SQLException {
|
||||||
|
if (localBean == null && queryMode == Mode.LAZYLOAD_MANY) {
|
||||||
|
// batch lazy load many into existing contextBean
|
||||||
|
localBean = contextBean;
|
||||||
|
lazyLoadMany = true;
|
||||||
|
}
|
||||||
|
for (SqlTreeLoad child : children) {
|
||||||
|
child.load(ctx, localBean, contextBean);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLazyLoadManyRoot() {
|
||||||
|
return queryMode == Mode.LAZYLOAD_MANY && isRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityBean getContextBean() {
|
||||||
|
return contextBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void postLoad() {
|
||||||
|
if (!lazyLoadMany && localBean != null) {
|
||||||
|
ctx.setCurrentPrefix(prefix, pathMap);
|
||||||
|
if (readIdNormal) {
|
||||||
|
createListProxies();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create lazy loading proxies for the Many's except for the one that is
|
||||||
|
* included in the actual query.
|
||||||
|
*/
|
||||||
|
private void createListProxies() {
|
||||||
|
STreePropertyAssocMany fetchedMany = ctx.getManyProperty();
|
||||||
|
boolean forceNewReference = queryMode == Mode.REFRESH_BEAN;
|
||||||
|
for (STreePropertyAssocMany many : localDesc.propsMany()) {
|
||||||
|
if (many != fetchedMany) {
|
||||||
|
// create a proxy for the many (deferred fetching)
|
||||||
|
BeanCollection<?> ref = many.createReference(localBean, forceNewReference);
|
||||||
|
if (ref != null) {
|
||||||
|
if (disableLazyLoad) {
|
||||||
|
ref.setDisableLazyLoad(true);
|
||||||
|
}
|
||||||
|
if (!ref.isRegisteredWithLoadContext()) {
|
||||||
|
ctx.register(many.asMany(), ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBeanToParent() {
|
||||||
|
if (parentBean != null) {
|
||||||
|
// set this back to the parentBean
|
||||||
|
nodeBeanProp.setValue(parentBean, contextBean);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityBean complete() {
|
||||||
|
if (!readIdNormal) {
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialise() throws SQLException {
|
||||||
|
initLazyParent();
|
||||||
|
initBeanType();
|
||||||
|
initPersistenceContext();
|
||||||
|
readId();
|
||||||
|
initSqlLoadBean();
|
||||||
|
loadProperties();
|
||||||
|
loadChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the load returning the loaded bean.
|
||||||
|
*/
|
||||||
|
final EntityBean perform() throws SQLException {
|
||||||
|
initialise();
|
||||||
|
if (isLazyLoadManyRoot()) {
|
||||||
|
return getContextBean();
|
||||||
|
}
|
||||||
|
postLoad();
|
||||||
|
setBeanToParent();
|
||||||
|
return complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if this bean was already in the context. If already in the
|
||||||
|
* context we need to check if it is already contained in the collection.
|
||||||
|
*/
|
||||||
|
final boolean isContextBean() {
|
||||||
|
return localBean == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read the properties from the resultSet.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EntityBean load(DbReadContext ctx, EntityBean parentBean, EntityBean contextParent) throws SQLException {
|
||||||
|
return createLoad(ctx, parentBean).perform();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the loader with or without inheritance.
|
||||||
|
*/
|
||||||
|
final Load createLoad(DbReadContext ctx, EntityBean parentBean) {
|
||||||
|
return (inheritInfo != null) ? new LoadInherit(ctx, parentBean) : new Load(ctx, parentBean);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SqlTreeLoadBean: " + desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
|
import io.ebean.bean.EntityBean;
|
||||||
|
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
final class SqlTreeLoadManyRoot extends SqlTreeLoadBean {
|
||||||
|
|
||||||
|
private final STreePropertyAssocMany manyProp;
|
||||||
|
|
||||||
|
SqlTreeLoadManyRoot(SqlTreeNodeManyRoot node) {
|
||||||
|
super(node);
|
||||||
|
this.manyProp = node.manyProp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityBean load(DbReadContext cquery, EntityBean parentBean, EntityBean contextParent) throws SQLException {
|
||||||
|
// pass in null for parentBean because added to a collection rather than set to the parentBean
|
||||||
|
Load load = createLoad(cquery, null);
|
||||||
|
EntityBean detailBean = load.perform();
|
||||||
|
if (contextParent != null) {
|
||||||
|
// Add to the collection and initialise collection if needed
|
||||||
|
// A null detailBean may initialise an empty collection
|
||||||
|
// Check for bean existing in collection based on load.isContextBean()
|
||||||
|
manyProp.addBeanToCollectionWithCreate(contextParent, detailBean, load.isContextBean());
|
||||||
|
}
|
||||||
|
return detailBean;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
|
import io.ebean.Version;
|
||||||
|
import io.ebean.bean.EntityBean;
|
||||||
|
import io.ebeaninternal.server.deploy.DbReadContext;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the root node of the Sql Tree.
|
||||||
|
*/
|
||||||
|
final class SqlTreeLoadRoot extends SqlTreeLoadBean implements SqlTreeRoot {
|
||||||
|
|
||||||
|
SqlTreeLoadRoot(SqlTreeNodeBean node) {
|
||||||
|
super(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isRoot() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityBean load(DbReadContext ctx) throws SQLException {
|
||||||
|
return load(ctx, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the version bean.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> Version<T> loadVersion(DbReadContext ctx) throws SQLException {
|
||||||
|
// read the sys period lower and upper bounds
|
||||||
|
// these are always the first 2 columns in the resultSet
|
||||||
|
Timestamp start = ctx.getDataReader().getTimestamp();
|
||||||
|
Timestamp end = ctx.getDataReader().getTimestamp();
|
||||||
|
T bean = (T) load(ctx, null, null);
|
||||||
|
return new Version<>(bean, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,8 @@
|
|||||||
package io.ebeaninternal.server.query;
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
import io.ebean.Version;
|
|
||||||
import io.ebean.bean.EntityBean;
|
|
||||||
import io.ebean.core.type.ScalarDataReader;
|
|
||||||
import io.ebeaninternal.api.SpiQuery;
|
import io.ebeaninternal.api.SpiQuery;
|
||||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
|
||||||
import io.ebeaninternal.server.deploy.DbSqlContext;
|
import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -64,25 +59,11 @@ interface SqlTreeNode {
|
|||||||
*/
|
*/
|
||||||
void addSoftDeletePredicate(SpiQuery<?> query);
|
void addSoftDeletePredicate(SpiQuery<?> query);
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the appropriate information from the SqlSelectReader.
|
|
||||||
* <p>
|
|
||||||
* At a high level this actually controls the reading of the data from the
|
|
||||||
* jdbc resultSet and putting it into the bean etc.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
EntityBean load(DbReadContext ctx, EntityBean localBean, EntityBean contextBean) throws SQLException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the query has a many join.
|
* Return true if the query has a many join.
|
||||||
*/
|
*/
|
||||||
boolean hasMany();
|
boolean hasMany();
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the reader for the single attribute query.
|
|
||||||
*/
|
|
||||||
ScalarDataReader<?> getSingleAttributeReader();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the query is known to only have a single property selected.
|
* Return true if the query is known to only have a single property selected.
|
||||||
*/
|
*/
|
||||||
@@ -92,4 +73,9 @@ interface SqlTreeNode {
|
|||||||
* Add dependent tables to the given set.
|
* Add dependent tables to the given set.
|
||||||
*/
|
*/
|
||||||
void dependentTables(Set<String> tables);
|
void dependentTables(Set<String> tables);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the loader for this node.
|
||||||
|
*/
|
||||||
|
SqlTreeLoad createLoad();
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,20 @@
|
|||||||
package io.ebeaninternal.server.query;
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
import io.ebean.bean.BeanCollection;
|
|
||||||
import io.ebean.bean.EntityBean;
|
|
||||||
import io.ebean.bean.EntityBeanIntercept;
|
|
||||||
import io.ebean.bean.PersistenceContext;
|
|
||||||
import io.ebean.core.type.ScalarDataReader;
|
|
||||||
import io.ebean.util.SplitName;
|
import io.ebean.util.SplitName;
|
||||||
import io.ebeaninternal.api.SpiQuery;
|
import io.ebeaninternal.api.SpiQuery;
|
||||||
import io.ebeaninternal.api.SpiQuery.Mode;
|
|
||||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
|
||||||
import io.ebeaninternal.server.deploy.DbSqlContext;
|
import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||||
import io.ebeaninternal.server.deploy.InheritInfo;
|
import io.ebeaninternal.server.deploy.InheritInfo;
|
||||||
import io.ebeaninternal.server.deploy.TableJoin;
|
import io.ebeaninternal.server.deploy.TableJoin;
|
||||||
import io.ebeaninternal.server.deploy.id.IdBinder;
|
import io.ebeaninternal.server.deploy.id.IdBinder;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normal bean included in the query.
|
* Normal bean included in the query.
|
||||||
*/
|
*/
|
||||||
class SqlTreeNodeBean implements SqlTreeNode {
|
class SqlTreeNodeBean implements SqlTreeNode {
|
||||||
|
|
||||||
|
private static final SqlTreeLoad[] NO_LOAD_CHILDREN = new SqlTreeLoad[0];
|
||||||
private static final SqlTreeNode[] NO_CHILDREN = new SqlTreeNode[0];
|
private static final SqlTreeNode[] NO_CHILDREN = new SqlTreeNode[0];
|
||||||
|
|
||||||
final STreeType desc;
|
final STreeType desc;
|
||||||
@@ -36,33 +26,33 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
|||||||
/**
|
/**
|
||||||
* Set to true if this is a partial object fetch.
|
* Set to true if this is a partial object fetch.
|
||||||
*/
|
*/
|
||||||
private final boolean partialObject;
|
final boolean partialObject;
|
||||||
private final STreeProperty[] properties;
|
final STreeProperty[] properties;
|
||||||
/**
|
/**
|
||||||
* Extra where clause added by Where annotation on associated many.
|
* Extra where clause added by Where annotation on associated many.
|
||||||
*/
|
*/
|
||||||
private final String extraWhere;
|
final String extraWhere;
|
||||||
private final STreePropertyAssoc nodeBeanProp;
|
final STreePropertyAssoc nodeBeanProp;
|
||||||
/**
|
/**
|
||||||
* False if report bean and has no id property.
|
* False if report bean and has no id property.
|
||||||
*/
|
*/
|
||||||
final boolean readId;
|
final boolean readId;
|
||||||
private final boolean readIdNormal;
|
final boolean readIdNormal;
|
||||||
private final boolean disableLazyLoad;
|
final boolean disableLazyLoad;
|
||||||
private final InheritInfo inheritInfo;
|
final InheritInfo inheritInfo;
|
||||||
final String prefix;
|
final String prefix;
|
||||||
private final Map<String, String> pathMap;
|
final Map<String, String> pathMap;
|
||||||
final STreePropertyAssocMany lazyLoadParent;
|
final STreePropertyAssocMany lazyLoadParent;
|
||||||
private final SpiQuery.TemporalMode temporalMode;
|
final SpiQuery.TemporalMode temporalMode;
|
||||||
private final boolean temporalVersions;
|
final boolean temporalVersions;
|
||||||
private final IdBinder lazyLoadParentIdBinder;
|
final IdBinder lazyLoadParentIdBinder;
|
||||||
String baseTableAlias;
|
String baseTableAlias;
|
||||||
/**
|
/**
|
||||||
* Table alias set if this bean node includes a join to a intersection
|
* Table alias set if this bean node includes a join to a intersection
|
||||||
* table and that table has history support.
|
* table and that table has history support.
|
||||||
*/
|
*/
|
||||||
private boolean intersectionAsOfTableAlias;
|
boolean intersectionAsOfTableAlias;
|
||||||
private final boolean aggregation;
|
final boolean aggregation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct for leaf node.
|
* Construct for leaf node.
|
||||||
@@ -108,8 +98,23 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
|||||||
pathMap = createPathMap(prefix, desc);
|
pathMap = createPathMap(prefix, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isRoot() {
|
@Override
|
||||||
return false;
|
public SqlTreeLoad createLoad() {
|
||||||
|
return new SqlTreeLoadBean(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SqlTreeLoad[] createLoadChildren() {
|
||||||
|
if (children.length == 0) {
|
||||||
|
return NO_LOAD_CHILDREN;
|
||||||
|
}
|
||||||
|
List<SqlTreeLoad> loadChildren = new ArrayList<>(children.length);
|
||||||
|
for (SqlTreeNode child : children) {
|
||||||
|
SqlTreeLoad load = child.createLoad();
|
||||||
|
if (load != null) {
|
||||||
|
loadChildren.add(load);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loadChildren.toArray(new SqlTreeLoad[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -117,25 +122,6 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
|||||||
return properties != null && properties.length == 1 && children.length == 0;
|
return properties != null && properties.length == 1 && children.length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final ScalarDataReader<?> getSingleAttributeReader() {
|
|
||||||
if (properties == null || properties.length == 0) {
|
|
||||||
// if we have no property ask first children (in a distinct select with join)
|
|
||||||
if (children.length == 0) {
|
|
||||||
// expected to be a findIds query
|
|
||||||
return desc.idBinder().getBeanProperty();
|
|
||||||
}
|
|
||||||
return children[0].getSingleAttributeReader();
|
|
||||||
}
|
|
||||||
if (properties[0] instanceof STreePropertyAssocOne) {
|
|
||||||
STreePropertyAssocOne assocOne = (STreePropertyAssocOne)properties[0];
|
|
||||||
if (assocOne.isAssocId()) {
|
|
||||||
return assocOne.idReader();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return properties[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> createPathMap(String prefix, STreeType desc) {
|
private Map<String, String> createPathMap(String prefix, STreeType desc) {
|
||||||
HashMap<String, String> m = new HashMap<>();
|
HashMap<String, String> m = new HashMap<>();
|
||||||
for (STreePropertyAssocMany many : desc.propsMany()) {
|
for (STreePropertyAssocMany many : desc.propsMany()) {
|
||||||
@@ -173,293 +159,6 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Load that takes into account inheritance.
|
|
||||||
*/
|
|
||||||
private final class LoadInherit extends Load {
|
|
||||||
|
|
||||||
private LoadInherit(DbReadContext ctx, EntityBean parentBean) {
|
|
||||||
super(ctx, parentBean);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void initBeanType() throws SQLException {
|
|
||||||
InheritInfo localInfo = readId ? inheritInfo.readType(ctx) : desc.inheritInfo();
|
|
||||||
if (localInfo == null) {
|
|
||||||
// the bean must be null
|
|
||||||
localIdBinder = idBinder;
|
|
||||||
localDesc = desc;
|
|
||||||
} else {
|
|
||||||
localBean = localInfo.createEntityBean();
|
|
||||||
localType = localInfo.getType();
|
|
||||||
localIdBinder = localInfo.getIdBinder();
|
|
||||||
localDesc = localInfo.desc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void loadProperties() {
|
|
||||||
// take account of inheritance
|
|
||||||
for (STreeProperty property : properties) {
|
|
||||||
localDesc.inheritanceLoad(sqlBeanLoad, property, ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a bean instance.
|
|
||||||
*/
|
|
||||||
class Load {
|
|
||||||
|
|
||||||
final DbReadContext ctx;
|
|
||||||
final EntityBean parentBean;
|
|
||||||
|
|
||||||
Object lazyLoadParentId;
|
|
||||||
Class<?> localType;
|
|
||||||
STreeType localDesc;
|
|
||||||
IdBinder localIdBinder;
|
|
||||||
EntityBean localBean;
|
|
||||||
|
|
||||||
Mode queryMode;
|
|
||||||
PersistenceContext persistenceContext;
|
|
||||||
Object id;
|
|
||||||
EntityBean contextBean;
|
|
||||||
SqlBeanLoad sqlBeanLoad;
|
|
||||||
boolean lazyLoadMany;
|
|
||||||
|
|
||||||
private Load(DbReadContext ctx, EntityBean parentBean) {
|
|
||||||
this.ctx = ctx;
|
|
||||||
this.parentBean = parentBean;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initLazyParent() throws SQLException {
|
|
||||||
if (lazyLoadParentIdBinder != null) {
|
|
||||||
lazyLoadParentId = lazyLoadParentIdBinder.read(ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void initBeanType() throws SQLException {
|
|
||||||
localDesc = desc;
|
|
||||||
localBean = desc.createEntityBean();
|
|
||||||
localIdBinder = idBinder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initPersistenceContext() {
|
|
||||||
queryMode = ctx.getQueryMode();
|
|
||||||
persistenceContext = (!readIdNormal) ? null : ctx.getPersistenceContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
private 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 {
|
|
||||||
// bean already exists in persistenceContext
|
|
||||||
|
|
||||||
if (queryMode.isLoadContextBean()) {
|
|
||||||
// if explicitly set loadContextBean to true, then reload
|
|
||||||
localBean = contextBean;
|
|
||||||
} else if (!contextBean._ebean_getIntercept().isFullyLoadedBean()) {
|
|
||||||
// reload if contextBean is partial object
|
|
||||||
localBean = contextBean;
|
|
||||||
// and switch to lazyLoad query mode in order not to overwrite
|
|
||||||
// existing properties in SqlBeanLoad::load
|
|
||||||
queryMode = Mode.LAZYLOAD_BEAN;
|
|
||||||
} else {
|
|
||||||
// ignore the DB data...
|
|
||||||
localBean = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initSqlLoadBean() {
|
|
||||||
ctx.setCurrentPrefix(prefix, pathMap);
|
|
||||||
ctx.propagateState(localBean);
|
|
||||||
sqlBeanLoad = new SqlBeanLoad(ctx, localType, localBean, queryMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadProperties() {
|
|
||||||
for (STreeProperty property : properties) {
|
|
||||||
property.load(sqlBeanLoad);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadChildren() throws SQLException {
|
|
||||||
if (localBean == null && queryMode == Mode.LAZYLOAD_MANY) {
|
|
||||||
// batch lazy load many into existing contextBean
|
|
||||||
localBean = contextBean;
|
|
||||||
lazyLoadMany = true;
|
|
||||||
}
|
|
||||||
for (SqlTreeNode child : children) {
|
|
||||||
child.load(ctx, localBean, contextBean);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isLazyLoadManyRoot() {
|
|
||||||
return queryMode == Mode.LAZYLOAD_MANY && isRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
private EntityBean getContextBean() {
|
|
||||||
return contextBean;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postLoad() {
|
|
||||||
if (!lazyLoadMany && localBean != null) {
|
|
||||||
ctx.setCurrentPrefix(prefix, pathMap);
|
|
||||||
if (readIdNormal) {
|
|
||||||
createListProxies();
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create lazy loading proxies for the Many's except for the one that is
|
|
||||||
* included in the actual query.
|
|
||||||
*/
|
|
||||||
private void createListProxies() {
|
|
||||||
STreePropertyAssocMany fetchedMany = ctx.getManyProperty();
|
|
||||||
boolean forceNewReference = queryMode == Mode.REFRESH_BEAN;
|
|
||||||
for (STreePropertyAssocMany many : localDesc.propsMany()) {
|
|
||||||
if (many != fetchedMany) {
|
|
||||||
// create a proxy for the many (deferred fetching)
|
|
||||||
BeanCollection<?> ref = many.createReference(localBean, forceNewReference);
|
|
||||||
if (ref != null) {
|
|
||||||
if (disableLazyLoad) {
|
|
||||||
ref.setDisableLazyLoad(true);
|
|
||||||
}
|
|
||||||
if (!ref.isRegisteredWithLoadContext()) {
|
|
||||||
ctx.register(many.asMany(), ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setBeanToParent() {
|
|
||||||
if (parentBean != null) {
|
|
||||||
// set this back to the parentBean
|
|
||||||
nodeBeanProp.setValue(parentBean, contextBean);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private EntityBean complete() {
|
|
||||||
if (!readIdNormal) {
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initialise() throws SQLException {
|
|
||||||
initLazyParent();
|
|
||||||
initBeanType();
|
|
||||||
initPersistenceContext();
|
|
||||||
readId();
|
|
||||||
initSqlLoadBean();
|
|
||||||
loadProperties();
|
|
||||||
loadChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform the load returning the loaded bean.
|
|
||||||
*/
|
|
||||||
final EntityBean perform() throws SQLException {
|
|
||||||
initialise();
|
|
||||||
if (isLazyLoadManyRoot()) {
|
|
||||||
return getContextBean();
|
|
||||||
}
|
|
||||||
postLoad();
|
|
||||||
setBeanToParent();
|
|
||||||
return complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if this bean was already in the context. If already in the
|
|
||||||
* context we need to check if it is already contained in the collection.
|
|
||||||
*/
|
|
||||||
final boolean isContextBean() {
|
|
||||||
return localBean == null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* read the properties from the resultSet.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public EntityBean load(DbReadContext ctx, EntityBean parentBean, EntityBean contextParent) throws SQLException {
|
|
||||||
return createLoad(ctx, parentBean).perform();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the loader with or without inheritance.
|
|
||||||
*/
|
|
||||||
final Load createLoad(DbReadContext ctx, EntityBean parentBean) {
|
|
||||||
return (inheritInfo != null) ? new LoadInherit(ctx, parentBean) : new Load(ctx, parentBean);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void appendGroupBy(DbSqlContext ctx, boolean subQuery) {
|
public final void appendGroupBy(DbSqlContext ctx, boolean subQuery) {
|
||||||
ctx.pushJoin(prefix);
|
ctx.pushJoin(prefix);
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ final class SqlTreeNodeExtraJoin implements SqlTreeNode {
|
|||||||
this.manyJoin = assocBeanProperty instanceof STreePropertyAssocMany;
|
this.manyJoin = assocBeanProperty instanceof STreePropertyAssocMany;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SqlTreeLoad createLoad() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSingleProperty() {
|
public boolean isSingleProperty() {
|
||||||
return false;
|
return false;
|
||||||
@@ -73,11 +78,6 @@ final class SqlTreeNodeExtraJoin implements SqlTreeNode {
|
|||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ScalarType<?> getSingleAttributeReader() {
|
|
||||||
throw new IllegalStateException("No expected");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the extra join is a many join.
|
* Return true if the extra join is a many join.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -184,14 +184,6 @@ final class SqlTreeNodeExtraJoin implements SqlTreeNode {
|
|||||||
public void appendWhere(DbSqlContext ctx) {
|
public void appendWhere(DbSqlContext ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Does nothing.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public EntityBean load(DbReadContext ctx, EntityBean localBean, EntityBean parentBean) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMany() {
|
public boolean hasMany() {
|
||||||
return manyJoin;
|
return manyJoin;
|
||||||
|
|||||||
+4
-10
@@ -33,13 +33,13 @@ final class SqlTreeNodeFormulaWhereJoin implements SqlTreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSingleProperty() {
|
public SqlTreeLoad createLoad() {
|
||||||
return true;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ScalarType<?> getSingleAttributeReader() {
|
public boolean isSingleProperty() {
|
||||||
throw new IllegalStateException("No expected");
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -98,12 +98,6 @@ final class SqlTreeNodeFormulaWhereJoin implements SqlTreeNode {
|
|||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityBean load(DbReadContext ctx, EntityBean localBean, EntityBean parentBean) {
|
|
||||||
// nothing to do here
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMany() {
|
public boolean hasMany() {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
package io.ebeaninternal.server.query;
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
import io.ebean.bean.EntityBean;
|
|
||||||
import io.ebeaninternal.api.SpiQuery;
|
import io.ebeaninternal.api.SpiQuery;
|
||||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
|
||||||
import io.ebeaninternal.server.deploy.DbSqlContext;
|
import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
|
final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
|
||||||
|
|
||||||
private final STreePropertyAssocMany manyProp;
|
final STreePropertyAssocMany manyProp;
|
||||||
|
|
||||||
SqlTreeNodeManyRoot(String prefix, STreePropertyAssocMany prop, SqlTreeProperties props, List<SqlTreeNode> myList,
|
SqlTreeNodeManyRoot(String prefix, STreePropertyAssocMany prop, SqlTreeProperties props, List<SqlTreeNode> myList,
|
||||||
boolean withId, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad) {
|
boolean withId, SpiQuery.TemporalMode temporalMode, boolean disableLazyLoad) {
|
||||||
@@ -19,22 +16,13 @@ final class SqlTreeNodeManyRoot extends SqlTreeNodeBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMany() {
|
public SqlTreeLoad createLoad() {
|
||||||
return true;
|
return new SqlTreeLoadManyRoot(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityBean load(DbReadContext cquery, EntityBean parentBean, EntityBean contextParent) throws SQLException {
|
public boolean hasMany() {
|
||||||
// pass in null for parentBean because added to a collection rather than set to the parentBean
|
return true;
|
||||||
SqlTreeNodeBean.Load load = createLoad(cquery, null);
|
|
||||||
EntityBean detailBean = load.perform();
|
|
||||||
if (contextParent != null) {
|
|
||||||
// Add to the collection and initialise collection if needed
|
|
||||||
// A null detailBean may initialise an empty collection
|
|
||||||
// Check for bean existing in collection based on load.isContextBean()
|
|
||||||
manyProp.addBeanToCollectionWithCreate(contextParent, detailBean, load.isContextBean());
|
|
||||||
}
|
|
||||||
return detailBean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+4
-13
@@ -1,10 +1,7 @@
|
|||||||
package io.ebeaninternal.server.query;
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
import io.ebean.bean.EntityBean;
|
|
||||||
import io.ebean.core.type.ScalarType;
|
|
||||||
import io.ebean.util.SplitName;
|
import io.ebean.util.SplitName;
|
||||||
import io.ebeaninternal.api.SpiQuery;
|
import io.ebeaninternal.api.SpiQuery;
|
||||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
|
||||||
import io.ebeaninternal.server.deploy.DbSqlContext;
|
import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||||
import io.ebeaninternal.server.deploy.TableJoin;
|
import io.ebeaninternal.server.deploy.TableJoin;
|
||||||
|
|
||||||
@@ -37,13 +34,13 @@ final class SqlTreeNodeManyWhereJoin implements SqlTreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSingleProperty() {
|
public SqlTreeLoad createLoad() {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ScalarType<?> getSingleAttributeReader() {
|
public boolean isSingleProperty() {
|
||||||
throw new IllegalStateException("No expected");
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,12 +129,6 @@ final class SqlTreeNodeManyWhereJoin implements SqlTreeNode {
|
|||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityBean load(DbReadContext ctx, EntityBean localBean, EntityBean parentBean) {
|
|
||||||
// nothing to do here
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasMany() {
|
public boolean hasMany() {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,21 +1,16 @@
|
|||||||
package io.ebeaninternal.server.query;
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
import io.ebean.Version;
|
|
||||||
import io.ebean.bean.EntityBean;
|
|
||||||
import io.ebeaninternal.api.SpiQuery;
|
import io.ebeaninternal.api.SpiQuery;
|
||||||
import io.ebeaninternal.server.deploy.DbReadContext;
|
|
||||||
import io.ebeaninternal.server.deploy.DbSqlContext;
|
import io.ebeaninternal.server.deploy.DbSqlContext;
|
||||||
import io.ebeaninternal.server.deploy.TableJoin;
|
import io.ebeaninternal.server.deploy.TableJoin;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the root node of the Sql Tree.
|
* Represents the root node of the Sql Tree.
|
||||||
*/
|
*/
|
||||||
final class SqlTreeNodeRoot extends SqlTreeNodeBean implements SqlTreeRoot {
|
final class SqlTreeNodeRoot extends SqlTreeNodeBean {
|
||||||
|
|
||||||
private final TableJoin includeJoin;
|
private final TableJoin includeJoin;
|
||||||
private final boolean sqlDistinct;
|
private final boolean sqlDistinct;
|
||||||
@@ -34,27 +29,8 @@ final class SqlTreeNodeRoot extends SqlTreeNodeBean implements SqlTreeRoot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isRoot() {
|
public SqlTreeLoad createLoad() {
|
||||||
return true;
|
return new SqlTreeLoadRoot(this);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityBean load(DbReadContext ctx) throws SQLException {
|
|
||||||
return load(ctx, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the version bean.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> Version<T> loadVersion(DbReadContext ctx) throws SQLException {
|
|
||||||
// read the sys period lower and upper bounds
|
|
||||||
// these are always the first 2 columns in the resultSet
|
|
||||||
Timestamp start = ctx.getDataReader().getTimestamp();
|
|
||||||
Timestamp end = ctx.getDataReader().getTimestamp();
|
|
||||||
T bean = (T) load(ctx, null, null);
|
|
||||||
return new Version<>(bean, start, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package io.ebeaninternal.server.query;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
final class SqlTreePlan {
|
||||||
|
|
||||||
|
private final SqlTreeLoad rootNode;
|
||||||
|
private final STreePropertyAssocMany manyProperty;
|
||||||
|
private final STreeProperty[] encryptedProps;
|
||||||
|
private final Set<String> dependentTables;
|
||||||
|
|
||||||
|
SqlTreePlan(SqlTreeLoad rootNode, STreePropertyAssocMany manyProperty, STreeProperty[] encryptedProps, Set<String> dependentTables) {
|
||||||
|
this.rootNode = rootNode;
|
||||||
|
this.manyProperty = manyProperty;
|
||||||
|
this.encryptedProps = encryptedProps;
|
||||||
|
this.dependentTables = dependentTables;
|
||||||
|
}
|
||||||
|
|
||||||
|
SqlTreeRoot getRootNode() {
|
||||||
|
return (SqlTreeRoot)rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the property that is associated with the many. There can only be one
|
||||||
|
* per SqlSelect. This can be null.
|
||||||
|
*/
|
||||||
|
STreePropertyAssocMany getManyProperty() {
|
||||||
|
return manyProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
STreeProperty[] getEncryptedProps() {
|
||||||
|
return encryptedProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the tables that are joined in this query.
|
||||||
|
*/
|
||||||
|
Set<String> dependentTables() {
|
||||||
|
return dependentTables;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<!-- other tiles ... -->
|
<!-- other tiles ... -->
|
||||||
<tile>io.ebean.tile:enhancement:12.11.3</tile>
|
<tile>io.ebean.tile:enhancement:12.14.1</tile>
|
||||||
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<ebean-maven-plugin.version>12.13.0</ebean-maven-plugin.version>
|
<ebean-maven-plugin.version>12.14.1</ebean-maven-plugin.version>
|
||||||
<kotlin.version>1.6.0</kotlin.version>
|
<kotlin.version>1.6.0</kotlin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:12.11.3</tile>
|
<tile>io.ebean.tile:enhancement:12.14.1</tile>
|
||||||
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -100,7 +100,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:12.11.3</tile>
|
<tile>io.ebean.tile:enhancement:12.14.1</tile>
|
||||||
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
+1
-1
@@ -80,7 +80,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:12.11.3</tile>
|
<tile>io.ebean.tile:enhancement:12.14.1</tile>
|
||||||
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
+1
-1
@@ -249,7 +249,7 @@
|
|||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<tiles>
|
<tiles>
|
||||||
<tile>io.ebean.tile:enhancement:12.11.3</tile>
|
<tile>io.ebean.tile:enhancement:12.14.1</tile>
|
||||||
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
<tile>io.avaje.tile:moditech-module:1.0</tile>
|
||||||
</tiles>
|
</tiles>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
+2
-2
@@ -24,8 +24,8 @@ public class DefaultServer_getReferenceTest extends BaseTestCase {
|
|||||||
ResetBasicData.reset();
|
ResetBasicData.reset();
|
||||||
|
|
||||||
DB.execute(() -> {
|
DB.execute(() -> {
|
||||||
Customer loaded = DB.find(Customer.class, 1);
|
Customer loaded = DB.find(Customer.class).where().eq("name", "Rob").findOne();
|
||||||
Customer reference = DB.reference(Customer.class, 1);
|
Customer reference = DB.reference(Customer.class, loaded.getId());
|
||||||
assertThat(loaded).isSameAs(reference);
|
assertThat(loaded).isSameAs(reference);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -1,6 +1,7 @@
|
|||||||
package io.ebeaninternal.server.deploy;
|
package io.ebeaninternal.server.deploy;
|
||||||
|
|
||||||
import io.ebean.BaseTestCase;
|
import io.ebean.BaseTestCase;
|
||||||
|
import io.ebean.DB;
|
||||||
import io.ebean.bean.BeanCollection;
|
import io.ebean.bean.BeanCollection;
|
||||||
import io.ebean.bean.EntityBean;
|
import io.ebean.bean.EntityBean;
|
||||||
import io.ebean.common.BeanList;
|
import io.ebean.common.BeanList;
|
||||||
@@ -66,11 +67,13 @@ public class BeanPropertyAssocManyTest extends BaseTestCase {
|
|||||||
|
|
||||||
ResetBasicData.reset();
|
ResetBasicData.reset();
|
||||||
|
|
||||||
List<Object> customerIds = new ArrayList<>();
|
List<Long> ids = DB.find(Customer.class).orderBy("id").setMaxRows(2).findIds();
|
||||||
customerIds.add(1L);
|
|
||||||
customerIds.add(2L);
|
|
||||||
|
|
||||||
List<Object> contactIdsForOne = contacts().findIdsByParentId(1L, null, null, null, true);
|
List<Object> customerIds = new ArrayList<>();
|
||||||
|
customerIds.add(ids.get(0));
|
||||||
|
customerIds.add(ids.get(1));
|
||||||
|
|
||||||
|
List<Object> contactIdsForOne = contacts().findIdsByParentId(ids.get(0), null, null, null, true);
|
||||||
|
|
||||||
List<Object> contactIdsForMultiple = contacts().findIdsByParentId(null, customerIds, null, null, true);
|
List<Object> contactIdsForMultiple = contacts().findIdsByParentId(null, customerIds, null, null, true);
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,20 @@ import io.ebean.Database;
|
|||||||
import io.ebean.annotation.IgnorePlatform;
|
import io.ebean.annotation.IgnorePlatform;
|
||||||
import io.ebean.annotation.Platform;
|
import io.ebean.annotation.Platform;
|
||||||
import io.ebean.annotation.Transactional;
|
import io.ebean.annotation.Transactional;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.tests.model.basic.Customer;
|
import org.tests.model.basic.Customer;
|
||||||
|
import org.tests.model.basic.ResetBasicData;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
public class TestBatchSaveWithGetBeanId extends BaseTestCase {
|
public class TestBatchSaveWithGetBeanId extends BaseTestCase {
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void before() {
|
||||||
|
ResetBasicData.reset();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Making this transaction with batchSize means that the insert
|
* Making this transaction with batchSize means that the insert
|
||||||
* below does not occur immediately ... and the getBeanId()
|
* below does not occur immediately ... and the getBeanId()
|
||||||
@@ -22,7 +29,6 @@ public class TestBatchSaveWithGetBeanId extends BaseTestCase {
|
|||||||
@Test
|
@Test
|
||||||
@IgnorePlatform(Platform.HANA) // HANA doesn't support insert batching
|
@IgnorePlatform(Platform.HANA) // HANA doesn't support insert batching
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
||||||
Database server = DB.getDefault();
|
Database server = DB.getDefault();
|
||||||
Customer model = new Customer();
|
Customer model = new Customer();
|
||||||
model.setName("foo");
|
model.setName("foo");
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package org.tests.insert;
|
|||||||
|
|
||||||
import io.ebean.BaseTestCase;
|
import io.ebean.BaseTestCase;
|
||||||
import io.ebean.DB;
|
import io.ebean.DB;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.tests.model.basic.Customer;
|
import org.tests.model.basic.Customer;
|
||||||
|
import org.tests.model.basic.ResetBasicData;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -12,9 +14,13 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
|
|
||||||
public class TestInsertCollection extends BaseTestCase {
|
public class TestInsertCollection extends BaseTestCase {
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void before() {
|
||||||
|
ResetBasicData.reset();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
||||||
Customer cust1 = new Customer();
|
Customer cust1 = new Customer();
|
||||||
cust1.setName("jim");
|
cust1.setName("jim");
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.tests.model.basic;
|
|||||||
|
|
||||||
import io.ebean.DB;
|
import io.ebean.DB;
|
||||||
import io.ebean.Database;
|
import io.ebean.Database;
|
||||||
|
import io.ebean.Transaction;
|
||||||
import org.tests.model.basic.Order.Status;
|
import org.tests.model.basic.Order.Status;
|
||||||
|
|
||||||
import java.sql.Date;
|
import java.sql.Date;
|
||||||
@@ -47,6 +48,7 @@ public class ResetBasicData {
|
|||||||
// the test rely on the products being in there
|
// the test rely on the products being in there
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Transaction.current().setBatchMode(false);
|
||||||
//me.deleteAll();
|
//me.deleteAll();
|
||||||
me.insertCountries();
|
me.insertCountries();
|
||||||
me.insertProducts();
|
me.insertProducts();
|
||||||
@@ -56,100 +58,55 @@ public class ResetBasicData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void deleteAll() {
|
private void insertCountries() {
|
||||||
DB.execute(() -> {
|
Country c = new Country();
|
||||||
|
c.setCode("NZ");
|
||||||
|
c.setName("New Zealand");
|
||||||
|
server.save(c);
|
||||||
|
|
||||||
// orm update use bean name and bean properties
|
Country au = new Country();
|
||||||
server.sqlUpdate("delete from o_cached_bean_child").execute();
|
au.setCode("AU");
|
||||||
server.sqlUpdate("delete from o_cached_bean_country").execute();
|
au.setName("Australia");
|
||||||
server.sqlUpdate("delete from o_cached_bean").execute();
|
server.save(au);
|
||||||
|
|
||||||
server.createUpdate(OrderShipment.class, "delete from orderShipment").execute();
|
|
||||||
|
|
||||||
server.createUpdate(OrderDetail.class, "delete from orderDetail").execute();
|
|
||||||
|
|
||||||
server.createUpdate(Order.class, "delete from order").execute();
|
|
||||||
|
|
||||||
server.createUpdate(Contact.class, "delete from contact").execute();
|
|
||||||
|
|
||||||
server.createUpdate(Customer.class, "delete from Customer").execute();
|
|
||||||
|
|
||||||
server.createUpdate(Address.class, "delete from address").execute();
|
|
||||||
|
|
||||||
// sql update uses table and column names
|
|
||||||
server.sqlUpdate("delete from o_country").execute();
|
|
||||||
server.sqlUpdate("delete from o_product").execute();
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void insertCountries() {
|
private void insertProducts() {
|
||||||
|
Product p = new Product();
|
||||||
|
p.setName("Chair");
|
||||||
|
p.setSku("C001");
|
||||||
|
server.save(p);
|
||||||
|
|
||||||
if (server.find(Country.class).findCount() > 0) {
|
p = new Product();
|
||||||
return;
|
p.setName("Desk");
|
||||||
}
|
p.setSku("DSK1");
|
||||||
|
server.save(p);
|
||||||
|
|
||||||
server.execute(() -> {
|
p = new Product();
|
||||||
Country c = new Country();
|
p.setName("Computer");
|
||||||
c.setCode("NZ");
|
p.setSku("C002");
|
||||||
c.setName("New Zealand");
|
server.save(p);
|
||||||
server.save(c);
|
|
||||||
|
|
||||||
Country au = new Country();
|
p = new Product();
|
||||||
au.setCode("AU");
|
p.setName("Printer");
|
||||||
au.setName("Australia");
|
p.setSku("C003");
|
||||||
server.save(au);
|
server.save(p);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void insertTestCustAndOrders() {
|
||||||
|
Customer cust1 = insertCustomer("Rob");
|
||||||
|
Customer cust2 = insertCustomerNoAddress();
|
||||||
|
insertCustomerFiona();
|
||||||
|
insertCustomerNoContacts("NocCust");
|
||||||
|
|
||||||
public void insertProducts() {
|
createOrder1(cust1);
|
||||||
|
createOrder2(cust2);
|
||||||
if (server.find(Product.class).findCount() > 0) {
|
createOrder3(cust1);
|
||||||
return;
|
createOrder4(cust1);
|
||||||
}
|
createOrder5(cust2);
|
||||||
server.execute(() -> {
|
|
||||||
Product p = new Product();
|
|
||||||
p.setName("Chair");
|
|
||||||
p.setSku("C001");
|
|
||||||
server.save(p);
|
|
||||||
|
|
||||||
p = new Product();
|
|
||||||
p.setName("Desk");
|
|
||||||
p.setSku("DSK1");
|
|
||||||
server.save(p);
|
|
||||||
|
|
||||||
p = new Product();
|
|
||||||
p.setName("Computer");
|
|
||||||
p.setSku("C002");
|
|
||||||
server.save(p);
|
|
||||||
|
|
||||||
p = new Product();
|
|
||||||
p.setName("Printer");
|
|
||||||
p.setSku("C003");
|
|
||||||
server.save(p);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insertTestCustAndOrders() {
|
|
||||||
|
|
||||||
DB.execute(() -> {
|
|
||||||
Customer cust1 = insertCustomer("Rob");
|
|
||||||
Customer cust2 = insertCustomerNoAddress();
|
|
||||||
insertCustomerFiona();
|
|
||||||
insertCustomerNoContacts("NocCust");
|
|
||||||
|
|
||||||
createOrder1(cust1);
|
|
||||||
createOrder2(cust2);
|
|
||||||
createOrder3(cust1);
|
|
||||||
createOrder4(cust1);
|
|
||||||
createOrder5(cust2);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Customer createCustAndOrder(String custName) {
|
public static Customer createCustAndOrder(String custName) {
|
||||||
|
|
||||||
ResetBasicData me = new ResetBasicData();
|
ResetBasicData me = new ResetBasicData();
|
||||||
Customer cust1 = insertCustomer(custName);
|
Customer cust1 = insertCustomer(custName);
|
||||||
me.createOrder1(cust1);
|
me.createOrder1(cust1);
|
||||||
@@ -157,7 +114,6 @@ public class ResetBasicData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Order createOrderCustAndOrder(String custName) {
|
public static Order createOrderCustAndOrder(String custName) {
|
||||||
|
|
||||||
ResetBasicData me = new ResetBasicData();
|
ResetBasicData me = new ResetBasicData();
|
||||||
Customer cust1 = insertCustomer(custName);
|
Customer cust1 = insertCustomer(custName);
|
||||||
return me.createOrder1(cust1);
|
return me.createOrder1(cust1);
|
||||||
@@ -166,10 +122,8 @@ public class ResetBasicData {
|
|||||||
private static int contactEmailNum = 1;
|
private static int contactEmailNum = 1;
|
||||||
|
|
||||||
private Customer insertCustomerFiona() {
|
private Customer insertCustomerFiona() {
|
||||||
|
|
||||||
Customer c = createCustomer("Fiona", "12 Apple St", "West Coast Rd", 1, "2009-08-31");
|
Customer c = createCustomer("Fiona", "12 Apple St", "West Coast Rd", 1, "2009-08-31");
|
||||||
c.setStatus(Customer.Status.ACTIVE);
|
c.setStatus(Customer.Status.ACTIVE);
|
||||||
|
|
||||||
c.addContact(createContact("Fiona", "Black"));
|
c.addContact(createContact("Fiona", "Black"));
|
||||||
c.addContact(createContact("Tracy", "Red"));
|
c.addContact(createContact("Tracy", "Red"));
|
||||||
|
|
||||||
@@ -185,22 +139,18 @@ public class ResetBasicData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Customer insertCustomerNoContacts(String name) {
|
private Customer insertCustomerNoContacts(String name) {
|
||||||
|
|
||||||
Customer c = createCustomer("Roger", "15 Kumera Way", "Bos town", 1, "2010-04-10");
|
Customer c = createCustomer("Roger", "15 Kumera Way", "Bos town", 1, "2010-04-10");
|
||||||
c.setName(name);
|
c.setName(name);
|
||||||
c.setStatus(Customer.Status.ACTIVE);
|
c.setStatus(Customer.Status.ACTIVE);
|
||||||
|
|
||||||
DB.save(c);
|
DB.save(c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Customer insertCustomerNoAddress() {
|
private Customer insertCustomerNoAddress() {
|
||||||
|
|
||||||
Customer c = new Customer();
|
Customer c = new Customer();
|
||||||
c.setName("Cust NoAddress");
|
c.setName("Cust NoAddress");
|
||||||
c.setStatus(Customer.Status.NEW);
|
c.setStatus(Customer.Status.NEW);
|
||||||
c.addContact(createContact("Jack", "Black"));
|
c.addContact(createContact("Jack", "Black"));
|
||||||
|
|
||||||
DB.save(c);
|
DB.save(c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -216,7 +166,6 @@ public class ResetBasicData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Customer createCustomer(String name, String shippingStreet, String billingStreet, int contactSuffix, String annDate) {
|
public static Customer createCustomer(String name, String shippingStreet, String billingStreet, int contactSuffix, String annDate) {
|
||||||
|
|
||||||
Customer c = new Customer();
|
Customer c = new Customer();
|
||||||
c.setName(name);
|
c.setName(name);
|
||||||
c.setStatus(Customer.Status.NEW);
|
c.setStatus(Customer.Status.NEW);
|
||||||
@@ -251,17 +200,14 @@ public class ResetBasicData {
|
|||||||
|
|
||||||
c.setBillingAddress(billingAddr);
|
c.setBillingAddress(billingAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Order createOrder1(Customer customer) {
|
private Order createOrder1(Customer customer) {
|
||||||
|
|
||||||
Product product1 = DB.reference(Product.class, 1);
|
Product product1 = DB.reference(Product.class, 1);
|
||||||
Product product2 = DB.reference(Product.class, 2);
|
Product product2 = DB.reference(Product.class, 2);
|
||||||
Product product3 = DB.reference(Product.class, 3);
|
Product product3 = DB.reference(Product.class, 3);
|
||||||
|
|
||||||
|
|
||||||
Order order = new Order();
|
Order order = new Order();
|
||||||
order.setCustomer(customer);
|
order.setCustomer(customer);
|
||||||
order.setOrderDate(Date.valueOf("2018-07-01"));
|
order.setOrderDate(Date.valueOf("2018-07-01"));
|
||||||
@@ -271,16 +217,12 @@ public class ResetBasicData {
|
|||||||
details.add(new OrderDetail(product2, 3, 1.10));
|
details.add(new OrderDetail(product2, 3, 1.10));
|
||||||
details.add(new OrderDetail(product3, 1, 2.00));
|
details.add(new OrderDetail(product3, 1, 2.00));
|
||||||
order.setDetails(details);
|
order.setDetails(details);
|
||||||
|
|
||||||
|
|
||||||
order.addShipment(new OrderShipment());
|
order.addShipment(new OrderShipment());
|
||||||
|
|
||||||
DB.save(order);
|
DB.save(order);
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createOrder2(Customer customer) {
|
private void createOrder2(Customer customer) {
|
||||||
|
|
||||||
Product product1 = DB.reference(Product.class, 1);
|
Product product1 = DB.reference(Product.class, 1);
|
||||||
|
|
||||||
Order order = new Order();
|
Order order = new Order();
|
||||||
@@ -291,14 +233,11 @@ public class ResetBasicData {
|
|||||||
List<OrderDetail> details = new ArrayList<>();
|
List<OrderDetail> details = new ArrayList<>();
|
||||||
details.add(new OrderDetail(product1, 4, 10.50));
|
details.add(new OrderDetail(product1, 4, 10.50));
|
||||||
order.setDetails(details);
|
order.setDetails(details);
|
||||||
|
|
||||||
order.addShipment(new OrderShipment());
|
order.addShipment(new OrderShipment());
|
||||||
|
|
||||||
DB.save(order);
|
DB.save(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createOrder3(Customer customer) {
|
private void createOrder3(Customer customer) {
|
||||||
|
|
||||||
Product product1 = DB.reference(Product.class, 1);
|
Product product1 = DB.reference(Product.class, 1);
|
||||||
Product product3 = DB.reference(Product.class, 3);
|
Product product3 = DB.reference(Product.class, 3);
|
||||||
|
|
||||||
@@ -312,30 +251,23 @@ public class ResetBasicData {
|
|||||||
details.add(new OrderDetail(product3, 40, 2.10));
|
details.add(new OrderDetail(product3, 40, 2.10));
|
||||||
details.add(new OrderDetail(product1, 5, 10.00));
|
details.add(new OrderDetail(product1, 5, 10.00));
|
||||||
order.setDetails(details);
|
order.setDetails(details);
|
||||||
|
|
||||||
order.addShipment(new OrderShipment());
|
order.addShipment(new OrderShipment());
|
||||||
|
|
||||||
DB.save(order);
|
DB.save(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createOrder4(Customer customer) {
|
private void createOrder4(Customer customer) {
|
||||||
|
|
||||||
Order order = new Order();
|
Order order = new Order();
|
||||||
order.setCustomer(customer);
|
order.setCustomer(customer);
|
||||||
order.setOrderDate(Date.valueOf("2018-07-04"));
|
order.setOrderDate(Date.valueOf("2018-07-04"));
|
||||||
|
|
||||||
order.addShipment(new OrderShipment());
|
order.addShipment(new OrderShipment());
|
||||||
|
|
||||||
DB.save(order);
|
DB.save(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createOrder5(Customer customer) {
|
private void createOrder5(Customer customer) {
|
||||||
|
|
||||||
Order order = new Order();
|
Order order = new Order();
|
||||||
order.setCustomer(customer);
|
order.setCustomer(customer);
|
||||||
order.setOrderDate(Date.valueOf("2018-06-28"));
|
order.setOrderDate(Date.valueOf("2018-06-28"));
|
||||||
order.addShipment(new OrderShipment());
|
order.addShipment(new OrderShipment());
|
||||||
|
|
||||||
DB.save(order);
|
DB.save(order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
|||||||
|
|
||||||
Query<Customer> query = DB.find(Customer.class)
|
Query<Customer> query = DB.find(Customer.class)
|
||||||
.select("name")
|
.select("name")
|
||||||
.where().eq("id", 1).query();
|
.where().eq("name", "Rob").query();
|
||||||
|
|
||||||
String name = query.findSingleAttribute();
|
String name = query.findSingleAttribute();
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
|||||||
|
|
||||||
String name = DB.find(Customer.class)
|
String name = DB.find(Customer.class)
|
||||||
.select("name")
|
.select("name")
|
||||||
.where().eq("id", 1)
|
.where().eq("name", "Rob")
|
||||||
.findSingleAttribute();
|
.findSingleAttribute();
|
||||||
|
|
||||||
assertThat(name).isNotNull();
|
assertThat(name).isNotNull();
|
||||||
@@ -646,7 +646,7 @@ public class TestQuerySingleAttribute extends BaseTestCase {
|
|||||||
.findSingleAttributeList();
|
.findSingleAttributeList();
|
||||||
assertThat(list1.get(0)).isInstanceOf(CountedValue.class);
|
assertThat(list1.get(0)).isInstanceOf(CountedValue.class);
|
||||||
//assertThat(list1.toString()).isEqualTo("[1: Tracy, 3: Jim1, 1: Jack, 3: Fred1, 1: Fiona, 3: Bugs1]");
|
//assertThat(list1.toString()).isEqualTo("[1: Tracy, 3: Jim1, 1: Jack, 3: Fred1, 1: Fiona, 3: Bugs1]");
|
||||||
|
|
||||||
query = DB.find(Contact.class).select("firstName");
|
query = DB.find(Contact.class).select("firstName");
|
||||||
list1 = query
|
list1 = query
|
||||||
.setCountDistinct(CountDistinctOrder.NO_ORDERING)
|
.setCountDistinct(CountDistinctOrder.NO_ORDERING)
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ package org.tests.update;
|
|||||||
import io.ebean.DB;
|
import io.ebean.DB;
|
||||||
import io.ebean.TransactionalTestCase;
|
import io.ebean.TransactionalTestCase;
|
||||||
import io.ebean.test.LoggedSql;
|
import io.ebean.test.LoggedSql;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.tests.model.basic.Contact;
|
import org.tests.model.basic.Contact;
|
||||||
import org.tests.model.basic.Customer;
|
import org.tests.model.basic.Customer;
|
||||||
import org.tests.model.basic.EBasic;
|
import org.tests.model.basic.EBasic;
|
||||||
import org.tests.model.basic.EBasic.Status;
|
import org.tests.model.basic.EBasic.Status;
|
||||||
|
import org.tests.model.basic.ResetBasicData;
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
import javax.persistence.EntityNotFoundException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -17,6 +19,11 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
|
|
||||||
public class TestStatelessUpdate extends TransactionalTestCase {
|
public class TestStatelessUpdate extends TransactionalTestCase {
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void before() {
|
||||||
|
ResetBasicData.reset();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,21 @@ package org.tests.update;
|
|||||||
import io.ebean.BaseTestCase;
|
import io.ebean.BaseTestCase;
|
||||||
import io.ebean.DB;
|
import io.ebean.DB;
|
||||||
import io.ebean.SqlRow;
|
import io.ebean.SqlRow;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.tests.model.basic.Customer;
|
import org.tests.model.basic.Customer;
|
||||||
|
import org.tests.model.basic.ResetBasicData;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
public class TestUpdatePartial extends BaseTestCase {
|
public class TestUpdatePartial extends BaseTestCase {
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
static void before() {
|
||||||
|
ResetBasicData.reset();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.avaje</groupId>
|
<groupId>org.avaje</groupId>
|
||||||
<artifactId>java8-oss</artifactId>
|
<artifactId>java8-oss</artifactId>
|
||||||
<version>2.3</version>
|
<version>3.3</version>
|
||||||
<relativePath/>
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.avaje</groupId>
|
<groupId>org.avaje</groupId>
|
||||||
<artifactId>java11-oss</artifactId>
|
<artifactId>java11-oss</artifactId>
|
||||||
<version>2.3</version>
|
<version>3.4</version>
|
||||||
<relativePath/>
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<maven.compiler.source>11</maven.compiler.source>
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
|
|
||||||
<ebean-maven-plugin.version>12.13.0</ebean-maven-plugin.version>
|
<ebean-maven-plugin.version>12.14.1</ebean-maven-plugin.version>
|
||||||
<kotlin.version>1.6.0</kotlin.version>
|
<kotlin.version>1.6.0</kotlin.version>
|
||||||
<jackson.version>2.12.1</jackson.version>
|
<jackson.version>2.12.1</jackson.version>
|
||||||
<maven.deploy.skip>true</maven.deploy.skip>
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
|
|||||||
Reference in new issue
Block a user