From d710925cc7b2c9ba098caf354a43d72fae70f260 Mon Sep 17 00:00:00 2001 From: Noemi Praml Date: Mon, 17 Oct 2022 15:31:30 +0200 Subject: [PATCH 1/9] possible Fix --- .../server/executor/DefaultBackgroundExecutor.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/executor/DefaultBackgroundExecutor.java b/ebean-core/src/main/java/io/ebeaninternal/server/executor/DefaultBackgroundExecutor.java index d7975e04b..47271bc38 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/executor/DefaultBackgroundExecutor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/executor/DefaultBackgroundExecutor.java @@ -106,23 +106,23 @@ public final class DefaultBackgroundExecutor implements SpiBackgroundExecutor { @Override public ScheduledFuture scheduleWithFixedDelay(Runnable task, long initialDelay, long delay, TimeUnit unit) { - return schedulePool.scheduleWithFixedDelay(wrap(logExceptions(task)), initialDelay, delay, unit); + return schedulePool.scheduleWithFixedDelay(logExceptions(task), initialDelay, delay, unit); } @Override public ScheduledFuture scheduleAtFixedRate(Runnable task, long initialDelay, long delay, TimeUnit unit) { - return schedulePool.scheduleAtFixedRate(wrap(logExceptions(task)), initialDelay, delay, unit); + return schedulePool.scheduleAtFixedRate(logExceptions(task), initialDelay, delay, unit); } @Override public ScheduledFuture schedule(Runnable task, long delay, TimeUnit unit) { - return schedulePool.schedule(wrap(logExceptions(task)), delay, unit); + return schedulePool.schedule(logExceptions(task), delay, unit); } @Override public ScheduledFuture schedule(Callable task, long delay, TimeUnit unit) { // Note: No "logExceptions" as we expect Future.get() by the invoker - return schedulePool.schedule(wrap(task), delay, unit); + return schedulePool.schedule(task, delay, unit); } @Override From c855df8b8d6f707b11da03de2126abc6e5901581 Mon Sep 17 00:00:00 2001 From: Noemi Praml Date: Tue, 18 Oct 2022 07:59:19 +0200 Subject: [PATCH 2/9] javadoc --- .../main/java/io/ebean/config/BackgroundExecutorWrapper.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ebean-api/src/main/java/io/ebean/config/BackgroundExecutorWrapper.java b/ebean-api/src/main/java/io/ebean/config/BackgroundExecutorWrapper.java index b290e5863..28081c30f 100644 --- a/ebean-api/src/main/java/io/ebean/config/BackgroundExecutorWrapper.java +++ b/ebean-api/src/main/java/io/ebean/config/BackgroundExecutorWrapper.java @@ -6,6 +6,10 @@ import java.util.concurrent.Callable; * BackgroundExecutorWrapper that can be used to wrap tasks that are sent to background (i.e. another thread). * It should copy all necessary thread-local variables. See {@link MdcBackgroundExecutorWrapper} for implementation details. * + * Note: only tasks that are executed immediately (submit, execute) are wrapped. Periodic or scheduled tasks are not wrapped, + * as these may keep copied variables in memory either forever or until the scheduled task is finished. + * The caller is responsible to handle these cases. + * * @author Roland Praml, FOCONIS AG */ public interface BackgroundExecutorWrapper { From f4c747c6af15f0e03edde8f6326ad28f02d7f449 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 25 Oct 2022 08:52:15 +0200 Subject: [PATCH 3/9] FIX: LogFormat for SystemLogger --- .../io/ebeaninternal/server/idgen/UuidV1RndIdGenerator.java | 2 +- .../java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/idgen/UuidV1RndIdGenerator.java b/ebean-core/src/main/java/io/ebeaninternal/server/idgen/UuidV1RndIdGenerator.java index 21e34a8b3..adbf5e082 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/idgen/UuidV1RndIdGenerator.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/idgen/UuidV1RndIdGenerator.java @@ -106,7 +106,7 @@ public class UuidV1RndIdGenerator implements PlatformIdGenerator { delta = current - last; if (delta < -10000 * 20000) { - log.log(INFO, "Clock skew of {} ms detected", delta / -10000); + log.log(INFO, "Clock skew of {0} ms detected", delta / -10000); // The clock was adjusted back about 2 seconds, or we were generating a lot of ids too fast // if so, we try to set the current as last and also increment the clockSeq. lock.lock(); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java index 3ff9034d1..350c584e8 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/extraddl/model/ExtraDdlXmlReader.java @@ -42,7 +42,7 @@ public class ExtraDdlXmlReader { StringBuilder sb = new StringBuilder(300); for (DdlScript script : read.getDdlScript()) { if (script.isDrop() == drops && matchPlatform(platform, script.getPlatforms())) { - logger.log(DEBUG, "include script {}", script.getName()); + logger.log(DEBUG, "include script {0}", script.getName()); String value = script.getValue(); sb.append(value); if (value.lastIndexOf(';') == -1) { From 9d60ebd19e4dba246af73c3c54e241e576ae8bdf Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 25 Oct 2022 09:27:44 +0200 Subject: [PATCH 4/9] FIX: Typo --- .../java/io/ebeaninternal/server/core/SpiOrmQueryRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/SpiOrmQueryRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/SpiOrmQueryRequest.java index 039158200..174392918 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/SpiOrmQueryRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/SpiOrmQueryRequest.java @@ -121,7 +121,7 @@ public interface SpiOrmQueryRequest extends BeanQueryRequest, DocQueryRequ Map findMap(); /** - * Execute the findSingleAttributeList query. + * Execute the findSingleAttributeCollection query. */ > A findSingleAttributeCollection(A collection); From a82ba6d4aab3a78677d837c61c428e77a08a9bb7 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 25 Oct 2022 09:40:06 +0200 Subject: [PATCH 5/9] FIX: Flush transaction if it is modified in callback --- .../server/transaction/JdbcTransaction.java | 3 +++ .../transaction/JdbcTransactionTest.java | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java index 9fae2e21c..4b8408c27 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java @@ -885,6 +885,9 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { public final void preCommit() { internalBatchFlush(); firePreCommit(); + // we must flush the batch queue again, because the callback can + // modify current transaction + internalBatchFlush(); } /** diff --git a/ebean-test/src/test/java/io/ebean/xtest/internal/server/transaction/JdbcTransactionTest.java b/ebean-test/src/test/java/io/ebean/xtest/internal/server/transaction/JdbcTransactionTest.java index ce9e420b8..b306fef94 100644 --- a/ebean-test/src/test/java/io/ebean/xtest/internal/server/transaction/JdbcTransactionTest.java +++ b/ebean-test/src/test/java/io/ebean/xtest/internal/server/transaction/JdbcTransactionTest.java @@ -105,4 +105,25 @@ public class JdbcTransactionTest { assertThat(postCommitCallCount.get()).isEqualTo(2); // postcommit executed twice } } + + @Test + public void testFlushInCallback() { + try (Transaction transaction = DB.beginTransaction()) { + transaction.setBatchMode(true); + DB.currentTransaction().register( + new TransactionCallbackAdapter() { + + @Override + public void preCommit() { + EBasic basic = new EBasic("binner1"); + DB.save(basic); + } + } + ); + EBasic basic = new EBasic("bouter1"); + DB.save(basic); + transaction.commit(); // transaction will fail if recursive post-commit is failing + } + assertThat(DB.find(EBasic.class).where().eq("name", "binner1").exists()).isTrue(); + } } From b56fa851e0fc0a885ca66c2ee6684259cea3190f Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 25 Oct 2022 09:54:58 +0200 Subject: [PATCH 6/9] FIX: toJsonNanos for calendar --- .../java/io/ebeaninternal/server/type/ScalarTypeCalendar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCalendar.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCalendar.java index 8ac56e517..0331296cb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCalendar.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCalendar.java @@ -61,7 +61,7 @@ final class ScalarTypeCalendar extends ScalarTypeBaseDateTime { @Override protected String toJsonNanos(Calendar value) { - return String.valueOf(value.getTime()); + return String.valueOf(value.getTime().getTime()); } @Override From e2d75f4c2ed84cb167e85dc6b5573b32b30e43c5 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 25 Oct 2022 10:08:03 +0200 Subject: [PATCH 7/9] FIX: Add fallback for Ebean 11 Jsons --- .../server/type/ScalarTypeLocalDateTime.java | 9 ++++- .../type/ScalarTypeLocalDateTimeTest.java | 38 ++++++++++++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalDateTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalDateTime.java index 3de0184e1..eb84613ea 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalDateTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalDateTime.java @@ -11,6 +11,7 @@ import java.sql.Timestamp; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeParseException; /** * ScalarType for java.sql.Timestamp. @@ -48,7 +49,7 @@ final class ScalarTypeLocalDateTime extends ScalarTypeBaseDateTime Date: Tue, 25 Oct 2022 10:19:03 +0200 Subject: [PATCH 8/9] FIX: Run CsvReaderTest also in german locale --- .../src/test/java/io/ebean/csv/reader/CsvReaderTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ebean-csv-reader/src/test/java/io/ebean/csv/reader/CsvReaderTest.java b/ebean-csv-reader/src/test/java/io/ebean/csv/reader/CsvReaderTest.java index 8a871a62d..6504c219e 100644 --- a/ebean-csv-reader/src/test/java/io/ebean/csv/reader/CsvReaderTest.java +++ b/ebean-csv-reader/src/test/java/io/ebean/csv/reader/CsvReaderTest.java @@ -11,10 +11,11 @@ import java.io.Reader; import java.net.URL; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.Locale; class CsvReaderTest { - final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy"); + final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy", Locale.ENGLISH); @Test void test() throws Exception { From d190cd3a08a75d58b2ec1a3b0388d99cb0f2bef0 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 25 Oct 2022 14:18:54 +0200 Subject: [PATCH 9/9] NOCODE: Fix Whitespace --- .../java/org/tests/cache/TestQueryCache.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/ebean-test/src/test/java/org/tests/cache/TestQueryCache.java b/ebean-test/src/test/java/org/tests/cache/TestQueryCache.java index feff29a68..6e254ea6c 100644 --- a/ebean-test/src/test/java/org/tests/cache/TestQueryCache.java +++ b/ebean-test/src/test/java/org/tests/cache/TestQueryCache.java @@ -91,12 +91,12 @@ public class TestQueryCache extends BaseTestCase { // ensure that findCount & findSingleAttribute use different // slots in cache. If not a "Cannot cast List to int" should happen. int count = DB - .find(EColAB.class) - .setUseQueryCache(true) - .select("columnA") - .where() - .eq("columnB", "SingleAttribute") - .findCount(); + .find(EColAB.class) + .setUseQueryCache(true) + .select("columnA") + .where() + .eq("columnB", "SingleAttribute") + .findCount(); assertThat(count).isEqualTo(2); } @@ -305,7 +305,7 @@ public class TestQueryCache extends BaseTestCase { assertSame(list, list2B); List list3 = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(false).where() - .ilike("name", "Rob").findList(); + .ilike("name", "Rob").findList(); assertNotSame(list, list3); BeanCollection bc3 = (BeanCollection) list3; @@ -349,10 +349,10 @@ public class TestQueryCache extends BaseTestCase { // and now, ensure that we hit the database LoggedSql.start(); colA_second = DB.find(EColAB.class) - .setUseQueryCache(CacheMode.PUT) - .where() - .eq("columnB", "someId") - .findIds(); + .setUseQueryCache(CacheMode.PUT) + .where() + .eq("columnB", "someId") + .findIds(); sql = LoggedSql.stop(); assertThat(sql).hasSize(1); @@ -361,15 +361,15 @@ public class TestQueryCache extends BaseTestCase { @Test public void findCountDifferentQueriesBit() { DB.getDefault().pluginApi().cacheManager().clearAll(); - differentFindCount(q->q.bitwiseAny("id",1), q->q.bitwiseAny("id",0)); - differentFindCount(q->q.bitwiseAll("id",1), q->q.bitwiseAll("id",0)); + differentFindCount(q -> q.bitwiseAny("id", 1), q -> q.bitwiseAny("id", 0)); + differentFindCount(q -> q.bitwiseAll("id", 1), q -> q.bitwiseAll("id", 0)); // differentFindCount(q->q.bitwiseNot("id",1), q->q.bitwiseNot("id",0)); NOT 1 == AND 1 = 0 - differentFindCount(q->q.bitwiseAnd("id",1, 0), q->q.bitwiseAnd("id",1, 1)); + differentFindCount(q -> q.bitwiseAnd("id", 1, 0), q -> q.bitwiseAnd("id", 1, 1)); - differentFindCount(q->q.bitwiseAnd("id",2, 0), q->q.bitwiseAnd("id",4, 0)); - differentFindCount(q->q.bitwiseAnd("id",2, 1), q->q.bitwiseAnd("id",4, 1)); + differentFindCount(q -> q.bitwiseAnd("id", 2, 0), q -> q.bitwiseAnd("id", 4, 0)); + differentFindCount(q -> q.bitwiseAnd("id", 2, 1), q -> q.bitwiseAnd("id", 4, 1)); // Will produce hash collision - differentFindCount(q->q.bitwiseAnd("id",10, 0), q->q.bitwiseAnd("id",0, 928210)); + differentFindCount(q -> q.bitwiseAnd("id", 10, 0), q -> q.bitwiseAnd("id", 0, 928210)); }