From 2043fdf7e1a8b845b383c5287a965cb2fe8ba9e7 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 5 Aug 2021 13:12:18 +1200 Subject: [PATCH] #2274 Add DatabaseConfig jsonMutationDetection property setting the global default mode --- .../java/io/ebean/config/DatabaseConfig.java | 28 +++++++++++++++++-- .../server/type/DefaultTypeManager.java | 2 +- .../type/ScalarTypeJsonObjectMapper.java | 3 +- .../server/type/TypeJsonManager.java | 9 +++++- .../io/ebean/config/ServerConfigTest.java | 7 ++++- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java b/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java index 476007ebe..d1f0346b5 100644 --- a/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java +++ b/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java @@ -7,9 +7,7 @@ import io.ebean.EbeanVersion; import io.ebean.PersistenceContextScope; import io.ebean.Query; import io.ebean.Transaction; -import io.ebean.annotation.Encrypted; -import io.ebean.annotation.PersistBatch; -import io.ebean.annotation.Platform; +import io.ebean.annotation.*; import io.ebean.cache.ServerCachePlugin; import io.ebean.config.dbplatform.DatabasePlatform; import io.ebean.config.dbplatform.DbEncrypt; @@ -193,6 +191,11 @@ public class DatabaseConfig { */ private JsonConfig.Include jsonInclude = JsonConfig.Include.ALL; + /** + * The default mode used for {@code @DbJson} with Jackson ObjectMapper. + */ + private MutationDetection jsonMutationDetection = MutationDetection.HASH; + /** * The database platform name. Used to imply a DatabasePlatform to use. */ @@ -737,6 +740,24 @@ public class DatabaseConfig { this.jsonInclude = jsonInclude; } + /** + * Return the default MutableDetection to use with {@code @DbJson} using Jackson. + * + * @see DbJson#mutationDetection() + */ + public MutationDetection getJsonMutationDetection() { + return jsonMutationDetection; + } + + /** + * Set the default MutableDetection to use with {@code @DbJson} using Jackson. + * + * @see DbJson#mutationDetection() + */ + public void setJsonMutationDetection(MutationDetection jsonMutationDetection) { + this.jsonMutationDetection = jsonMutationDetection; + } + /** * Return the name of the Database. */ @@ -2909,6 +2930,7 @@ public class DatabaseConfig { jsonInclude = p.getEnum(JsonConfig.Include.class, "jsonInclude", jsonInclude); jsonDateTime = p.getEnum(JsonConfig.DateTime.class, "jsonDateTime", jsonDateTime); jsonDate = p.getEnum(JsonConfig.Date.class, "jsonDate", jsonDate); + jsonMutationDetection = p.getEnum(MutationDetection.class, "jsonMutationDetection", jsonMutationDetection); runMigration = p.getBoolean("migration.run", runMigration); ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java index 8ffb15372..1400b2180 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java @@ -134,7 +134,7 @@ public final class DefaultTypeManager implements TypeManager { this.postgres = isPostgres(config.getDatabasePlatform()); this.objectMapperPresent = config.getClassLoadConfig().isJacksonObjectMapperPresent(); this.objectMapper = (objectMapperPresent) ? initObjectMapper(config) : null; - this.jsonManager = (objectMapperPresent) ? new TypeJsonManager(postgres, objectMapper) : null; + this.jsonManager = (objectMapperPresent) ? new TypeJsonManager(postgres, objectMapper, config.getJsonMutationDetection()) : null; this.extraTypeFactory = new DefaultTypeFactory(config); this.arrayTypeListFactory = arrayTypeListFactory(config.getDatabasePlatform()); this.arrayTypeSetFactory = arrayTypeSetFactory(config.getDatabasePlatform()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonObjectMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonObjectMapper.java index 334f4b232..7ae24420f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonObjectMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonObjectMapper.java @@ -38,7 +38,8 @@ class ScalarTypeJsonObjectMapper { } else if (mode != MutationDetection.DEFAULT) { return new GenericObject(jsonManager, field, dbType, docType); } - prop.setMutationDetection(MutationDetection.HASH); + // using the global default MutationDetection mode (defaults to HASH) + prop.setMutationDetection(jsonManager.mutationDetection()); return new GenericObject(jsonManager, field, dbType, docType); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/TypeJsonManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/TypeJsonManager.java index 9cc0b5f0d..989ba2729 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/TypeJsonManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/TypeJsonManager.java @@ -2,16 +2,23 @@ package io.ebeaninternal.server.type; import com.fasterxml.jackson.databind.ObjectMapper; import io.ebean.ModifyAwareType; +import io.ebean.annotation.MutationDetection; import io.ebean.config.dbplatform.DbPlatformType; class TypeJsonManager { private final boolean postgres; private final ObjectMapper objectMapper; + private final MutationDetection mutationDetection; - TypeJsonManager(boolean postgres, Object objectMapper) { + TypeJsonManager(boolean postgres, Object objectMapper, MutationDetection mutationDetection) { this.postgres = postgres; this.objectMapper = (ObjectMapper) objectMapper; + this.mutationDetection = mutationDetection; + } + + MutationDetection mutationDetection() { + return mutationDetection; } ObjectMapper objectMapper() { diff --git a/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java b/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java index 55eb1f06e..46f283e55 100644 --- a/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java +++ b/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java @@ -1,6 +1,7 @@ package io.ebean.config; import com.fasterxml.jackson.databind.ObjectMapper; +import io.ebean.annotation.MutationDetection; import io.ebean.annotation.PersistBatch; import io.ebean.config.dbplatform.IdType; import io.ebean.datasource.DataSourceConfig; @@ -62,7 +63,7 @@ public class ServerConfigTest { props.setProperty("dbOffline", "true"); props.setProperty("jsonDateTime", "MILLIS"); props.setProperty("jsonDate", "MILLIS"); - props.setProperty("jsonDirtyByDefault", "false"); + props.setProperty("jsonMutationDetection", "NONE"); props.setProperty("autoReadOnlyDataSource", "true"); props.setProperty("disableL2Cache", "true"); props.setProperty("notifyL2CacheInForeground", "true"); @@ -98,6 +99,9 @@ public class ServerConfigTest { assertThat(serverConfig.getNamingConvention()).isInstanceOf(MatchingNamingConvention.class); + assertEquals(MutationDetection.NONE, serverConfig.getJsonMutationDetection()); + serverConfig.setJsonMutationDetection(MutationDetection.SOURCE); + assertEquals(MutationDetection.SOURCE, serverConfig.getJsonMutationDetection()); assertEquals(IdType.SEQUENCE, serverConfig.getIdType()); assertEquals(PersistBatch.ALL, serverConfig.getPersistBatch()); assertEquals(PersistBatch.ALL, serverConfig.getPersistBatchOnCascade()); @@ -156,6 +160,7 @@ public class ServerConfigTest { assertFalse(serverConfig.isIdGeneratorAutomatic()); assertEquals(JsonConfig.DateTime.ISO8601, serverConfig.getJsonDateTime()); assertEquals(JsonConfig.Date.ISO8601, serverConfig.getJsonDate()); + assertEquals(MutationDetection.HASH, serverConfig.getJsonMutationDetection()); assertTrue(serverConfig.getPlatformConfig().isCaseSensitiveCollation()); assertTrue(serverConfig.isAutoLoadModuleInfo());