diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java index 830b825f5..82ae78451 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java @@ -338,7 +338,6 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery private int notifyCache(int rows, boolean update) { if (rows > 0) { - beanDescriptor.contextClear(transaction.persistenceContext()); beanDescriptor.cacheUpdateQuery(update, transaction); } return rows; @@ -783,4 +782,10 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery public int forwardOnlyFetchSize() { return queryEngine.forwardOnlyFetchSize(); } + + public void clearContext() { + if (!transaction.isAutoPersistUpdates()) { + beanDescriptor.contextClear(transaction.persistenceContext()); + } + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestOrmUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestOrmUpdate.java index 4c6771cbb..9e93a064f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestOrmUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestOrmUpdate.java @@ -78,7 +78,7 @@ public final class PersistRequestOrmUpdate extends PersistRequest { @Override public void postExecute() { OrmUpdateType ormUpdateType = ormUpdate.ormUpdateType(); - if (OrmUpdateType.INSERT != ormUpdateType) { + if (OrmUpdateType.INSERT != ormUpdateType && !transaction.isAutoPersistUpdates()) { beanDescriptor.contextClear(transaction.persistenceContext()); } if (startNanos > 0) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestUpdateSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestUpdateSql.java index dc6d0b5de..a5453420f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestUpdateSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistRequestUpdateSql.java @@ -159,7 +159,7 @@ public final class PersistRequestUpdateSql extends PersistRequest { */ @Override public void postExecute() { - if (sqlType != SqlType.SQL_INSERT) { + if (sqlType != SqlType.SQL_INSERT && !transaction.isAutoPersistUpdates()) { List> descriptors = server.descriptors(tableName); if (descriptors != null) { for (BeanDescriptor descriptor : descriptors) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryEngine.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryEngine.java index 969d7ca25..a0dab920a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryEngine.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryEngine.java @@ -74,6 +74,9 @@ public final class CQueryEngine { if (request.logSql()) { request.logSql("{0}; --bind({1}) --micros({2}) --rows({3})", query.generatedSql(), query.bindLog(), query.micros(), rows); } + if (rows > 0) { + request.clearContext(); + } return rows; } catch (SQLException e) { throw translate(request, query.bindLog(), query.generatedSql(), e); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryUpdate.java index 85081238b..add07241a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryUpdate.java @@ -61,6 +61,7 @@ final class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery /** * Execute the update or delete statement returning the row count. */ + @SuppressWarnings("resource") public int execute() throws SQLException { long startNano = System.nanoTime(); try { @@ -109,6 +110,7 @@ final class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery pstmt = null; } + @SuppressWarnings("resource") @Override public void profile() { transaction() diff --git a/ebean-test/src/test/java/org/tests/persistencecontext/TestPersistenceContextQueryScope.java b/ebean-test/src/test/java/org/tests/persistencecontext/TestPersistenceContextQueryScope.java index f82f855d1..2715196a9 100644 --- a/ebean-test/src/test/java/org/tests/persistencecontext/TestPersistenceContextQueryScope.java +++ b/ebean-test/src/test/java/org/tests/persistencecontext/TestPersistenceContextQueryScope.java @@ -19,8 +19,6 @@ class TestPersistenceContextQueryScope extends BaseTestCase { EBasicVer bean = new EBasicVer("first"); DB.save(bean); - //DB.cacheManager().setCaching(EBasicVer.class, true); - try (Transaction txn = DB.beginTransaction()) { EBasicVer bean1 = DB.find(EBasicVer.class, bean.getId()); @@ -47,7 +45,7 @@ class TestPersistenceContextQueryScope extends BaseTestCase { .setPersistenceContextScope(QUERY) .findOne(); - // TRANsACTION scope ... same as bean2 and does not hit the DB + // TRANSACTION scope ... same as bean2 and does not hit the DB EBasicVer bean5 = DB.find(EBasicVer.class) .setId(bean.getId()) .setUseCache(false) // ignore L2 cache @@ -57,11 +55,13 @@ class TestPersistenceContextQueryScope extends BaseTestCase { assertEquals("first", bean.getName()); assertEquals("first", bean1.getName()); assertEquals("second", bean2.getName()); + assertEquals("second", bean3.getName()); assertEquals("second", bean5.getName()); assertNotSame(bean1, bean2); assertNotSame(bean1, bean5); + assertSame(bean2, bean5); + assertNotSame(bean3, bean5); - assertEquals("second", bean3.getName()); DB.delete(bean3); txn.commit(); @@ -99,7 +99,7 @@ class TestPersistenceContextQueryScope extends BaseTestCase { .setPersistenceContextScope(QUERY) .findOne(); - // TRANsACTION scope ... same as bean2 and does not hit the DB + // TRANSACTION scope ... same as bean2 and does not hit the DB EBasicVer bean5 = DB.find(EBasicVer.class) .setId(bean.getId()) .setUseCache(false) // ignore L2 cache @@ -113,6 +113,8 @@ class TestPersistenceContextQueryScope extends BaseTestCase { assertEquals("second", bean5.getName()); assertNotSame(bean1, bean2); assertNotSame(bean1, bean5); + assertSame(bean2, bean5); + assertNotSame(bean3, bean5); DB.delete(bean3); txn.commit(); @@ -151,7 +153,7 @@ class TestPersistenceContextQueryScope extends BaseTestCase { .setPersistenceContextScope(QUERY) .findOne(); - // TRANsACTION scope ... same as bean2 and does not hit the DB + // TRANSACTION scope ... same as bean2 and does not hit the DB EBasicVer bean5 = DB.find(EBasicVer.class) .setId(bean.getId()) .setUseCache(false) // ignore L2 cache @@ -165,6 +167,63 @@ class TestPersistenceContextQueryScope extends BaseTestCase { assertEquals("second", bean5.getName()); assertNotSame(bean1, bean2); assertNotSame(bean1, bean5); + assertSame(bean2, bean5); + assertNotSame(bean3, bean5); + + DB.delete(bean3); + txn.commit(); + } + } + + + @Test + void ormUpdateQueryWithAutoPersist_expect_clearsContext() { + + EBasicVer bean = new EBasicVer("first"); + DB.save(bean); + + try (Transaction txn = DB.beginTransaction()) { + txn.setAutoPersistUpdates(true); + EBasicVer bean1 = DB.find(EBasicVer.class, bean.getId()); + + // do an update of the name in the DB + int rowCount = DB.update(EBasicVer.class) + .set("name", "second") + .where().idEq(bean.getId()) + .update(); + assertEquals(1, rowCount); + + // fetch the bean again... but doesn't hit DB as it + // is in the PersistenceContext which is transaction scoped + EBasicVer bean2 = DB.find(EBasicVer.class) + .setId(bean.getId()) + .setUseCache(false) // ignore L2 cache + .findOne(); + + // QUERY scope hits the DB (doesn't use the existing transactions persistence context) + // ... also explicitly not use bean cache + EBasicVer bean3 = DB.find(EBasicVer.class) + .setId(bean.getId()) + .setUseCache(false) // ignore L2 cache + .setPersistenceContextScope(QUERY) + .findOne(); + + // TRANSACTION scope ... same as bean2 and does not hit the DB + EBasicVer bean5 = DB.find(EBasicVer.class) + .setId(bean.getId()) + .setUseCache(false) // ignore L2 cache + .setPersistenceContextScope(TRANSACTION) + .findOne(); + + assertEquals("first", bean.getName()); + assertEquals("first", bean1.getName()); + assertEquals("first", bean2.getName()); // This is still first + assertEquals("second", bean3.getName()); + assertEquals("first", bean5.getName()); // This is still first + assertSame(bean1, bean2); // Now the same + assertSame(bean1, bean5); // Now the same + assertSame(bean2, bean5); + assertNotSame(bean3, bean5); DB.delete(bean3); txn.commit();