From dfc5963e35919b7fb47400962222a66c8e209f7c Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Thu, 9 Mar 2023 09:57:41 +1300 Subject: [PATCH] Fix for IndexOutOfBoundsException: The size must be at least 1 Stack trace observed: java.lang.IndexOutOfBoundsException: The size must be at least 1 at io.ebeaninternal.server.deploy.id.IdBinderSimple.getIdInValueExpr(IdBinderSimple.java:135) at io.ebeaninternal.server.deploy.BeanDescriptor.parentIdInExpr(BeanDescriptor.java:1634) at io.ebeaninternal.server.deploy.BeanPropertyAssocManySqlHelp.addWhereParentIdIn(BeanPropertyAssocManySqlHelp.java:121) at io.ebeaninternal.server.deploy.BeanPropertyAssocMany.addWhereParentIdIn(BeanPropertyAssocMany.java:342) at io.ebeaninternal.api.LoadManyRequest.createQuery(LoadManyRequest.java:90) at io.ebeaninternal.server.core.DefaultBeanLoader.loadMany(DefaultBeanLoader.java:39) at io.ebeaninternal.server.core.DefaultServer.loadMany(DefaultServer.java:475) at io.ebeaninternal.server.loadcontext.DLoadManyContext$LoadBuffer.loadMany(DLoadManyContext.java:215) at io.ebean.common.AbstractBeanCollection.lazyLoadCollection(AbstractBeanCollection.java:90) at io.ebean.common.BeanList.init(BeanList.java:141) at io.ebean.common.BeanList.iterator(BeanList.java:327) --- .../io/ebeaninternal/api/LoadManyRequest.java | 30 +++++++++++++------ .../server/loadcontext/DLoadManyContext.java | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/LoadManyRequest.java b/ebean-core/src/main/java/io/ebeaninternal/api/LoadManyRequest.java index e83e32aa4..7aef79279 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/LoadManyRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/LoadManyRequest.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.List; import static java.lang.System.Logger.Level.DEBUG; +import static java.lang.System.Logger.Level.INFO; /** * Request for loading Associated Many Beans. @@ -22,26 +23,29 @@ public final class LoadManyRequest extends LoadRequest { private final LoadManyBuffer loadContext; private final boolean onlyIds; private final boolean loadCache; + private final BeanCollection originCollection; + private boolean originIncluded; /** * Construct for lazy loading. */ - public LoadManyRequest(LoadManyBuffer loadContext, boolean onlyIds, boolean loadCache) { - this(loadContext, null, true, onlyIds, loadCache); + public LoadManyRequest(LoadManyBuffer loadContext, boolean onlyIds, boolean loadCache, BeanCollection originCollection) { + super(null, true); + this.loadContext = loadContext; + this.onlyIds = onlyIds; + this.loadCache = loadCache; + this.originCollection = originCollection; } /** * Construct for secondary query. */ public LoadManyRequest(LoadManyBuffer loadContext, OrmQueryRequest parentRequest) { - this(loadContext, parentRequest, false, false, false); - } - - private LoadManyRequest(LoadManyBuffer loadContext, OrmQueryRequest parentRequest, boolean lazy, boolean onlyIds, boolean loadCache) { - super(parentRequest, lazy); + super(parentRequest, false); this.loadContext = loadContext; - this.onlyIds = onlyIds; - this.loadCache = loadCache; + this.onlyIds = false; + this.loadCache = false; + this.originCollection = null; } @Override @@ -59,10 +63,18 @@ public final class LoadManyRequest extends LoadRequest { for (int i = 0; i < loadContext.size(); i++) { BeanCollection bc = loadContext.get(i); if (bc != null) { + if (lazy && !originIncluded && bc == originCollection) { + originIncluded = true; + } idList.add(many.parentId(bc.getOwnerBean())); bc.setLoader(server); // don't use the load buffer again } } + if (originCollection != null && !originIncluded) { + CoreLog.log.log(INFO, "Batch lazy loading including origin collection - size:{0}", idList.size()); + idList.add(many.parentId(originCollection.getOwnerBean())); + originCollection.setLoader(server); // don't use the load buffer again + } if (many.targetDescriptor().isPadInExpression()) { BindPadding.padIds(idList); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadManyContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadManyContext.java index 56270820e..c9c532ae2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadManyContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadManyContext.java @@ -212,7 +212,7 @@ final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext } } - context.parent.getEbeanServer().loadMany(new LoadManyRequest(this, onlyIds, useCache)); + context.parent.getEbeanServer().loadMany(new LoadManyRequest(this, onlyIds, useCache, bc)); // clear the buffer as all entries have been loaded clear(); } finally {