#1341 - Cascade persist with JDBC batch and BeanPersistAdapter with preUpdate() that invokes lazy loading on persisted bean ... results in OptimisticLockException

This commit is contained in:
Rob Bygrave
2018-03-08 14:12:32 +13:00
parent 54ba1480eb
commit c0efd49c73
2 changed files with 52 additions and 6 deletions
@@ -85,16 +85,19 @@ public class BatchedBeanHolder {
// Note updates and deletes can result in many PreparedStatements
// if their where clauses differ via use of IS NOT NULL.
if (deletes != null && !deletes.isEmpty()) {
control.executeNow(deletes);
deletes.clear();
ArrayList<PersistRequest> bufferedDeletes = deletes;
deletes = new ArrayList<>();
control.executeNow(bufferedDeletes);
}
if (inserts != null && !inserts.isEmpty()) {
control.executeNow(inserts);
inserts.clear();
ArrayList<PersistRequest> bufferedInserts = inserts;
inserts = new ArrayList<>();
control.executeNow(bufferedInserts);
}
if (updates != null && !updates.isEmpty()) {
control.executeNow(updates);
updates.clear();
ArrayList<PersistRequest> bufferedUpdates = updates;
updates = new ArrayList<>();
control.executeNow(bufferedUpdates);
}
persistedBeans.clear();
}
@@ -3,9 +3,12 @@ package io.ebean.event;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebean.Transaction;
import io.ebean.config.ServerConfig;
import org.junit.Test;
import org.tests.model.basic.EBasicVer;
import org.tests.model.basic.UTDetail;
import org.tests.model.basic.UTMaster;
import java.util.ArrayList;
import java.util.Arrays;
@@ -19,6 +22,36 @@ public class BeanPersistControllerTest {
private PersistAdapter stopPersistingAdapter = new PersistAdapter(false);
@Test
public void issue_1341() {
EbeanServer ebeanServer = getEbeanServer(continuePersistingAdapter);
UTMaster bean0 = new UTMaster("one0");
UTDetail detail0 = new UTDetail("detail0", 12, 23D);
bean0.getDetails().add(detail0);
ebeanServer.save(bean0);
UTMaster master = ebeanServer.find(UTMaster.class)
.setId(bean0.getId())
.fetch("details", "name, version")
.findOne();
UTDetail utDetail = master.getDetails().get(0);
utDetail.setName("detail0 mod");
Transaction txn = ebeanServer.beginTransaction();
try {
txn.setBatchMode(true);
ebeanServer.save(master);
txn.commit();
} finally {
txn.end();
}
}
@Test
public void testInsertUpdateDelete_given_continuePersistingAdapter() {
@@ -91,6 +124,8 @@ public class BeanPersistControllerTest {
config.setRegister(false);
config.setDefaultServer(false);
config.getClasses().add(EBasicVer.class);
config.getClasses().add(UTMaster.class);
config.getClasses().add(UTDetail.class);
config.add(persistAdapter);
@@ -130,6 +165,14 @@ public class BeanPersistControllerTest {
@Override
public boolean preUpdate(BeanPersistRequest<?> request) {
methodsCalled.add("preUpdate");
Object bean = request.getBean();
if (bean instanceof UTDetail) {
UTDetail detail = (UTDetail)bean;
// invoke lazy loading ... which invoke the flush of the jdbc batch
detail.setQty(42);
}
return continueDefaultPersisting;
}