Fix Transaction Flushing when ID Property is Loaded (#1450)

* Fix for unintentianal flush when ID is loaded

* fix duplicateKey Exception

* higher id
This commit is contained in:
Mitsch164
2018-07-12 15:10:17 +12:00
committed by Rob Bygrave
parent 2755e6d1ec
commit 5b8ef8154a
3 changed files with 85 additions and 3 deletions
@@ -356,7 +356,15 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
private boolean flushBatchOnGetter(int propertyIndex) {
// propertyIndex of -1 the Id property, no flush for get Id on UPDATE
return propertyIndex == -1 ? type == Type.INSERT : beanDescriptor.isGeneratedProperty(propertyIndex);
if (propertyIndex == -1) {
if (beanDescriptor.isIdLoaded(intercept)) {
return false;
} else {
return type == Type.INSERT;
}
} else {
return beanDescriptor.isGeneratedProperty(propertyIndex);
}
}
public void setSkipBatchForTopLevel() {
@@ -3160,6 +3160,10 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
public boolean hasIdPropertyOnly(EntityBeanIntercept ebi) {
return ebi.hasIdOnly(idPropertyIndex);
}
public boolean isIdLoaded(EntityBeanIntercept ebi) {
return ebi.isLoadedProperty(idPropertyIndex);
}
public boolean hasIdValue(EntityBean bean) {
return (idProperty != null && !DmlUtil.isNullOrZero(idProperty.getValue(bean)));
@@ -122,15 +122,20 @@ public class TestBatchInsertFlush extends BaseTestCase {
public void transactional_flushOnGetId() {
EbeanServer server = Ebean.getDefaultServer();
LoggedSqlCollector.start();
EBasicVer b1 = new EBasicVer("b1");
server.save(b1);
EBasicVer b2 = new EBasicVer("b2");
server.save(b2);
//flush here
assertThat(LoggedSqlCollector.current()).isEmpty();
Integer id = b1.getId();
assertNotNull(id);
assertThat(LoggedSqlCollector.current()).hasSize(2);
EBasicVer b3 = new EBasicVer("b3");
server.save(b3);
}
@@ -141,7 +146,8 @@ public class TestBatchInsertFlush extends BaseTestCase {
EbeanServer server = Ebean.getDefaultServer();
Transaction txn = server.beginTransaction();
try {
txn.setBatch(PersistBatch.ALL);
LoggedSqlCollector.start();
txn.setBatchMode(true);
EBasicVer b1 = new EBasicVer("b1");
server.save(b1, txn);
@@ -149,8 +155,11 @@ public class TestBatchInsertFlush extends BaseTestCase {
EBasicVer b2 = new EBasicVer("b2");
server.save(b2, txn);
//flush here
assertThat(LoggedSqlCollector.current()).isEmpty();
Integer id = b1.getId();
assertNotNull(id);
assertThat(LoggedSqlCollector.current()).hasSize(2);
EBasicVer b3 = new EBasicVer("b3");
server.save(b3, txn);
@@ -161,6 +170,67 @@ public class TestBatchInsertFlush extends BaseTestCase {
txn.end();
}
}
@Test
@Transactional(batch = PersistBatch.ALL)
public void transactional_noflushWhenIdIsLoaded() {
EbeanServer server = Ebean.getDefaultServer();
LoggedSqlCollector.start();
EBasicVer b1 = new EBasicVer("b1");
b1.setId(78965);
server.save(b1);
EBasicVer b2 = new EBasicVer("b2");
b2.setId(78645);
server.save(b2);
assertThat(LoggedSqlCollector.current()).isEmpty();
// dont flush here
Integer id = b1.getId();
assertNotNull(id);
assertThat(LoggedSqlCollector.current()).isEmpty();
EBasicVer b3 = new EBasicVer("b3");
server.save(b3);
}
@Test
public void noflushWhenIdIsLoaded() {
EbeanServer server = Ebean.getDefaultServer();
Transaction txn = server.beginTransaction();
try {
LoggedSqlCollector.start();
txn.setBatchMode(true);
EBasicVer b1 = new EBasicVer("b1");
b1.setId(546864);
server.save(b1, txn);
EBasicVer b2 = new EBasicVer("b2");
b2.setId(21354);
server.save(b2, txn);
assertThat(LoggedSqlCollector.current()).isEmpty();
//dont flush here
Integer id = b1.getId();
assertNotNull(id);
assertThat(LoggedSqlCollector.current()).isEmpty();
EBasicVer b3 = new EBasicVer("b3");
server.save(b3, txn);
txn.commit();
assertThat(LoggedSqlCollector.current()).hasSize(3);
} finally {
txn.end();
}
}
@Test
public void testFlushOnGetProperty() {