diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/LoadBeanRequest.java b/ebean-core/src/main/java/io/ebeaninternal/api/LoadBeanRequest.java index 7fa8b8a091..112b7d51b8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/LoadBeanRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/LoadBeanRequest.java @@ -6,7 +6,11 @@ import io.ebeaninternal.server.core.OrmQueryRequest; import io.ebeaninternal.server.deploy.BeanDescriptor; -import java.util.*; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import static java.lang.System.Logger.Level.DEBUG; @@ -21,6 +25,9 @@ public final class LoadBeanRequest extends LoadRequest { private final boolean loadCache; private final boolean alreadyLoaded; private String triggerEbi; + private String batchBefore; + private List queryIds; + /** * Construct for lazy load request. */ @@ -56,17 +63,19 @@ public String description() { } /** - * Return the batch of beans to actually load. + * Return true if the batch is empty. */ - public Set batch() { + public boolean checkEmpty() { loadBuffer.loadingStarted(); - return batch; + batchBefore = String.valueOf(batch); + queryIds = ids(); + return batch.isEmpty(); } /** * Return the list of Id values for the beans in the lazy load buffer. */ - public List ids() { + private List ids() { final List idList = new ArrayList<>(batch.size()); final BeanDescriptor desc = loadBuffer.descriptor(); for (EntityBeanIntercept ebi : batch) { @@ -78,7 +87,7 @@ public List ids() { /** * Configure the query for lazy loading execution. */ - public void configureQuery(SpiQuery query, List idList) { + public void configureQuery(SpiQuery query) { query.setMode(Mode.LAZYLOAD_BEAN); query.setPersistenceContext(loadBuffer.persistenceContext()); query.setLoadDescription(mode(), description()); @@ -94,10 +103,10 @@ public void configureQuery(SpiQuery query, List idList) { if (loadCache) { query.setBeanCacheMode(CacheMode.PUT); } - if (idList.size() == 1) { - query.where().idEq(idList.get(0)); + if (queryIds.size() == 1) { + query.where().idEq(queryIds.get(0)); } else { - query.where().idIn(idList); + query.where().idIn(queryIds); } } @@ -108,7 +117,7 @@ private String mode() { /** * Load the beans into the L2 cache if that is requested and check for load failures due to deletes. */ - public Result postLoad(List list, List queryIds) { + public void postLoad(List list) { loadBuffer.loadingStopped(); Set loadedIds = new HashSet<>(); BeanDescriptor desc = loadBuffer.descriptor(); @@ -137,42 +146,16 @@ public Result postLoad(List list, List queryIds) { } } if (!missed.isEmpty()) { - CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch triggered by ebi:{0} property:{1}", triggerEbi, lazyLoadProperty); + if (CoreLog.markedAsDeleted.isLoggable(DEBUG)) { + CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch triggered by ebi:{0} property:{1}", triggerEbi, lazyLoadProperty); + CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch BEFORE {0}", batchBefore); + CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch AFTER {0}", batch); + String msg = MessageFormat.format("Bean added to batch during load for {0} missedIds:{1} queryIds:{2} missed:{3}", + beanType(), missedIds, queryIds, missed); + CoreLog.markedAsDeleted.log(DEBUG, msg, new RuntimeException("LoadBeanRequest - Bean added to batch during load")); + } } } - return new Result(loadedIds, missedIds, missed); - } - return EMPTY_RESULT; - } - - static final Result EMPTY_RESULT = new Result(Collections.emptySet(),Collections.emptySet(), Collections.emptyList()); - - public static class Result { - - private final Set loadedIds; - private final Set missedIds; - private final List missed; - - Result(Set loadedIds, Set missedIds, List missed) { - this.loadedIds = loadedIds; - this.missedIds = missedIds; - this.missed = missed; - } - - public boolean hasMisses() { - return !missedIds.isEmpty(); - } - - public Set missedIds() { - return missedIds; - } - - public Set loadedIds() { - return loadedIds; - } - - public List missed() { - return missed; } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java index a7a9e51b72..871a5b982f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java @@ -14,12 +14,9 @@ import io.ebeaninternal.server.transaction.DefaultPersistenceContext; import javax.persistence.EntityNotFoundException; -import java.text.MessageFormat; import java.util.List; -import java.util.Set; import static java.lang.System.Logger.Level.DEBUG; -import static java.lang.System.Logger.Level.ERROR; /** * Helper to handle lazy loading and refreshing of beans. @@ -126,30 +123,12 @@ private void loadManyInternal(EntityBean parentBean, String propertyName, boolea * Load a batch of beans for +query or +lazy loading. */ void loadBean(LoadBeanRequest loadRequest) { - final Set batch = loadRequest.batch(); - if (batch.isEmpty()) { + if (loadRequest.checkEmpty()) { throw new RuntimeException("Nothing in batch?"); } - - final String batchBefore = String.valueOf(batch); - final List ids = loadRequest.ids(); - if (ids.isEmpty()) { - // this should never happen given the batch is not empty - CoreLog.internal.log(ERROR, "No Ids when loading Batch buffer"); - return; - } - final SpiQuery query = server.createQuery(loadRequest.beanType()); - loadRequest.configureQuery(query, ids); - final List list = executeQuery(loadRequest, query); - final LoadBeanRequest.Result result = loadRequest.postLoad(list, ids); - if (result.hasMisses() && CoreLog.markedAsDeleted.isLoggable(DEBUG)) { - CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch BEFORE {0}", batchBefore); - CoreLog.markedAsDeleted.log(DEBUG, "Loaded bean batch AFTER {0}", batch); - String msg = MessageFormat.format("Bean added to batch during load for {0} missedIds:{1} ids:{2} loadedIds:{3} sql:{4} missed:{5}", - loadRequest.beanType(), result.missedIds(), ids, result.loadedIds(), query.getGeneratedSql(), result.missed()); - CoreLog.markedAsDeleted.log(DEBUG, msg, new RuntimeException("LoadBeanRequest - Bean added to batch during load")); - } + loadRequest.configureQuery(query); + loadRequest.postLoad(executeQuery(loadRequest, query)); } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadBean.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadBean.java index bd6f62d57f..5611ab82a5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadBean.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeLoadBean.java @@ -147,6 +147,7 @@ class Load { EntityBean contextBean; SqlBeanLoad sqlBeanLoad; boolean lazyLoadMany; + boolean usingContextBean; private Load(DbReadContext ctx, EntityBean parentBean) { this.ctx = ctx; @@ -189,6 +190,7 @@ private void readIdBean() { contextBean = localBean; } else { // bean already exists in persistenceContext + usingContextBean = true; if (ctx.isLoadContextBean()) { // if explicitly set loadContextBean to true, then reload localBean = contextBean; @@ -278,13 +280,11 @@ private void postLoad() { if (!partialObject) { ebi.setFullyLoadedBean(true); } - } else if (partialObject) { - if (readId) { - // register for lazy loading - ctx.register(null, ebi); - } - } else { + } else if (!partialObject) { ebi.setFullyLoadedBean(true); + } else if (readId && !usingContextBean) { + // register for lazy loading if bean is new + ctx.register(null, ebi); } if (ctx.isAutoTuneProfiling() && !disableLazyLoad) { @@ -370,7 +370,7 @@ final EntityBean perform() throws SQLException { * context we need to check if it is already contained in the collection. */ final boolean isContextBean() { - return localBean == null || queryMode == Mode.LAZYLOAD_BEAN; + return usingContextBean; } }