mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#220 - Refactor Persist batch, add effectively add PersistBatch.INSERT (to ALL and NONE) and allow batching per request (save(), insert(), update(), delete())
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package com.avaje.ebean.config;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class ServerConfigTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testLoadFromEbeanProperties() {
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.loadFromProperties();
|
||||
|
||||
assertEquals(PersistBatch.NONE, serverConfig.getPersistBatch());
|
||||
assertEquals(PersistBatch.ALL, serverConfig.getPersistBatchOnCascade());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadWithProperties() {
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.setPersistBatch(PersistBatch.NONE);
|
||||
serverConfig.setPersistBatchOnCascade(PersistBatch.NONE);
|
||||
|
||||
Properties props = new Properties();
|
||||
props.setProperty("persistBatch", "INSERT");
|
||||
props.setProperty("persistBatchOnCascade", "INSERT");
|
||||
|
||||
serverConfig.loadFromProperties(props);
|
||||
|
||||
assertEquals(PersistBatch.INSERT, serverConfig.getPersistBatch());
|
||||
assertEquals(PersistBatch.INSERT, serverConfig.getPersistBatchOnCascade());
|
||||
|
||||
serverConfig.setPersistBatch(PersistBatch.NONE);
|
||||
serverConfig.setPersistBatchOnCascade(PersistBatch.NONE);
|
||||
|
||||
Properties props1 = new Properties();
|
||||
props1.setProperty("ebean.persistBatch", "ALL");
|
||||
props1.setProperty("ebean.persistBatchOnCascade", "ALL");
|
||||
|
||||
serverConfig.loadFromProperties(props1);
|
||||
|
||||
assertEquals(PersistBatch.ALL, serverConfig.getPersistBatch());
|
||||
assertEquals(PersistBatch.ALL, serverConfig.getPersistBatchOnCascade());
|
||||
}
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package com.avaje.ebeaninternal.server.transaction;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.config.PersistBatch;
|
||||
import com.avaje.tests.model.basic.UTDetail;
|
||||
import com.avaje.tests.model.basic.UTMaster;
|
||||
import org.avaje.ebeantest.LoggedSqlCollector;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestBatchPersistCascade extends BaseTestCase {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(TestBatchPersistCascade.class);
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
|
||||
EbeanServer ebeanServer = Ebean.getServer(null);
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
Transaction txn = ebeanServer.beginTransaction();
|
||||
try {
|
||||
txn.setBatch(PersistBatch.INSERT);
|
||||
logger.info("start ------------");
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
UTMaster master = createMaster(i);
|
||||
logger.info("save ------------ {}", i);
|
||||
ebeanServer.save(master);
|
||||
//txn.flushBatch();
|
||||
}
|
||||
|
||||
logger.info("commit ------------");
|
||||
txn.commit();
|
||||
|
||||
} finally {
|
||||
txn.end();
|
||||
}
|
||||
|
||||
List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
assertTrue(loggedSql.size() > 2);
|
||||
|
||||
|
||||
testUpdates();
|
||||
|
||||
}
|
||||
|
||||
private void testUpdates() {
|
||||
|
||||
EbeanServer server = Ebean.getServer(null);
|
||||
|
||||
List<UTMaster> list = server.find(UTMaster.class).fetch("details").findList();
|
||||
|
||||
Transaction txn = server.beginTransaction();
|
||||
try {
|
||||
txn.setBatch(PersistBatch.INSERT);
|
||||
txn.setBatchOnCascade(PersistBatch.ALL);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
UTMaster master = createMaster(i+500);
|
||||
logger.info("save ------------ {}", i);
|
||||
server.save(master);
|
||||
}
|
||||
|
||||
logger.info("starting updates ------------ ");
|
||||
|
||||
UTMaster lastMaster = null;
|
||||
for (UTMaster utMaster : list) {
|
||||
utMaster.setName(utMaster.getName()+" + mod");
|
||||
List<UTDetail> details = utMaster.getDetails();
|
||||
for (UTDetail detail : details) {
|
||||
detail.setQty(detail.getQty()+7);
|
||||
detail.setName(detail.getName()+" + foo");
|
||||
}
|
||||
|
||||
server.save(utMaster);
|
||||
lastMaster = utMaster;
|
||||
}
|
||||
|
||||
logger.info("starting some inserts ------------ ");
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
UTMaster master = createMaster(i+1000);
|
||||
logger.info("save ------------ {}", i);
|
||||
server.save(master);
|
||||
if (i == 1) {
|
||||
logger.info("save lastMaster ------------ ");
|
||||
lastMaster.setName("mod");
|
||||
server.save(lastMaster);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("commit ------------ ");
|
||||
|
||||
server.commitTransaction();
|
||||
} finally {
|
||||
server.endTransaction();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private UTDetail createUTDetail(String master, int count) {
|
||||
UTDetail detail = new UTDetail();
|
||||
detail.setName(master+"-"+count);
|
||||
detail.setAmount(50d);
|
||||
detail.setQty(count);
|
||||
return detail;
|
||||
}
|
||||
|
||||
private UTMaster createMaster(int count) {
|
||||
|
||||
String name = "master"+count;
|
||||
|
||||
UTMaster m0 = new UTMaster();
|
||||
m0.setName(name);
|
||||
for (int i =0; i< 5; i++) {
|
||||
m0.addDetail(createUTDetail(name, i));
|
||||
}
|
||||
return m0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,7 +23,7 @@ public class ScalarTypeLocalDateTimeTest {
|
||||
long now = System.currentTimeMillis();
|
||||
long toMillis = type.convertToMillis(LocalDateTime.now());
|
||||
|
||||
assertTrue(toMillis - now < 10);
|
||||
assertTrue(toMillis - now < 30);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,53 +1,115 @@
|
||||
package com.avaje.tests.batchinsert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.config.PersistBatch;
|
||||
import com.avaje.tests.model.basic.UTDetail;
|
||||
import com.avaje.tests.model.basic.UTMaster;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class TestBatchInsertSimple extends BaseTestCase {
|
||||
|
||||
Random random = new Random();
|
||||
|
||||
@Test
|
||||
public void testSimpleJdbcBatching() {
|
||||
public void testJdbcBatchPerRequestWithMasterAndDetails() {
|
||||
|
||||
int numOfMasters = 10;// 2 + random.nextInt(8);
|
||||
int numOfMasters = 4;// 2 + random.nextInt(8);
|
||||
|
||||
Transaction transaction = Ebean.beginTransaction();
|
||||
try {
|
||||
transaction.setBatch(PersistBatch.NONE);
|
||||
transaction.setBatchOnCascade(PersistBatch.INSERT);
|
||||
transaction.setBatchSize(30);
|
||||
|
||||
for (int i = 0; i < numOfMasters; i++) {
|
||||
UTMaster master = createMasterAndDetails(i, 20);
|
||||
Ebean.save(master);
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
|
||||
} finally {
|
||||
transaction.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testJdbcBatchPerRequestWithMasterOnly() {
|
||||
|
||||
int numOfMasters = 4;
|
||||
|
||||
Transaction transaction = Ebean.beginTransaction();
|
||||
try {
|
||||
transaction.setBatch(PersistBatch.NONE);
|
||||
transaction.setBatchOnCascade(PersistBatch.INSERT);
|
||||
transaction.setBatchSize(30);
|
||||
|
||||
for (int i = 0; i < numOfMasters; i++) {
|
||||
UTMaster master = createMaster(i);
|
||||
Ebean.save(master);
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
|
||||
} finally {
|
||||
transaction.end();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJdbcBatchOnCollection() {
|
||||
|
||||
int numOfMasters = 3;
|
||||
|
||||
List<UTMaster> masters = new ArrayList<UTMaster>();
|
||||
for (int i = 0; i < numOfMasters; i++) {
|
||||
masters.add(createMasterAndDetails(i));
|
||||
masters.add(createMasterAndDetails(i, 7));
|
||||
}
|
||||
|
||||
Transaction transaction = Ebean.beginTransaction();
|
||||
try {
|
||||
transaction.setBatchMode(true);
|
||||
transaction.setBatchSize(4);
|
||||
// transaction.setLogLevel(LogLevel.SUMMARY);
|
||||
// transaction.setBatchGetGeneratedKeys(false);
|
||||
transaction.setBatch(PersistBatch.NONE);
|
||||
transaction.setBatchOnCascade(PersistBatch.ALL);
|
||||
transaction.setBatchSize(20);
|
||||
|
||||
// escalate based on batchOnCascade value
|
||||
Ebean.save(masters);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
} finally {
|
||||
Ebean.endTransaction();
|
||||
transaction.end();
|
||||
}
|
||||
}
|
||||
|
||||
private UTMaster createMasterAndDetails(int masterPos) {
|
||||
@Test
|
||||
public void testJdbcBatchOnCollectionNoTransaction() {
|
||||
|
||||
int numOfMasters = 3;
|
||||
|
||||
List<UTMaster> masters = new ArrayList<UTMaster>();
|
||||
for (int i = 0; i < numOfMasters; i++) {
|
||||
masters.add(createMasterAndDetails(i, 5));
|
||||
}
|
||||
|
||||
// escalate based on batchOnCascade value
|
||||
Ebean.save(masters);
|
||||
|
||||
}
|
||||
|
||||
private UTMaster createMasterAndDetails(int masterPos, int size) {
|
||||
|
||||
UTMaster master = createMaster(masterPos);
|
||||
List<UTDetail> details = new ArrayList<UTDetail>();
|
||||
|
||||
int count = 2 + random.nextInt(20);
|
||||
int count = 2 + random.nextInt(size);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.avaje.tests.model.basic.xtra;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.config.PersistBatch;
|
||||
import org.avaje.ebeantest.LoggedSqlCollector;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestInsertBatchThenFlushThenUpdate extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
Transaction txn = Ebean.beginTransaction();
|
||||
try {
|
||||
txn.setBatch(PersistBatch.ALL);
|
||||
|
||||
EdParent parent = new EdParent();
|
||||
parent.setName("MyComputer");
|
||||
|
||||
EdChild child = new EdChild();
|
||||
child.setName("Harddisk 123");
|
||||
child.setParent(parent);
|
||||
ArrayList<EdChild> children = new ArrayList<EdChild>();
|
||||
children.add(child);
|
||||
parent.setChildren(children);
|
||||
|
||||
Ebean.save(parent);
|
||||
|
||||
// nothing flushed yet
|
||||
assertEquals(0, LoggedSqlCollector.start().size());
|
||||
|
||||
txn.flushBatch();
|
||||
|
||||
List<String> loggedSql1 = LoggedSqlCollector.start();
|
||||
assertEquals(loggedSql1.toString(), 2, loggedSql1.size());
|
||||
|
||||
parent.setName("MyDesk");
|
||||
Ebean.save(parent);
|
||||
|
||||
// nothing flushed yet
|
||||
assertEquals(0, LoggedSqlCollector.start().size());
|
||||
|
||||
Ebean.commitTransaction();
|
||||
|
||||
// insert statements for EdExtendedParent
|
||||
List<String> loggedSql2 = LoggedSqlCollector.start();
|
||||
assertEquals(2, loggedSql2.size());
|
||||
assertTrue(loggedSql2.get(0).contains(" update td_parent "));
|
||||
assertTrue(loggedSql2.get(1).contains(" update td_child "));
|
||||
|
||||
} finally {
|
||||
Ebean.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.avaje.tests.model.basic.xtra;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.config.PersistBatch;
|
||||
import org.avaje.ebeantest.LoggedSqlCollector;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestInsertBatchThenUpdate extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
Transaction txn = Ebean.beginTransaction();
|
||||
try {
|
||||
txn.setBatch(PersistBatch.ALL);
|
||||
|
||||
EdParent parent = new EdParent();
|
||||
parent.setName("MyComputer");
|
||||
|
||||
EdChild child = new EdChild();
|
||||
child.setName("Harddisk 123");
|
||||
child.setParent(parent);
|
||||
ArrayList<EdChild> children = new ArrayList<EdChild>();
|
||||
children.add(child);
|
||||
parent.setChildren(children);
|
||||
|
||||
Ebean.save(parent);
|
||||
|
||||
// nothing flushed yet
|
||||
List<String> loggedSql0 = LoggedSqlCollector.start();
|
||||
assertEquals(0, loggedSql0.size());
|
||||
|
||||
parent.setName("MyDesk");
|
||||
Ebean.save(parent);
|
||||
|
||||
// nothing flushed yet
|
||||
assertEquals(0, LoggedSqlCollector.start().size());
|
||||
|
||||
Ebean.commitTransaction();
|
||||
|
||||
// insert statements for EdExtendedParent
|
||||
List<String> loggedSql2 = LoggedSqlCollector.start();
|
||||
assertEquals(2, loggedSql2.size());
|
||||
|
||||
} finally {
|
||||
Ebean.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.avaje.tests.model.basic.xtra;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.config.PersistBatch;
|
||||
import org.avaje.ebeantest.LoggedSqlCollector;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TestInsertBatchWithDifferentRootTypes extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testDifferRootTypes() {
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
Transaction txn = Ebean.beginTransaction();
|
||||
try {
|
||||
txn.setBatch(PersistBatch.ALL);
|
||||
|
||||
EdParent parent = new EdParent();
|
||||
parent.setName("MyComputer");
|
||||
|
||||
EdChild child = new EdChild();
|
||||
child.setName("Harddisk 123");
|
||||
child.setParent(parent);
|
||||
ArrayList<EdChild> children = new ArrayList<EdChild>();
|
||||
children.add(child);
|
||||
parent.setChildren(children);
|
||||
|
||||
Ebean.save(parent);
|
||||
|
||||
EdExtendedParent extendedParent = new EdExtendedParent();
|
||||
extendedParent.setName("My second computer");
|
||||
extendedParent.setExtendedName("Multimedia");
|
||||
|
||||
child = new EdChild();
|
||||
child.setName("DVBS Card");
|
||||
children = new ArrayList<EdChild>();
|
||||
children.add(child);
|
||||
extendedParent.setChildren(children);
|
||||
|
||||
// nothing flushed yet
|
||||
List<String> loggedSql0 = LoggedSqlCollector.start();
|
||||
assertEquals(0, loggedSql0.size());
|
||||
|
||||
// causes a flush as EdExtendedParent is different from EdParent
|
||||
Ebean.save(extendedParent);
|
||||
|
||||
// insert statements for EdParent
|
||||
List<String> loggedSql1 = LoggedSqlCollector.start();
|
||||
assertEquals(2, loggedSql1.size());
|
||||
|
||||
Ebean.commitTransaction();
|
||||
|
||||
// insert statements for EdExtendedParent
|
||||
List<String> loggedSql2 = LoggedSqlCollector.start();
|
||||
assertEquals(2, loggedSql2.size());
|
||||
|
||||
} finally {
|
||||
Ebean.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,18 +2,39 @@ package com.avaje.tests.query.joins;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.avaje.ebean.*;
|
||||
import org.avaje.ebeantest.LoggedSqlCollector;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.FetchConfig;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.tests.model.basic.Order;
|
||||
import com.avaje.tests.model.basic.ResetBasicData;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestQueryJoinManyNonRoot extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test_manyPredicate() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
LoggedSqlCollector.start();
|
||||
|
||||
List<Order> orders = Ebean.find(Order.class)
|
||||
.select("id, status, orderDate")
|
||||
.where().gt("details.orderQty", 0)
|
||||
.findList();
|
||||
|
||||
assertTrue(!orders.isEmpty());
|
||||
|
||||
List<String> loggedSql = LoggedSqlCollector.stop();
|
||||
assertEquals(1, loggedSql.size());
|
||||
assertTrue(loggedSql.get(0).contains("select distinct "));
|
||||
assertTrue(loggedSql.get(0).contains(" from o_order t0 join o_order_detail u1 on u1.order_id = t0.id "));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_manyNonRoot() {
|
||||
|
||||
@@ -27,9 +48,9 @@ public class TestQueryJoinManyNonRoot extends BaseTestCase {
|
||||
List<Order> list = q.findList();
|
||||
String sql = q.getGeneratedSql();
|
||||
|
||||
Assert.assertTrue(list.size() > 0);
|
||||
Assert.assertTrue(sql.contains("join o_customer t1 on t1.id "));
|
||||
Assert.assertTrue(sql.contains("left outer join contact t2 on"));
|
||||
assertTrue(list.size() > 0);
|
||||
assertTrue(sql.contains("join o_customer t1 on t1.id "));
|
||||
assertTrue(sql.contains("left outer join contact t2 on"));
|
||||
|
||||
// select t0.id c0, t0.status c1, t0.order_date c2, t0.ship_date c3, t1.name c4, t0.cretime c5, t0.updtime c6,
|
||||
// t1.id c7, t1.status c8, t1.name c9, t1.smallnote c10, t1.anniversary c11, t1.cretime c12, t1.updtime c13, t1.billing_address_id c14, t1.shipping_address_id c15,
|
||||
@@ -56,10 +77,10 @@ public class TestQueryJoinManyNonRoot extends BaseTestCase {
|
||||
List<Order> list = q.findList();
|
||||
String sql = q.getGeneratedSql();
|
||||
|
||||
Assert.assertTrue(list.size() > 0);
|
||||
Assert.assertTrue(sql.contains("join o_customer t1 on t1.id "));
|
||||
Assert.assertTrue(sql.contains("left outer join o_order_detail "));
|
||||
Assert.assertTrue(sql.contains("left outer join o_product "));
|
||||
assertTrue(list.size() > 0);
|
||||
assertTrue(sql.contains("join o_customer t1 on t1.id "));
|
||||
assertTrue(sql.contains("left outer join o_order_detail "));
|
||||
assertTrue(sql.contains("left outer join o_product "));
|
||||
|
||||
Assert.assertFalse(sql.contains("left outer join contact"));
|
||||
|
||||
@@ -84,9 +105,9 @@ public class TestQueryJoinManyNonRoot extends BaseTestCase {
|
||||
order.getCustomer().getContacts().size();
|
||||
}
|
||||
|
||||
Assert.assertTrue(list.size() > 0);
|
||||
Assert.assertTrue(sql.contains("join o_customer t1 on t1.id "));
|
||||
Assert.assertTrue(sql.contains("left outer join contact "));
|
||||
assertTrue(list.size() > 0);
|
||||
assertTrue(sql.contains("join o_customer t1 on t1.id "));
|
||||
assertTrue(sql.contains("left outer join contact "));
|
||||
|
||||
Assert.assertFalse(sql.contains("left outer join o_order_detail "));
|
||||
Assert.assertFalse(sql.contains("left outer join o_product "));
|
||||
|
||||
Reference in New Issue
Block a user