#2265 - ArrayIndexOutOfBoundsException: Index -1 out of bounds with @IdClass and batch insert accessing id property

This commit is contained in:
rbygrave
2021-07-13 11:30:31 +12:00
parent f8e54be9a6
commit e82b8c80f0
3 changed files with 38 additions and 4 deletions
@@ -379,9 +379,11 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
public void setBatched() {
batched = true;
if (type == Type.INSERT || type == Type.UPDATE) {
// used to trigger automatic jdbc batch flush
intercept.registerGetterCallback(this);
getterCallback = true;
if (beanDescriptor.hasSingleIdProperty()) {
// used to trigger automatic jdbc batch flush
intercept.registerGetterCallback(this);
getterCallback = true;
}
}
}
@@ -1747,6 +1747,13 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
return idProperty != null;
}
/**
* Return false for IdClass case with multiple @Id properties.
*/
public boolean hasSingleIdProperty() {
return idPropertyIndex != -1;
}
/**
* Return true if this type has a simple Id and the platform supports mutli-value binding.
*/
@@ -3145,7 +3152,8 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
}
public boolean isIdLoaded(EntityBeanIntercept ebi) {
return ebi.isLoadedProperty(idPropertyIndex);
// assume id loaded for IdClass case with idPropertyIndex == -1
return idPropertyIndex == -1 ? true : ebi.isLoadedProperty(idPropertyIndex);
}
boolean hasIdValue(EntityBean bean) {
@@ -1,7 +1,9 @@
package org.tests.model.bridge;
import io.ebean.BaseTestCase;
import io.ebean.DB;
import io.ebean.Ebean;
import io.ebean.Transaction;
import org.ebeantest.LoggedSqlCollector;
import org.junit.Test;
@@ -39,6 +41,28 @@ public class TestIdClassScalar extends BaseTestCase {
}
@Test
public void insertBatch() {
UUID siteId = UUID.randomUUID();
UUID userId = UUID.randomUUID();
try (final Transaction transaction = DB.beginTransaction()) {
transaction.setBatchMode(true);
BSiteUserD access = new BSiteUserD(BAccessLevel.ONE, siteId, userId);
DB.save(access);
final UUID siteId1 = access.getSiteId(); // ArrayIndexOutOfBoundsException here
assertThat(siteId1).isNotNull();
assertThat(access.getUserId()).isEqualTo(userId);
transaction.commit();
}
DB.delete(BSiteUserD.class, new BEmbId(siteId, userId));
}
@Test
public void test() {