From bd7499a5054564119b6609e1be94f8c43c87f181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20P=C3=B6hler=20=28JPo=29?= Date: Mon, 29 Mar 2021 13:23:56 +0200 Subject: [PATCH 001/120] Use SoftReference in Cache, so it can be gc'ed if the jvm runs out of memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonas Pöhler (JPo) --- .../server/cache/DefaultServerCache.java | 45 +++++++++++-------- .../cache/DefaultServerCacheConfig.java | 8 ++-- .../server/cache/DefaultServerQueryCache.java | 5 ++- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCache.java b/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCache.java index 41ec3e2c9..334a0838a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCache.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCache.java @@ -11,6 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; +import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; @@ -37,7 +38,7 @@ public class DefaultServerCache implements ServerCache { /** * The underlying map (ConcurrentHashMap or similar) */ - protected final Map map; + protected final Map> map; protected final CountMetric hitCount; protected final CountMetric missCount; @@ -199,7 +200,8 @@ public class DefaultServerCache implements ServerCache { * Get the cache entry - override for query cache to validate dependent tables. */ protected CacheEntry getCacheEntry(Object id) { - return map.get(key(id)); + final SoftReference ref = map.get(key(id)); + return ref != null ? ref.get() : null; } @Override @@ -213,7 +215,7 @@ public class DefaultServerCache implements ServerCache { @Override public void put(Object id, Object value) { Object key = key(id); - map.put(key, new CacheEntry(key, value)); + map.put(key, new SoftReference<>(new CacheEntry(key, value))); putCount.increment(); } @@ -222,8 +224,8 @@ public class DefaultServerCache implements ServerCache { */ @Override public void remove(Object id) { - CacheEntry entry = map.remove(key(id)); - if (entry != null) { + SoftReference entry = map.remove(key(id)); + if (entry != null && entry.get() != null) { removeCount.increment(); } } @@ -266,6 +268,7 @@ public class DefaultServerCache implements ServerCache { long startNanos = System.nanoTime(); long trimmedByIdle = 0; + long trimmedByGC = 0; long trimmedByTTL = 0; long trimmedByLRU = 0; @@ -274,10 +277,14 @@ public class DefaultServerCache implements ServerCache { long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs); long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive); - Iterator it = map.values().iterator(); + Iterator> it = map.values().iterator(); while (it.hasNext()) { - CacheEntry cacheEntry = it.next(); - if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) { + SoftReference ref = it.next(); + final CacheEntry cacheEntry = ref.get(); + if (cacheEntry == null) { + it.remove(); + trimmedByGC++; + } else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) { it.remove(); trimmedByIdle++; @@ -290,27 +297,27 @@ public class DefaultServerCache implements ServerCache { } } - if (trimForMaxSize > 0) { - trimmedByLRU = activeList.size() - maxSize; - if (trimmedByLRU > 0) { - // sort into last access time ascending - activeList.sort(BY_LAST_ACCESS); - int trimSize = getTrimSize(); - for (int i = trimSize; i < activeList.size(); i++) { - // remove if still in the cache - map.remove(activeList.get(i).getKey()); + if (trimForMaxSize > 0 && activeList.size() > maxSize) { + // sort into last access time ascending + activeList.sort(BY_LAST_ACCESS); + int trimSize = getTrimSize(); + for (int i = trimSize; i < activeList.size(); i++) { + // remove if still in the cache + if (map.remove(activeList.get(i).getKey()) != null) { + trimmedByLRU++; } } } evictCount.add(trimmedByIdle); + evictCount.add(trimmedByGC); evictCount.add(trimmedByTTL); evictCount.add(trimmedByLRU); if (logger.isTraceEnabled()) { long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS); - logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}]" - , name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU); + logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]", + name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCacheConfig.java b/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCacheConfig.java index 638f237a2..5f8ed1d5d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCacheConfig.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerCacheConfig.java @@ -4,7 +4,9 @@ import io.ebean.cache.QueryCacheEntryValidate; import io.ebean.cache.ServerCacheConfig; import io.ebean.cache.ServerCacheOptions; import io.ebean.config.CurrentTenantProvider; +import io.ebeaninternal.server.cache.DefaultServerCache.CacheEntry; +import java.lang.ref.SoftReference; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -17,13 +19,13 @@ public class DefaultServerCacheConfig { private int maxSecsToLive; private int trimFrequency; - private Map map; + private Map> map; public DefaultServerCacheConfig(ServerCacheConfig config) { this(config, new ConcurrentHashMap<>()); } - public DefaultServerCacheConfig(ServerCacheConfig config, Map map) { + public DefaultServerCacheConfig(ServerCacheConfig config, Map> map) { this.config = config; this.map = map; @@ -50,7 +52,7 @@ public class DefaultServerCacheConfig { return config.getShortName(); } - public Map getMap() { + public Map> getMap() { return map; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerQueryCache.java b/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerQueryCache.java index afbdb37f7..4f437eafc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerQueryCache.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/cache/DefaultServerQueryCache.java @@ -3,6 +3,8 @@ package io.ebeaninternal.server.cache; import io.ebean.cache.QueryCacheEntry; import io.ebean.cache.QueryCacheEntryValidate; +import java.lang.ref.SoftReference; + /** * Server cache for query caching. *

@@ -27,7 +29,8 @@ public class DefaultServerQueryCache extends DefaultServerCache { @Override protected CacheEntry getCacheEntry(Object id) { Object key = key(id); - CacheEntry entry = map.get(key); + final SoftReference ref = map.get(key); + CacheEntry entry = ref != null ? ref.get() : null; if (entry == null) { return null; } From 7e265f7bde97120cf66e59e43abf044e0b047764 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 13 Jul 2021 09:09:30 +0200 Subject: [PATCH 002/120] FIX: SubQuery with fetch-path does not work correctly --- .../server/query/SqlTreeBuilder.java | 2 +- .../server/querydefn/DefaultOrmQuery.java | 4 +- .../java/org/tests/query/TestSubQuery.java | 71 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java index 239e8a58e..e4c936e45 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java @@ -311,7 +311,7 @@ public final class SqlTreeBuilder { } else { // do not read Id on child beans (e.g. when used with fetch()) - boolean withId = isNotSingleAttribute(); + boolean withId = isNotSingleAttribute() && !subQuery; return new SqlTreeNodeBean(prefix, prop, props, myList, withId, temporalMode, disableLazyLoad); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index 96a923637..3a81183e9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -616,7 +616,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { * Limit the number of fetch joins to Many properties, mark as query joins as needed. */ private void markQueryJoins() { - detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), type != Type.ATTRIBUTE); + detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), type != Type.ATTRIBUTE && type != Type.SUBQUERY); } private boolean isAllowOneManyFetch() { @@ -629,7 +629,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { @Override public void setDefaultSelectClause() { - if (type != Type.ATTRIBUTE) { + if (type != Type.ATTRIBUTE && type != Type.SUBQUERY) { detail.setDefaultSelectClause(beanDescriptor); } else if (!detail.hasSelectClause()) { // explicit empty select when single attribute query on non-root fetch path diff --git a/ebean-core/src/test/java/org/tests/query/TestSubQuery.java b/ebean-core/src/test/java/org/tests/query/TestSubQuery.java index db9eb7cbd..61ffacf56 100644 --- a/ebean-core/src/test/java/org/tests/query/TestSubQuery.java +++ b/ebean-core/src/test/java/org/tests/query/TestSubQuery.java @@ -6,6 +6,8 @@ import io.ebean.Query; import org.junit.Test; import org.tests.model.basic.CKeyParent; import org.tests.model.basic.Order; +import org.tests.model.basic.OrderDetail; +import org.tests.model.basic.OrderShipment; import org.tests.model.basic.ResetBasicData; import org.tests.model.basic.Vehicle; import org.tests.model.basic.VehicleDriver; @@ -47,6 +49,75 @@ public class TestSubQuery extends BaseTestCase { DB.find(Order.class).where().isIn("id", sq).findList(); } + /** + * Testcase, that discovered, that DefaultOrmQuery.setDefaultSelectClause is set on subQueries with fetch path. + * Also checks, that SqlTreeBuilder does not read id on Many2One props. + */ + @Test + public void test_IsInWithFetchSubQuery1() { + + List productIds = new ArrayList<>(); + productIds.add(3); + + Query sq = DB.createQuery(OrderDetail.class).fetch("order", "id").where() + .isIn("product.id", productIds).query(); + + // execute the subQuery as copy (generatedSQL must be part of original query) + Query debugSq = sq.copy(); + debugSq.findSingleAttribute(); + assertThat(debugSq.getGeneratedSql()).isEqualTo( + "select t1.id from o_order_detail t0 join o_order t1 on t1.id = t0.order_id where t0.product_id in (?)"); + + Query query = DB.find(Order.class).select("shipDate").where().isIn("id", sq).query(); + query.findSingleAttribute(); + + assertThat(query.getGeneratedSql()) + .isEqualTo("select t0.ship_date from o_order t0 where (t0.id) in (" + debugSq.getGeneratedSql() + ")"); + } + + /** + * Test checks, that DefaultOrmQuery.markQueryJoins handles subQuery correct. + */ + @Test + public void test_IsInWithFetchSubQuery2() { + + Query sq = DB.createQuery(OrderDetail.class).fetch("order.customer", "anniversary").where() + .eq("order.customer.name", "Roland") + .query().setDistinct(true); + + // execute the subQuery as copy (generatedSQL must be part of original query) + Query debugSq = sq.copy(); + debugSq.findSingleAttribute(); + + Query query = DB.find(Order.class).select("status").where().isIn("shipDate", sq).query(); + query.findSingleAttribute(); + assertThat(query.getGeneratedSql()) + .isEqualTo("select t0.status from o_order t0 where (t0.ship_date) in (" + debugSq.getGeneratedSql() + ")"); + } + + /** + * Checks, that SqlTreeBuilder does not read id on One2Many props. + */ + @Test + public void test_IsInWithFetchSubQuery3() { + + List productIds = new ArrayList<>(); + productIds.add(3); + + Query sq = DB.createQuery(OrderDetail.class).fetch("order.shipments", "id").where() + .isIn("product.id", productIds).query(); + + // execute the subQuery as copy (generatedSQL must be part of original query) + Query debugSq = sq.copy(); + debugSq.findSingleAttribute(); + + Query query = DB.find(OrderShipment.class).select("shipTime").where().isIn("id", sq).query(); + query.findSingleAttribute(); + + assertThat(query.getGeneratedSql()) + .isEqualTo("select t0.ship_time from or_order_ship t0 where (t0.id) in (" + debugSq.getGeneratedSql() + ")"); + } + public void testCompositeKey() { ResetBasicData.reset(); From 6c262f1df549d07298431941bc08c71b9b2da6e8 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 23 Jul 2021 16:50:24 +1200 Subject: [PATCH 003/120] JSON bean dirty detection via MD5 of JSON string content - MD5 of json content stored on EntityBeanIntercept for dirty detection - Only convert to JSON once (at dirty detection time). Store this json content on EntityBeanIntercept to later push to ScalarTypeJsonObjectMapper for bind Should consider alternative to extend BeanProperty rather than have these if blocks. --- .../io/ebean/bean/EntityBeanIntercept.java | 33 +++++++++ .../java/io/ebean/core/type/DataBinder.java | 11 +++ .../java/io/ebean/core/type/DataReader.java | 10 +++ .../java/io/ebean/core/type/ScalarType.java | 8 ++ .../server/deploy/BeanDescriptor.java | 4 +- .../server/deploy/BeanProperty.java | 47 ++++++++---- .../server/persist/dml/DmlHandler.java | 5 ++ .../dmlbind/BindablePropertyJsonInsert.java | 42 +++++++++++ .../dmlbind/BindablePropertyJsonUpdate.java | 35 +++++++++ .../persist/dmlbind/BindableRequest.java | 5 ++ .../persist/dmlbind/FactoryProperty.java | 7 ++ .../server/query/SqlBeanLoad.java | 11 ++- .../ebeaninternal/server/type/DataBind.java | 11 +++ .../server/type/RsetDataReader.java | 15 +++- .../type/ScalarTypeJsonObjectMapper.java | 52 ++++++++++++- .../org/tests/json/TestDbJson_Jackson3.java | 3 +- .../java/org/tests/json/TestDbJson_List.java | 12 ++- .../org/tests/model/json/EBasicPlain.java | 54 ++++++++++++++ .../model/json/TestJacksonPlainBean.java | 73 +++++++++++++++++++ 19 files changed, 404 insertions(+), 34 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java create mode 100644 ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java create mode 100644 ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java index 28a088ce6..59a2450bd 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -91,6 +91,17 @@ public final class EntityBeanIntercept implements Serializable { private Object ownerId; private int sortOrder; + /** + * Holds MD5 hash of json loaded jackson beans. + */ + private String[] mutableHash; + + /** + * Holds json content determined at point of dirty check. + * Stored here on dirty check such that we only convert to json once. + */ + private String[] mutableContent; + /** * Create a intercept with a given entity. */ @@ -1138,4 +1149,26 @@ public final class EntityBeanIntercept implements Serializable { } return ret; } + + public String mutableHash(int propertyIndex) { + return mutableHash == null ? null : mutableHash[propertyIndex]; + } + + public void mutableHash(int propertyIndex, String content) { + if (mutableHash == null) { + mutableHash = new String[flags.length]; + } + mutableHash[propertyIndex] = content; + } + + public String mutableContent(int propertyIndex) { + return mutableContent == null ? null : mutableContent[propertyIndex]; + } + + public void mutableContent(int propertyIndex, String content) { + if (mutableContent == null) { + mutableContent = new String[flags.length]; + } + mutableContent[propertyIndex] = content; + } } diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/DataBinder.java b/ebean-core-type/src/main/java/io/ebean/core/type/DataBinder.java index be6a3b559..b08bb529a 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/DataBinder.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/DataBinder.java @@ -163,4 +163,15 @@ public interface DataBinder { * Bind an array value. */ void setArray(String arrayType, Object[] elements) throws SQLException; + + /** + * Push json from dirty detection to be available for binding. + */ + void pushJson(String json); + + /** + * Pop json made during dirty detection for scalarType binding. + */ + String popJson(); + } diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/DataReader.java b/ebean-core-type/src/main/java/io/ebean/core/type/DataReader.java index a8ace12be..ef61b9122 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/DataReader.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/DataReader.java @@ -48,4 +48,14 @@ public interface DataReader { Object getObject() throws SQLException; InputStream getBinaryStream() throws SQLException; + + /** + * Push json from dirty detection to be available for binding. + */ + void pushJson(String json); + + /** + * Pop json made during dirty detection for scalarType binding. + */ + String popJson(); } diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java index a971a0115..831664991 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java @@ -34,6 +34,14 @@ import java.sql.SQLException; */ public interface ScalarType extends StringParser, StringFormatter, ScalarDataReader { + default boolean isJsonMapper() { + return false; + } + + default String jsonMapper(Object value) { + throw new UnsupportedOperationException(); + } + /** * Return true if this is a binary type and can not support parse() and format() from/to string. * This allows Ebean to optimise marshalling types to string. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 63599b7ad..d165b1489 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -2022,7 +2022,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { public boolean isTableManaged(String tableName) { return owner.isTableManaged(tableName); } - + /** * Return the order column property. */ @@ -3200,7 +3200,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { int propertyIndex = beanProperty.getPropertyIndex(); if (!ebi.isDirtyProperty(propertyIndex) && ebi.isLoadedProperty(propertyIndex)) { Object value = beanProperty.getValue(ebi.getOwner()); - if (value != null && beanProperty.isDirtyValue(value)) { + if (value != null && beanProperty.isDirtyValue(value, ebi)) { // mutable scalar value which is considered dirty so mark // it as such so that it is included in an update ebi.markPropertyAsChanged(propertyIndex); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index 8793942b6..d3c832c85 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -13,6 +13,7 @@ import io.ebean.core.type.DocPropertyType; import io.ebean.core.type.ScalarType; import io.ebean.plugin.Property; import io.ebean.text.StringParser; +import io.ebean.text.TextException; import io.ebean.util.SplitName; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.api.SpiQuery; @@ -31,11 +32,8 @@ import io.ebeaninternal.server.properties.BeanPropertySetter; import io.ebeaninternal.server.query.STreeProperty; import io.ebeaninternal.server.query.SqlBeanLoad; import io.ebeaninternal.server.query.SqlJoinType; -import io.ebeaninternal.server.type.DataBind; -import io.ebeaninternal.server.type.LocalEncryptedType; -import io.ebeaninternal.server.type.ScalarTypeBoolean; -import io.ebeaninternal.server.type.ScalarTypeEnum; -import io.ebeaninternal.server.type.ScalarTypeLogicalType; +import io.ebeaninternal.server.type.*; +import io.ebeaninternal.server.util.Md5; import io.ebeaninternal.util.ValueUtil; import io.ebeanservice.docstore.api.mapping.DocMappingBuilder; import io.ebeanservice.docstore.api.mapping.DocPropertyMapping; @@ -54,6 +52,7 @@ import java.sql.SQLException; import java.sql.Types; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; /** @@ -220,6 +219,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { */ @SuppressWarnings("rawtypes") final ScalarType scalarType; + final boolean jsonMapperType; private final DocPropertyOptions docOptions; @@ -333,6 +333,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { this.formula = sqlFormulaSelect != null; this.dbType = deploy.getDbType(); this.scalarType = deploy.getScalarType(); + this.jsonMapperType = (scalarType == null) ? false : scalarType.isJsonMapper(); this.lob = isLobType(dbType); this.propertyType = deploy.getPropertyType(); this.field = deploy.getField(); @@ -427,6 +428,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { this.setter = source.setter; this.dbType = source.getDbType(true); this.scalarType = source.scalarType; + this.jsonMapperType = source.jsonMapperType; this.lob = isLobType(dbType); this.propertyType = source.getPropertyType(); this.field = source.getField(); @@ -630,8 +632,17 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { Object value = scalarType.read(reader); if (bean != null) { setValue(bean, value); + if (jsonMapperType) { + String json = reader.popJson(); + if (json != null) { + final String hash = Md5.hash(json); + bean._ebean_getIntercept().mutableHash(propertyIndex, hash); + } + } } return value; + } catch (TextException e) { + throw e; } catch (Exception e) { throw new PersistenceException("Error readSet on " + descriptor + "." + name, e); } @@ -643,13 +654,11 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { public Object readSet(DbReadContext ctx, EntityBean bean) throws SQLException { try { - Object value = scalarType.read(ctx.getDataReader()); - if (bean != null) { - setValue(bean, value); - } - return value; - } catch (Exception e) { - throw new PersistenceException("Error readSet on " + descriptor + "." + name, e); + return readSet(ctx.getDataReader(), bean); + } catch (TextException e) { + bean._ebean_getIntercept().setLoadError(propertyIndex, e); + ctx.handleLoadError(getFullBeanName(), e); + return getValue(bean); } } @@ -1018,7 +1027,19 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { * Return true if the mutable value is considered dirty. * This is only used for 'mutable' scalar types like hstore etc. */ - boolean isDirtyValue(Object value) { + boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { + if (jsonMapperType) { + // dirty detection based on md5 hash of json content + final String json = scalarType.jsonMapper(value); + final String newHash = Md5.hash(json); + final String oldHash = ebi.mutableHash(propertyIndex); + if (!Objects.equals(newHash, oldHash)) { + ebi.mutableContent(propertyIndex, json); // so we only convert to json once + ebi.mutableHash(propertyIndex, newHash); // for dirty detection next time + return true; + } + return false; + } return scalarType.isDirty(value); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlHandler.java index 189613808..0a4bb6b8a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlHandler.java @@ -63,6 +63,11 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest { } } + @Override + public void pushJson(String json) { + dataBind.pushJson(json); + } + @Override public long now() { return now; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java new file mode 100644 index 000000000..0a93452f1 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java @@ -0,0 +1,42 @@ +package io.ebeaninternal.server.persist.dmlbind; + +import io.ebean.bean.EntityBean; +import io.ebeaninternal.server.deploy.BeanProperty; +import io.ebeaninternal.server.util.Md5; + +import java.sql.SQLException; + +/** + * For JSON Jackson properties - dirty detection via MD5 of json content. + */ +class BindablePropertyJsonInsert extends BindableProperty { + + private final int propertyIndex; + + BindablePropertyJsonInsert(BeanProperty prop) { + super(prop); + this.propertyIndex = prop.getPropertyIndex(); + } + + /** + * Normal binding of a property value from the bean. + */ + @Override + public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { + if (bean == null) { + request.bind(null, prop); + } else { + Object value = prop.getValue(bean); + if (value == null) { + request.bind(null, prop); + } else { + // on insert store MD5 hash and push json + final String json = prop.format(value); + final String hash = Md5.hash(json); + bean._ebean_getIntercept().mutableHash(propertyIndex, hash); + request.pushJson(json); + request.bind(value, prop); + } + } + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java new file mode 100644 index 000000000..3418369f5 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java @@ -0,0 +1,35 @@ +package io.ebeaninternal.server.persist.dmlbind; + +import io.ebean.bean.EntityBean; +import io.ebeaninternal.server.deploy.BeanProperty; + +import java.sql.SQLException; + +/** + * For JSON Jackson properties - dirty detection via MD5 of json content. + */ +class BindablePropertyJsonUpdate extends BindableProperty { + + private final int propertyIndex; + + BindablePropertyJsonUpdate(BeanProperty prop) { + super(prop); + this.propertyIndex = prop.getPropertyIndex(); + } + + /** + * Normal binding of a property value from the bean. + */ + @Override + public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { + if (bean == null) { + request.bind(null, prop); + } else { + // on update push json + final String json = bean._ebean_getIntercept().mutableContent(propertyIndex); + request.pushJson(json); + final Object value = prop.getValue(bean); + request.bind(value, prop); + } + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableRequest.java index 4a1fc6754..e06862e86 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableRequest.java @@ -57,4 +57,9 @@ public interface BindableRequest { * Return true if this is an update request. */ boolean isUpdate(); + + /** + * Push json content for scalarType bind(). + */ + void pushJson(String json); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java index b47b4ecb6..78ceb098b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java @@ -43,6 +43,13 @@ class FactoryProperty { return new BindableAssocOne((BeanPropertyAssocOne)prop); } + if (prop.getScalarType().isJsonMapper()) { + if (DmlMode.INSERT == mode) { + return new BindablePropertyJsonInsert(prop); + } else if (DmlMode.UPDATE == mode) { + return new BindablePropertyJsonUpdate(prop); + } + } return new BindableProperty(prop); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java index ac1386e11..20d1dfddb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java @@ -25,7 +25,6 @@ public class SqlBeanLoad { private final boolean rawSql; SqlBeanLoad(DbReadContext ctx, Class type, EntityBean bean, Mode queryMode) { - this.ctx = ctx; this.rawSql = ctx.isRawSql(); this.type = type; @@ -69,16 +68,16 @@ public class SqlBeanLoad { } try { - Object dbVal = prop.read(ctx); if (!refreshLoading) { - prop.setValue(bean, dbVal); - } else { - prop.setValueIntercept(bean, dbVal); + return prop.readSet(ctx, bean); } - + // TODO: maybe create prop.readSetIntercept() and move this + Object dbVal = prop.read(ctx); + prop.setValueIntercept(bean, dbVal); return dbVal; } catch (Exception e) { + // TODO: maybe move this into prop.readSetIntercept() bean._ebean_getIntercept().setLoadError(prop.getPropertyIndex(), e); ctx.handleLoadError(prop.getFullBeanName(), e); return prop.getValue(bean); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java index 2959c872c..489046405 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java @@ -36,6 +36,7 @@ public class DataBind implements DataBinder { private List inputStreams; protected int pos; + private String json; public DataBind(DataTimeZone dataTimeZone, PreparedStatement pstmt, Connection connection) { this.dataTimeZone = dataTimeZone; @@ -43,6 +44,16 @@ public class DataBind implements DataBinder { this.connection = connection; } + @Override + public void pushJson(String json) { + this.json = json; + } + + @Override + public String popJson() { + return json; + } + @Override public StringBuilder append(Object entry) { return bindLog.append(entry); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java index 9763a5667..b85c8e688 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/RsetDataReader.java @@ -20,22 +20,29 @@ import java.util.Calendar; public class RsetDataReader implements DataReader { private static final int bufferSize = 512; - static final int clobBufferSize = 512; - static final int stringInitialSize = 512; private final DataTimeZone dataTimeZone; - private final ResultSet rset; - protected int pos; + private String json; public RsetDataReader(DataTimeZone dataTimeZone, ResultSet rset) { this.dataTimeZone = dataTimeZone; this.rset = rset; } + @Override + public void pushJson(String json) { + this.json = json; + } + + @Override + public String popJson() { + return json; + } + @Override public void close() throws SQLException { rset.close(); 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 5e24412b5..d71cf18d6 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 @@ -56,6 +56,50 @@ class ScalarTypeJsonObjectMapper { GenericObject(TypeJsonManager jsonManager, AnnotatedField field, int dbType, Class rawType) { super(Object.class, jsonManager, field, dbType, DocPropertyType.OBJECT, rawType); } + + @Override + public boolean isJsonMapper() { + return true; + } + + @Override + public String jsonMapper(Object value) { + return formatValue(value); + } + + @Override + public Object read(DataReader reader) throws SQLException { + String json = reader.getString(); + if (json == null || json.isEmpty()) { + return null; + } + // pushJson such that we MD5 and store on EntityBeanIntercept later + reader.pushJson(json); + try { + return objectReader.readValue(json, deserType); + } catch (IOException e) { + throw new TextException("Failed to parse JSON [{}] as " + deserType, json, e); + } + } + + @Override + public void bind(DataBinder binder, Object value) throws SQLException { + // popJson as dirty detection already converted to json string + String rawJson = binder.popJson(); + if (rawJson == null && value != null) { + rawJson = formatValue(value); // not expected, need to check? + } + if (pgType != null) { + binder.setObject(PostgresHelper.asObject(pgType, rawJson)); + } else { + if (value == null) { + // use varchar, otherwise SqlServer/db2 will fail with 'Invalid JDBC data type 5.001.' + binder.setNull(Types.VARCHAR); + } else { + binder.setString(rawJson); + } + } + } } /** @@ -118,10 +162,10 @@ class ScalarTypeJsonObjectMapper { */ private static abstract class Base extends ScalarTypeBase { - private final ObjectWriter objectWriter; - private final ObjectMapper objectReader; - private final JavaType deserType; - private final String pgType; + protected final ObjectWriter objectWriter; + protected final ObjectMapper objectReader; + protected final JavaType deserType; + protected final String pgType; private final DocPropertyType docType; private final TypeJsonManager.DirtyHandler dirtyHandler; diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index 106beb9f2..4bc0194d6 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -74,6 +74,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase { final List sql = LoggedSql.stop(); assertThat(sql).hasSize(1); - assertThat(sql.get(0)).contains("update ebasic_json_list set name=?, bean_list=?, plain_bean=?, version=? where id=?"); + // plain_bean=?, no longer included with MD5 dirty detection + assertThat(sql.get(0)).contains("update ebasic_json_list set name=?, bean_list=?, version=? where id=?"); } } diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java index 28fd78221..f43d6f23c 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java @@ -113,7 +113,8 @@ public class TestDbJson_List extends BaseTestCase { List sql = LoggedSqlCollector.stop(); // we don't update the phone numbers (as they are not dirty) - assertSql(sql.get(0)).contains("update ebasic_json_list set name=?, plain_bean=?, version=? where"); + // plain_bean=?, no longer included with MD5 dirty detection + assertSql(sql.get(0)).contains("update ebasic_json_list set name=?, version=? where"); } public void update_when_dirty() { @@ -126,7 +127,8 @@ public class TestDbJson_List extends BaseTestCase { List sql = LoggedSqlCollector.stop(); // we don't update the phone numbers (as they are not dirty) - assertSql(sql.get(0)).contains("update ebasic_json_list set plain_bean=?, tags=?, version=? where id=? and version=?"); + // plain_bean=? not included using MD5 dirty detection + assertSql(sql.get(0)).contains("update ebasic_json_list set tags=?, version=? where id=? and version=?"); } public void update_when_dirty_flags() { @@ -139,7 +141,8 @@ public class TestDbJson_List extends BaseTestCase { List sql = LoggedSqlCollector.stop(); // we don't update the phone numbers (as they are not dirty) - assertSql(sql.get(0)).contains("update ebasic_json_list set plain_bean=?, flags=?, version=? where id=? and version=?;"); + // plain_bean=? not included with MD5 dirty detection + assertSql(sql.get(0)).contains("update ebasic_json_list set flags=?, version=? where id=? and version=?;"); } public void update_when_dirty_SetListMap() { @@ -154,7 +157,8 @@ public class TestDbJson_List extends BaseTestCase { List sql = LoggedSqlCollector.stop(); // we don't update the phone numbers (as they are not dirty) - assertSql(sql.get(0)).contains("update ebasic_json_list set beans=?, bean_list=?, bean_map=?, plain_bean=?, version=? where id=? and version=?"); + // plain_bean=? not included with MD5 dirty detection + assertSql(sql.get(0)).contains("update ebasic_json_list set beans=?, bean_list=?, bean_map=?, version=? where id=? and version=?"); } @Test diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java b/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java new file mode 100644 index 000000000..f3705aa16 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java @@ -0,0 +1,54 @@ +package org.tests.model.json; + +import io.ebean.annotation.DbJson; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Version; + +@Entity +public class EBasicPlain { + + @Id + long id; + + String attr; + + @DbJson(length = 500) + PlainBean plainBean; + + @Version + long version; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getAttr() { + return attr; + } + + public void setAttr(String attr) { + this.attr = attr; + } + + public PlainBean getPlainBean() { + return plainBean; + } + + public void setPlainBean(PlainBean plainBean) { + this.plainBean = plainBean; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } +} diff --git a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java new file mode 100644 index 000000000..0e3d22aa7 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java @@ -0,0 +1,73 @@ +package org.tests.model.json; + +import io.ebean.DB; +import org.ebeantest.LoggedSqlCollector; +import org.junit.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestJacksonPlainBean { + + @Test + public void insertUpdate() { + + DB.getDefault(); + LoggedSqlCollector.start(); + + PlainBean content = new PlainBean(); + content.setAlong(42); + content.setName("foo"); + + EBasicPlain bean = new EBasicPlain(); + bean.setAttr("attr0"); + bean.setPlainBean(content); + + + DB.save(bean); + expectedSql(0, "insert into ebasic_plain (attr, plain_bean, version) values (?,?,?)"); + + + // inserted plainBean has not been mutated + bean.setAttr("attr1"); + DB.save(bean); + expectedSql(0, "update ebasic_plain set attr=?, version=? where id=? and version=?"); + + + // inserted plainBean has now been mutated + content.setName("notFoo"); + bean.setAttr("attr2"); + DB.save(bean); + expectedSql(0, "update ebasic_plain set attr=?, plain_bean=?, version=? where id=? and version=?"); + + + final EBasicPlain found = DB.find(EBasicPlain.class, bean.getId()); + + // update mutating PlainBean only + final PlainBean plainBean = found.getPlainBean(); + plainBean.setName("mod1"); + DB.save(found); + expectedSql(1, "update ebasic_plain set plain_bean=?, version=? where id=? and version=?"); + + + // update bean, mutate PlainBean only + plainBean.setName("mod2"); + DB.save(found); + expectedSql(0, "update ebasic_plain set plain_bean=?, version=? where id=? and version=?"); + + + // update bean, not mutating PlainBean + found.setAttr("attr3"); + DB.save(found); + expectedSql(LoggedSqlCollector.stop(), 0, "update ebasic_plain set attr=?, version=? where id=? and version=?"); + } + + private void expectedSql(int i, String s) { + assertThat(LoggedSqlCollector.current().get(i)).contains(s); + } + + private void expectedSql(List sql, int i, String s) { + assertThat(sql.get(i)).contains(s); + } +} From 11eed4cfe9cb9118624bd0200691acf6b71d587e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 28 Jul 2021 21:43:57 +1200 Subject: [PATCH 004/120] Add BeanPropertyJsonMapper for JSON dirty detection --- .../server/deploy/BeanProperty.java | 22 ------- .../server/deploy/BeanPropertyJsonMapper.java | 57 +++++++++++++++++++ .../deploy/meta/DeployBeanProperty.java | 3 + .../deploy/meta/DeployBeanPropertyLists.java | 13 ++--- 4 files changed, 64 insertions(+), 31 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index d3c832c85..d9af317d7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -219,7 +219,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { */ @SuppressWarnings("rawtypes") final ScalarType scalarType; - final boolean jsonMapperType; private final DocPropertyOptions docOptions; @@ -333,7 +332,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { this.formula = sqlFormulaSelect != null; this.dbType = deploy.getDbType(); this.scalarType = deploy.getScalarType(); - this.jsonMapperType = (scalarType == null) ? false : scalarType.isJsonMapper(); this.lob = isLobType(dbType); this.propertyType = deploy.getPropertyType(); this.field = deploy.getField(); @@ -428,7 +426,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { this.setter = source.setter; this.dbType = source.getDbType(true); this.scalarType = source.scalarType; - this.jsonMapperType = source.jsonMapperType; this.lob = isLobType(dbType); this.propertyType = source.getPropertyType(); this.field = source.getField(); @@ -632,13 +629,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { Object value = scalarType.read(reader); if (bean != null) { setValue(bean, value); - if (jsonMapperType) { - String json = reader.popJson(); - if (json != null) { - final String hash = Md5.hash(json); - bean._ebean_getIntercept().mutableHash(propertyIndex, hash); - } - } } return value; } catch (TextException e) { @@ -1028,18 +1018,6 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { * This is only used for 'mutable' scalar types like hstore etc. */ boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { - if (jsonMapperType) { - // dirty detection based on md5 hash of json content - final String json = scalarType.jsonMapper(value); - final String newHash = Md5.hash(json); - final String oldHash = ebi.mutableHash(propertyIndex); - if (!Objects.equals(newHash, oldHash)) { - ebi.mutableContent(propertyIndex, json); // so we only convert to json once - ebi.mutableHash(propertyIndex, newHash); // for dirty detection next time - return true; - } - return false; - } return scalarType.isDirty(value); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java new file mode 100644 index 000000000..2d24958b6 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -0,0 +1,57 @@ +package io.ebeaninternal.server.deploy; + +import io.ebean.bean.EntityBean; +import io.ebean.bean.EntityBeanIntercept; +import io.ebean.core.type.DataReader; +import io.ebean.text.TextException; +import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; +import io.ebeaninternal.server.util.Md5; + +import javax.persistence.PersistenceException; +import java.sql.SQLException; +import java.util.Objects; + +public class BeanPropertyJsonMapper extends BeanProperty { + + public BeanPropertyJsonMapper(BeanDescriptor desc, DeployBeanProperty deployProp) { + super(desc, deployProp); + } + + /** + * Return true if the mutable value is considered dirty. + * This is only used for 'mutable' scalar types like hstore etc. + */ + @Override + boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { + // dirty detection based on md5 hash of json content + final String json = scalarType.jsonMapper(value); + final String newHash = Md5.hash(json); + final String oldHash = ebi.mutableHash(propertyIndex); + if (!Objects.equals(newHash, oldHash)) { + ebi.mutableContent(propertyIndex, json); // so we only convert to json once + ebi.mutableHash(propertyIndex, newHash); // for dirty detection next time + return true; + } + return false; + } + + @Override + public Object readSet(DataReader reader, EntityBean bean) throws SQLException { + try { + Object value = scalarType.read(reader); + if (bean != null) { + setValue(bean, value); + String json = reader.popJson(); + if (json != null) { + final String hash = Md5.hash(json); + bean._ebean_getIntercept().mutableHash(propertyIndex, hash); + } + } + return value; + } catch (TextException e) { + throw e; + } catch (Exception e) { + throw new PersistenceException("Error readSet on " + descriptor + "." + name, e); + } + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java index e20c898ce..92ad7f1e9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java @@ -1201,4 +1201,7 @@ public class DeployBeanProperty { return false; } + boolean isJsonMapper() { + return scalarType != null && scalarType.isJsonMapper(); + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java index f6280b260..9843f8e5c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java @@ -1,15 +1,7 @@ package io.ebeaninternal.server.deploy.meta; import io.ebean.bean.EntityBean; -import io.ebeaninternal.server.deploy.BeanDescriptor; -import io.ebeaninternal.server.deploy.BeanDescriptorMap; -import io.ebeaninternal.server.deploy.BeanProperty; -import io.ebeaninternal.server.deploy.BeanPropertyAssocMany; -import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; -import io.ebeaninternal.server.deploy.BeanPropertyIdClass; -import io.ebeaninternal.server.deploy.BeanPropertyOrderColumn; -import io.ebeaninternal.server.deploy.BeanPropertySimpleCollection; -import io.ebeaninternal.server.deploy.InheritInfo; +import io.ebeaninternal.server.deploy.*; import io.ebeaninternal.server.deploy.generatedproperty.GeneratedProperty; import io.ebeaninternal.server.properties.BeanPropertySetter; import io.ebeaninternal.server.type.ScalarTypeString; @@ -490,6 +482,9 @@ public class DeployBeanPropertyLists { return new BeanPropertyAssocMany(desc, (DeployBeanPropertyAssocMany) deployProp); } + if (deployProp.isJsonMapper()) { + return new BeanPropertyJsonMapper(desc, deployProp); + } return new BeanProperty(desc, deployProp); } From 49b86d07d3bb5bdd13b97a180ab92038011655fc Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 28 Jul 2021 22:48:29 +1200 Subject: [PATCH 005/120] Modify SqlBeanLoad to use readSet() Note that we don't need to use readSetIntercept() now as there is no property change listener support --- .../server/deploy/BeanProperty.java | 18 +++++--------- .../server/query/SqlBeanLoad.java | 24 ++----------------- .../java/io/ebean/EbeanServer_refresh.java | 5 +++- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index d9af317d7..4306ed97d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -33,7 +33,6 @@ import io.ebeaninternal.server.query.STreeProperty; import io.ebeaninternal.server.query.SqlBeanLoad; import io.ebeaninternal.server.query.SqlJoinType; import io.ebeaninternal.server.type.*; -import io.ebeaninternal.server.util.Md5; import io.ebeaninternal.util.ValueUtil; import io.ebeanservice.docstore.api.mapping.DocMappingBuilder; import io.ebeanservice.docstore.api.mapping.DocPropertyMapping; @@ -52,7 +51,6 @@ import java.sql.SQLException; import java.sql.Types; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; /** @@ -643,13 +641,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { } public Object readSet(DbReadContext ctx, EntityBean bean) throws SQLException { - try { - return readSet(ctx.getDataReader(), bean); - } catch (TextException e) { - bean._ebean_getIntercept().setLoadError(propertyIndex, e); - ctx.handleLoadError(getFullBeanName(), e); - return getValue(bean); - } + return readSet(ctx.getDataReader(), bean); } @SuppressWarnings("unchecked") @@ -908,7 +900,8 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { /** * Return the name of the property. */ - @Override @Nonnull + @Override + @Nonnull public String getName() { return name; } @@ -1280,7 +1273,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { @Override public Object localEncrypt(Object value) { - return ((LocalEncryptedType)scalarType).localEncrypt(value); + return ((LocalEncryptedType) scalarType).localEncrypt(value); } /** @@ -1393,7 +1386,8 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { /** * Return the property type. */ - @Override @Nonnull + @Override + @Nonnull public Class getPropertyType() { return propertyType; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java index 20d1dfddb..83c7b2936 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java @@ -18,10 +18,8 @@ public class SqlBeanLoad { private final DbReadContext ctx; private final EntityBean bean; private final EntityBeanIntercept ebi; - private final Class type; private final boolean lazyLoading; - private final boolean refreshLoading; private final boolean rawSql; SqlBeanLoad(DbReadContext ctx, Class type, EntityBean bean, Mode queryMode) { @@ -29,7 +27,6 @@ public class SqlBeanLoad { this.rawSql = ctx.isRawSql(); this.type = type; this.lazyLoading = queryMode == Mode.LAZYLOAD_BEAN; - this.refreshLoading = queryMode == Mode.REFRESH_BEAN; this.bean = bean; this.ebi = bean == null ? null : bean._ebean_getIntercept(); } @@ -49,35 +46,22 @@ public class SqlBeanLoad { } public Object load(BeanProperty prop) { - if (!rawSql && !prop.isLoadProperty(ctx.isDraftQuery())) { return null; } - if ((bean == null) || (lazyLoading && ebi.isLoadedProperty(prop.getPropertyIndex())) || (type != null && !prop.isAssignableFrom(type))) { - // ignore this property // ... null: bean already in persistence context // ... lazyLoading: partial bean that is lazy loading // ... type: inheritance and not assignable to this instance - prop.loadIgnore(ctx); return null; } - try { - if (!refreshLoading) { - return prop.readSet(ctx, bean); - } - // TODO: maybe create prop.readSetIntercept() and move this - Object dbVal = prop.read(ctx); - prop.setValueIntercept(bean, dbVal); - return dbVal; - + return prop.readSet(ctx, bean); } catch (Exception e) { - // TODO: maybe move this into prop.readSetIntercept() bean._ebean_getIntercept().setLoadError(prop.getPropertyIndex(), e); ctx.handleLoadError(prop.getFullBeanName(), e); return prop.getValue(bean); @@ -88,10 +72,6 @@ public class SqlBeanLoad { * Load the given value into the property. */ public void load(BeanProperty target, Object dbVal) { - if (!refreshLoading) { - target.setValue(bean, dbVal); - } else { - target.setValueIntercept(bean, dbVal); - } + target.setValue(bean, dbVal); } } diff --git a/ebean-core/src/test/java/io/ebean/EbeanServer_refresh.java b/ebean-core/src/test/java/io/ebean/EbeanServer_refresh.java index 1e1900a13..66af5d164 100644 --- a/ebean-core/src/test/java/io/ebean/EbeanServer_refresh.java +++ b/ebean-core/src/test/java/io/ebean/EbeanServer_refresh.java @@ -11,7 +11,7 @@ import java.util.HashMap; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; public class EbeanServer_refresh { @@ -39,8 +39,11 @@ public class EbeanServer_refresh { assertEquals(rows, 1); + basic.setName("modify"); + assertTrue(DB.getBeanState(basic).isDirty()); server.refresh(basic); assertEquals(basic.getStatus(), EBasic.Status.ACTIVE); + assertFalse(DB.getBeanState(basic).isDirty()); } @Test From 5e595ec5f875690d7c6e198871fc8f726f234ef7 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Wed, 28 Jul 2021 14:54:56 +0200 Subject: [PATCH 006/120] Proof of concept to support also bean change detection / changelog on mutable properties --- .../io/ebean/bean/EntityBeanIntercept.java | 29 ++++++-- .../main/java/io/ebean/bean/MutableJson.java | 12 ++++ .../java/io/ebean/core/type/ScalarType.java | 5 ++ .../server/deploy/BeanPropertyJsonMapper.java | 13 ++-- .../dmlbind/BindablePropertyJsonInsert.java | 3 +- .../type/ScalarTypeJsonObjectMapper.java | 64 +++++++++++++++++ .../org/tests/json/TestDbJson_Jackson3.java | 70 ++++++++++++++++++- 7 files changed, 180 insertions(+), 16 deletions(-) create mode 100644 ebean-api/src/main/java/io/ebean/bean/MutableJson.java diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java index 59a2450bd..2ea4afbb5 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -94,7 +94,7 @@ public final class EntityBeanIntercept implements Serializable { /** * Holds MD5 hash of json loaded jackson beans. */ - private String[] mutableHash; + private MutableJson[] mutableHash; /** * Holds json content determined at point of dirty check. @@ -381,7 +381,11 @@ public final class EntityBeanIntercept implements Serializable { this.origValues = null; for (int i = 0; i < flags.length; i++) { flags[i] &= ~(FLAG_CHANGED_PROP + FLAG_ORIG_VALUE_SET); + if (mutableHash != null && mutableHash[i] != null) { + mutableHash[i].update(owner._ebean_getField(i)); + } } + this.dirty = false; } @@ -649,7 +653,7 @@ public final class EntityBeanIntercept implements Serializable { public void addDirtyPropertyNames(Set props, String prefix) { int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if ((flags[i] & FLAG_CHANGED_PROP) != 0) { + if ((flags[i] & FLAG_CHANGED_PROP) != 0 || isChangedByHash(i)) { // the property has been changed on this bean props.add((prefix == null ? getProperty(i) : prefix + getProperty(i))); } else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) { @@ -667,7 +671,7 @@ public final class EntityBeanIntercept implements Serializable { String[] names = owner._ebean_getPropertyNames(); int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if ((flags[i] & FLAG_CHANGED_PROP) != 0) { + if ((flags[i] & FLAG_CHANGED_PROP) != 0 || isChangedByHash(i)) { if (propertyNames.contains(names[i])) { return true; } @@ -695,7 +699,12 @@ public final class EntityBeanIntercept implements Serializable { public void addDirtyPropertyValues(Map dirtyValues, String prefix) { int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if ((flags[i] & FLAG_CHANGED_PROP) != 0) { + if (isChangedByHash(i)) { + String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i)); + Object newVal = owner._ebean_getField(i); + Object oldVal = mutableHash[i].get(); + dirtyValues.put(propName, new ValuePair(newVal, oldVal)); + } else if ((flags[i] & FLAG_CHANGED_PROP) != 0) { // the property has been changed on this bean String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i)); Object newVal = owner._ebean_getField(i); @@ -1150,13 +1159,19 @@ public final class EntityBeanIntercept implements Serializable { return ret; } - public String mutableHash(int propertyIndex) { + private boolean isChangedByHash(int propertyIndex) { + return mutableHash != null + && mutableHash[propertyIndex] != null + && !mutableHash[propertyIndex].isEqualToObject(owner._ebean_getField(propertyIndex)); + } + + public MutableJson mutableHash(int propertyIndex) { return mutableHash == null ? null : mutableHash[propertyIndex]; } - public void mutableHash(int propertyIndex, String content) { + public void mutableHash(int propertyIndex, MutableJson content) { if (mutableHash == null) { - mutableHash = new String[flags.length]; + mutableHash = new MutableJson[flags.length]; } mutableHash[propertyIndex] = content; } diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableJson.java b/ebean-api/src/main/java/io/ebean/bean/MutableJson.java new file mode 100644 index 000000000..5989465e2 --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/bean/MutableJson.java @@ -0,0 +1,12 @@ +package io.ebean.bean; + +public interface MutableJson { + + boolean isEqualToObject(Object obj); + + boolean isEqualToJson(String json); + + Object get(); + + void update(Object obj); +} diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java index 831664991..b9f7f168c 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java @@ -2,6 +2,8 @@ package io.ebean.core.type; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; + +import io.ebean.bean.MutableJson; import io.ebean.text.StringFormatter; import io.ebean.text.StringParser; @@ -42,6 +44,9 @@ public interface ScalarType extends StringParser, StringFormatter, ScalarData throw new UnsupportedOperationException(); } + default MutableJson jsonMutable(String json) { + throw new UnsupportedOperationException(); + } /** * Return true if this is a binary type and can not support parse() and format() from/to string. * This allows Ebean to optimise marshalling types to string. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index 2d24958b6..de5d148b5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -2,6 +2,7 @@ package io.ebeaninternal.server.deploy; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; +import io.ebean.bean.MutableJson; import io.ebean.core.type.DataReader; import io.ebean.text.TextException; import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; @@ -25,11 +26,11 @@ public class BeanPropertyJsonMapper extends BeanProperty { boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { // dirty detection based on md5 hash of json content final String json = scalarType.jsonMapper(value); - final String newHash = Md5.hash(json); - final String oldHash = ebi.mutableHash(propertyIndex); - if (!Objects.equals(newHash, oldHash)) { + final MutableJson oldHash = ebi.mutableHash(propertyIndex); + if (oldHash == null || !oldHash.isEqualToJson(json)) { ebi.mutableContent(propertyIndex, json); // so we only convert to json once - ebi.mutableHash(propertyIndex, newHash); // for dirty detection next time + //ebi.mutableHash(propertyIndex, scalarType.jsonMutable(json)); // for dirty detection next time + //must be done AFTER persistControllers are called. return true; } return false; @@ -43,8 +44,8 @@ public class BeanPropertyJsonMapper extends BeanProperty { setValue(bean, value); String json = reader.popJson(); if (json != null) { - final String hash = Md5.hash(json); - bean._ebean_getIntercept().mutableHash(propertyIndex, hash); + final String hash = scalarType.format(value); + bean._ebean_getIntercept().mutableHash(propertyIndex, scalarType.jsonMutable(hash)); } } return value; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java index 0a93452f1..24cf050e3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java @@ -32,8 +32,7 @@ class BindablePropertyJsonInsert extends BindableProperty { } else { // on insert store MD5 hash and push json final String json = prop.format(value); - final String hash = Md5.hash(json); - bean._ebean_getIntercept().mutableHash(propertyIndex, hash); + bean._ebean_getIntercept().mutableHash(propertyIndex, prop.getScalarType().jsonMutable(json)); request.pushJson(json); request.bind(value, prop); } 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 d71cf18d6..5b44b63e4 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 @@ -7,6 +7,8 @@ import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.introspect.AnnotatedField; + +import io.ebean.bean.MutableJson; import io.ebean.core.type.DataBinder; import io.ebean.core.type.DataReader; import io.ebean.core.type.DocPropertyType; @@ -15,6 +17,7 @@ import io.ebean.text.TextException; import io.ebeaninternal.json.ModifyAwareList; import io.ebeaninternal.json.ModifyAwareMap; import io.ebeaninternal.json.ModifyAwareSet; +import io.ebeaninternal.server.util.Md5; import javax.persistence.PersistenceException; import java.io.DataInput; @@ -24,6 +27,7 @@ import java.sql.SQLException; import java.sql.Types; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; /** @@ -66,6 +70,66 @@ class ScalarTypeJsonObjectMapper { public String jsonMapper(Object value) { return formatValue(value); } + + private class Md5MutableJson implements MutableJson { + + private String md5; + Md5MutableJson(String json) { + md5 = Md5.hash(json); + } + @Override + public boolean isEqualToObject(Object obj) { + return true; // we cannot determine differences... + } + + @Override + public boolean isEqualToJson(String json) { + return Md5.hash(json).equals(md5); + } + + @Override + public Object get() { + return null; // cannot create object from json + } + @Override + public void update(Object obj) { + md5 = Md5.hash(format(obj)); + } + } + + private class PlainMutableJson implements MutableJson { + + private String originalJson; + PlainMutableJson(String json) { + originalJson = json; + } + @Override + public boolean isEqualToObject(Object obj) { + return isEqualToJson(format(obj)); + } + + @Override + public boolean isEqualToJson(String json) { + return Objects.equals(originalJson, json); + } + + @Override + public Object get() { + return parse(originalJson); + } + @Override + public void update(Object obj) { + originalJson = format(obj); + } + } + @Override + public MutableJson jsonMutable(String originalJson) { + if (false) { + return new Md5MutableJson(originalJson); + } else { + return new PlainMutableJson(originalJson); + } + } @Override public Object read(DataReader reader) throws SQLException { diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index 4bc0194d6..4d31f8a56 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -1,7 +1,11 @@ package org.tests.json; import io.ebean.BaseTestCase; +import io.ebean.BeanState; import io.ebean.DB; +import io.ebean.ValuePair; +import io.ebean.event.BeanPersistAdapter; +import io.ebean.event.BeanPersistRequest; import io.ebeantest.LoggedSql; import org.junit.Test; import org.tests.model.json.EBasicJsonJackson3; @@ -11,11 +15,33 @@ import org.tests.model.json.PlainBeanDirtyAware; import java.util.Arrays; import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; public class TestDbJson_Jackson3 extends BaseTestCase { + public static class EBasicJsonListPersistController extends BeanPersistAdapter { + + private static Map updatedValues; + + @Override + public boolean isRegisterFor(Class cls) { + return EBasicJsonList.class.isAssignableFrom(cls); + } + + @Override + public boolean preInsert(BeanPersistRequest request) { + updatedValues = request.getUpdatedValues(); + return true; + } + + @Override + public boolean preUpdate(BeanPersistRequest request) { + updatedValues = request.getUpdatedValues(); + return true; + } + } @Test public void updateIncludesJsonColumn_when_explicit_isMarkedDirty() { @@ -69,12 +95,54 @@ public class TestDbJson_Jackson3 extends BaseTestCase { found.setName("p1-mod"); found.setBeanList(null); + BeanState state = DB.getBeanState(found); + assertThat(state.getChangedProps()).containsExactlyInAnyOrder("name", "beanList"); + + ValuePair pair = state.getDirtyValues().get("name"); + assertThat(pair.getNewValue()).isEqualTo("p1-mod"); + assertThat(pair.getOldValue()).isEqualTo("p1"); + + pair = state.getDirtyValues().get("beanList"); + assertThat(pair.getNewValue()).isEqualTo(null); + assertThat((List)pair.getOldValue()).hasSize(1) + .extracting(PlainBean::getName).containsExactly("a"); + + LoggedSql.start(); DB.save(found); - final List sql = LoggedSql.stop(); + List sql = LoggedSql.stop(); assertThat(sql).hasSize(1); // plain_bean=?, no longer included with MD5 dirty detection assertThat(sql.get(0)).contains("update ebasic_json_list set name=?, bean_list=?, version=? where id=?"); + + assertThat(EBasicJsonListPersistController.updatedValues.entrySet()) + .extracting(Map.Entry::toString) + .containsExactlyInAnyOrder("beanList=null,[name:a]","name=p1-mod,p1","version=2,1"); + + + found.getPlainBean().setName("b"); + + // CHECKME: How do we get these checks to work? + // assertThat(DB.getBeanState(found).isDirty()).isTrue(); + + state = DB.getBeanState(found); + assertThat(state.getChangedProps()).containsExactlyInAnyOrder("plainBean"); + pair = state.getDirtyValues().get("plainBean"); + assertThat(pair.getNewValue()).hasToString("name:b"); + assertThat(pair.getOldValue()).hasToString("name:a"); + + + LoggedSql.start(); + DB.save(found); + + sql = LoggedSql.stop(); + assertThat(sql).hasSize(1); + // plain_bean=?, no longer included with MD5 dirty detection + assertThat(sql.get(0)).contains("update ebasic_json_list set plain_bean=?, version=? where id=?"); + + assertThat(EBasicJsonListPersistController.updatedValues.entrySet()) + .extracting(Map.Entry::toString) + .containsExactlyInAnyOrder("plainBean=name:b,name:a", "version=3,2"); } } From b497b8635b8c3fcbc0ee08028aec2b67be2148e0 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Wed, 28 Jul 2021 17:22:29 +0200 Subject: [PATCH 007/120] some refactor and tidying --- .../io/ebean/bean/EntityBeanIntercept.java | 71 +++++++---- .../main/java/io/ebean/bean/MutableHash.java | 16 +++ .../main/java/io/ebean/bean/MutableJson.java | 12 -- .../java/io/ebean/core/type/ScalarType.java | 5 +- .../server/deploy/BeanProperty.java | 8 ++ .../server/deploy/BeanPropertyJsonMapper.java | 12 +- .../dmlbind/BindablePropertyJsonInsert.java | 7 +- .../dmlbind/BindablePropertyJsonUpdate.java | 5 +- .../ebeaninternal/server/type/DataBind.java | 5 +- .../type/ScalarTypeJsonObjectMapper.java | 111 +++++++++--------- .../org/tests/json/TestDbJson_Jackson3.java | 28 ++++- .../tests/model/json/EBasicJsonJackson3.java | 11 ++ 12 files changed, 184 insertions(+), 107 deletions(-) create mode 100644 ebean-api/src/main/java/io/ebean/bean/MutableHash.java delete mode 100644 ebean-api/src/main/java/io/ebean/bean/MutableJson.java diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java index 2ea4afbb5..37446a1b3 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -51,6 +51,11 @@ public final class EntityBeanIntercept implements Serializable { */ private static final byte FLAG_ORIG_VALUE_SET = 8; + /** + * Flags indicating if the mutable hash is set. + */ + private static final byte FLAG_MUTABLE_HASH_SET = 16; + private transient final ReentrantLock lock = new ReentrantLock(); private transient NodeUsageCollector nodeUsageCollector; private transient PersistenceContext persistenceContext; @@ -94,7 +99,7 @@ public final class EntityBeanIntercept implements Serializable { /** * Holds MD5 hash of json loaded jackson beans. */ - private MutableJson[] mutableHash; + private MutableHash[] mutableHash; /** * Holds json content determined at point of dirty check. @@ -239,6 +244,17 @@ public final class EntityBeanIntercept implements Serializable { * if any embedded beans are either new or dirty (and hence need saving). */ public boolean isDirty() { + if (dirty) { + return true; + } + if (mutableHash != null) { + for (int i = 0; i < mutableHash.length; i++) { + if (mutableHash[i] != null && !mutableHash[i].isEqualToObject(owner._ebean_getField(i))) { + dirty = true; + break; + } + } + } return dirty; } @@ -379,13 +395,10 @@ public final class EntityBeanIntercept implements Serializable { this.owner._ebean_setEmbeddedLoaded(); this.lazyLoadProperty = -1; this.origValues = null; + this.mutableContent = null; for (int i = 0; i < flags.length; i++) { - flags[i] &= ~(FLAG_CHANGED_PROP + FLAG_ORIG_VALUE_SET); - if (mutableHash != null && mutableHash[i] != null) { - mutableHash[i].update(owner._ebean_getField(i)); - } + flags[i] &= ~(FLAG_CHANGED_PROP | FLAG_ORIG_VALUE_SET); } - this.dirty = false; } @@ -653,14 +666,14 @@ public final class EntityBeanIntercept implements Serializable { public void addDirtyPropertyNames(Set props, String prefix) { int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if ((flags[i] & FLAG_CHANGED_PROP) != 0 || isChangedByHash(i)) { + if (isChangedProp(i)) { // the property has been changed on this bean props.add((prefix == null ? getProperty(i) : prefix + getProperty(i))); } else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) { // an embedded property has been changed - recurse EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i); embeddedBean._ebean_getIntercept().addDirtyPropertyNames(props, getProperty(i) + "."); - } + } } } @@ -671,7 +684,7 @@ public final class EntityBeanIntercept implements Serializable { String[] names = owner._ebean_getPropertyNames(); int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if ((flags[i] & FLAG_CHANGED_PROP) != 0 || isChangedByHash(i)) { + if (isChangedProp(i)) { if (propertyNames.contains(names[i])) { return true; } @@ -699,16 +712,17 @@ public final class EntityBeanIntercept implements Serializable { public void addDirtyPropertyValues(Map dirtyValues, String prefix) { int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if (isChangedByHash(i)) { - String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i)); - Object newVal = owner._ebean_getField(i); - Object oldVal = mutableHash[i].get(); - dirtyValues.put(propName, new ValuePair(newVal, oldVal)); - } else if ((flags[i] & FLAG_CHANGED_PROP) != 0) { + + if (isChangedProp(i)) { // the property has been changed on this bean String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i)); Object newVal = owner._ebean_getField(i); Object oldVal = getOrigValue(i); + if ((flags[i] & (FLAG_ORIG_VALUE_SET | FLAG_MUTABLE_HASH_SET)) == FLAG_MUTABLE_HASH_SET) { + // mutable hash set, but not ORIG_VALUE + oldVal = mutableHash[i].get(); + setOriginalValue(i, oldVal); + } if (notEqual(oldVal, newVal)) { dirtyValues.put(propName, new ValuePair(newVal, oldVal)); } @@ -726,7 +740,7 @@ public final class EntityBeanIntercept implements Serializable { public void addDirtyPropertyValues(BeanDiffVisitor visitor) { int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if ((flags[i] & FLAG_CHANGED_PROP) != 0) { + if (isChangedProp(i)) { // the property has been changed on this bean Object newVal = owner._ebean_getField(i); Object oldVal = getOrigValue(i); @@ -761,7 +775,7 @@ public final class EntityBeanIntercept implements Serializable { } int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if ((flags[i] & FLAG_CHANGED_PROP) != 0) { + if ((flags[i] & FLAG_CHANGED_PROP) != 0) { // we do not check against mutablecontent here. sb.append(i).append(','); } else if ((flags[i] & FLAG_EMBEDDED_DIRTY) != 0) { // an embedded property has been changed - recurse @@ -1159,20 +1173,29 @@ public final class EntityBeanIntercept implements Serializable { return ret; } - private boolean isChangedByHash(int propertyIndex) { - return mutableHash != null - && mutableHash[propertyIndex] != null - && !mutableHash[propertyIndex].isEqualToObject(owner._ebean_getField(propertyIndex)); + private boolean isChangedProp(int i) { + if ((flags[i] & FLAG_CHANGED_PROP) != 0) { + return true; + } else if (mutableHash == null || mutableHash[i] == null + || mutableHash[i].isEqualToObject(owner._ebean_getField(i))) { + return false; + } else { + // mark for change + flags[i] |= FLAG_CHANGED_PROP; + dirty = true; // this makes the bean automatically dirty! + return true; + } } - public MutableJson mutableHash(int propertyIndex) { + public MutableHash mutableHash(int propertyIndex) { return mutableHash == null ? null : mutableHash[propertyIndex]; } - public void mutableHash(int propertyIndex, MutableJson content) { + public void mutableHash(int propertyIndex, MutableHash content) { if (mutableHash == null) { - mutableHash = new MutableJson[flags.length]; + mutableHash = new MutableHash[flags.length]; } + flags[propertyIndex] |= FLAG_MUTABLE_HASH_SET; mutableHash[propertyIndex] = content; } diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableHash.java b/ebean-api/src/main/java/io/ebean/bean/MutableHash.java new file mode 100644 index 000000000..09c8761af --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/bean/MutableHash.java @@ -0,0 +1,16 @@ +package io.ebean.bean; + + +public interface MutableHash { + + boolean isEqualToJson(String json); + + default boolean isEqualToObject(Object obj) { + return true; + } + + default Object get() { + return null; + } +} + \ No newline at end of file diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableJson.java b/ebean-api/src/main/java/io/ebean/bean/MutableJson.java deleted file mode 100644 index 5989465e2..000000000 --- a/ebean-api/src/main/java/io/ebean/bean/MutableJson.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.ebean.bean; - -public interface MutableJson { - - boolean isEqualToObject(Object obj); - - boolean isEqualToJson(String json); - - Object get(); - - void update(Object obj); -} diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java index b9f7f168c..55c8ad9bd 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java @@ -3,7 +3,7 @@ package io.ebean.core.type; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; -import io.ebean.bean.MutableJson; +import io.ebean.bean.MutableHash; import io.ebean.text.StringFormatter; import io.ebean.text.StringParser; @@ -44,9 +44,10 @@ public interface ScalarType extends StringParser, StringFormatter, ScalarData throw new UnsupportedOperationException(); } - default MutableJson jsonMutable(String json) { + default MutableHash createMutableHash(String json) { throw new UnsupportedOperationException(); } + /** * Return true if this is a binary type and can not support parse() and format() from/to string. * This allows Ebean to optimise marshalling types to string. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index 4306ed97d..99ef307a7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonToken; import io.ebean.ValuePair; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; +import io.ebean.bean.MutableHash; import io.ebean.bean.PersistenceContext; import io.ebean.config.EncryptKey; import io.ebean.config.dbplatform.DbEncryptFunction; @@ -818,6 +819,13 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { public Object parse(String value) { return scalarType.parse(value); } + + /** + * creates a mutableHash for the given JSON value. + */ + public MutableHash createMutableHash(String json) { + return scalarType.createMutableHash(json); + } /** * Read the value for this property from L2 cache entry and set it to the bean. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index de5d148b5..204b9aac5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -2,15 +2,13 @@ package io.ebeaninternal.server.deploy; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; -import io.ebean.bean.MutableJson; +import io.ebean.bean.MutableHash; import io.ebean.core.type.DataReader; import io.ebean.text.TextException; import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; -import io.ebeaninternal.server.util.Md5; import javax.persistence.PersistenceException; import java.sql.SQLException; -import java.util.Objects; public class BeanPropertyJsonMapper extends BeanProperty { @@ -26,11 +24,9 @@ public class BeanPropertyJsonMapper extends BeanProperty { boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { // dirty detection based on md5 hash of json content final String json = scalarType.jsonMapper(value); - final MutableJson oldHash = ebi.mutableHash(propertyIndex); + final MutableHash oldHash = ebi.mutableHash(propertyIndex); if (oldHash == null || !oldHash.isEqualToJson(json)) { ebi.mutableContent(propertyIndex, json); // so we only convert to json once - //ebi.mutableHash(propertyIndex, scalarType.jsonMutable(json)); // for dirty detection next time - //must be done AFTER persistControllers are called. return true; } return false; @@ -44,8 +40,8 @@ public class BeanPropertyJsonMapper extends BeanProperty { setValue(bean, value); String json = reader.popJson(); if (json != null) { - final String hash = scalarType.format(value); - bean._ebean_getIntercept().mutableHash(propertyIndex, scalarType.jsonMutable(hash)); + final MutableHash hash = scalarType.createMutableHash(json); + bean._ebean_getIntercept().mutableHash(propertyIndex, hash); } } return value; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java index 24cf050e3..e9de67a52 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java @@ -1,8 +1,8 @@ package io.ebeaninternal.server.persist.dmlbind; import io.ebean.bean.EntityBean; +import io.ebean.bean.MutableHash; import io.ebeaninternal.server.deploy.BeanProperty; -import io.ebeaninternal.server.util.Md5; import java.sql.SQLException; @@ -30,9 +30,10 @@ class BindablePropertyJsonInsert extends BindableProperty { if (value == null) { request.bind(null, prop); } else { - // on insert store MD5 hash and push json + // on insert store hash and push json final String json = prop.format(value); - bean._ebean_getIntercept().mutableHash(propertyIndex, prop.getScalarType().jsonMutable(json)); + final MutableHash hash = prop.createMutableHash(json); + bean._ebean_getIntercept().mutableHash(propertyIndex, hash); request.pushJson(json); request.bind(value, prop); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java index 3418369f5..ab281cf01 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.persist.dmlbind; import io.ebean.bean.EntityBean; +import io.ebean.bean.MutableHash; import io.ebeaninternal.server.deploy.BeanProperty; import java.sql.SQLException; @@ -25,8 +26,10 @@ class BindablePropertyJsonUpdate extends BindableProperty { if (bean == null) { request.bind(null, prop); } else { - // on update push json + // on update store hash and push json final String json = bean._ebean_getIntercept().mutableContent(propertyIndex); + final MutableHash hash = prop.createMutableHash(json); + bean._ebean_getIntercept().mutableHash(propertyIndex, hash); request.pushJson(json); final Object value = prop.getValue(bean); request.bind(value, prop); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java index 489046405..a1a9ec8cf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java @@ -46,12 +46,15 @@ public class DataBind implements DataBinder { @Override public void pushJson(String json) { + assert this.json == null; // we can only push one value this.json = json; } @Override public String popJson() { - return json; + String ret = json; + json = null; + return ret; } @Override 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 5b44b63e4..0012c4cd6 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 @@ -8,7 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.introspect.AnnotatedField; -import io.ebean.bean.MutableJson; +import io.ebean.bean.MutableHash; import io.ebean.core.type.DataBinder; import io.ebean.core.type.DataReader; import io.ebean.core.type.DocPropertyType; @@ -51,7 +51,59 @@ class ScalarTypeJsonObjectMapper { } return new GenericObject(jsonManager, field, dbType, type); } + + private static class Md5MutableHash implements MutableHash { + private final String md5; + + Md5MutableHash(String json) { + md5 = Md5.hash(json); + } + + @Override + public boolean isEqualToObject(Object obj) { + return true; // we cannot determine differences... + } + + @Override + public boolean isEqualToJson(String json) { + return Md5.hash(json).equals(md5); + } + + @Override + public Object get() { + return null; // cannot create object from json + } + + } + + private static class JsonMutableHash implements MutableHash { + + private final String originalJson; + private ScalarType parent; + + JsonMutableHash(ScalarType parent, String json) { + this.parent = parent; + originalJson = json; + } + + @Override + public boolean isEqualToObject(Object obj) { + return isEqualToJson(parent.format(obj)); + } + + @Override + public boolean isEqualToJson(String json) { + return Objects.equals(originalJson, json); + } + + @Override + public Object get() { + return parent.parse(originalJson); + } + + } + /** * Maps any type (Object) using Jackson ObjectMapper. */ @@ -71,63 +123,16 @@ class ScalarTypeJsonObjectMapper { return formatValue(value); } - private class Md5MutableJson implements MutableJson { - private String md5; - Md5MutableJson(String json) { - md5 = Md5.hash(json); - } - @Override - public boolean isEqualToObject(Object obj) { - return true; // we cannot determine differences... - } - @Override - public boolean isEqualToJson(String json) { - return Md5.hash(json).equals(md5); - } - @Override - public Object get() { - return null; // cannot create object from json - } - @Override - public void update(Object obj) { - md5 = Md5.hash(format(obj)); - } - } - - private class PlainMutableJson implements MutableJson { - - private String originalJson; - PlainMutableJson(String json) { - originalJson = json; - } - @Override - public boolean isEqualToObject(Object obj) { - return isEqualToJson(format(obj)); - } - - @Override - public boolean isEqualToJson(String json) { - return Objects.equals(originalJson, json); - } - - @Override - public Object get() { - return parse(originalJson); - } - @Override - public void update(Object obj) { - originalJson = format(obj); - } - } + @Override - public MutableJson jsonMutable(String originalJson) { - if (false) { - return new Md5MutableJson(originalJson); + public MutableHash createMutableHash(String json) { + if (false) { // TODO should we make that configurable? + return new Md5MutableHash(json); } else { - return new PlainMutableJson(originalJson); + return new JsonMutableHash(this, json); } } diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index 4d31f8a56..8e399d3df 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -50,6 +50,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase { EBasicJsonJackson3 bean = new EBasicJsonJackson3(); bean.setName("b1"); bean.setPlainValue(contentBean); + bean.setPlainValue2(contentBean); bean.save(); @@ -121,10 +122,11 @@ public class TestDbJson_Jackson3 extends BaseTestCase { .containsExactlyInAnyOrder("beanList=null,[name:a]","name=p1-mod,p1","version=2,1"); - found.getPlainBean().setName("b"); + assertThat(DB.getBeanState(found).isDirty()).isFalse(); - // CHECKME: How do we get these checks to work? - // assertThat(DB.getBeanState(found).isDirty()).isTrue(); + found.getPlainBean().setName("b"); + + assertThat(DB.getBeanState(found).isDirty()).isTrue(); state = DB.getBeanState(found); assertThat(state.getChangedProps()).containsExactlyInAnyOrder("plainBean"); @@ -145,4 +147,24 @@ public class TestDbJson_Jackson3 extends BaseTestCase { .extracting(Map.Entry::toString) .containsExactlyInAnyOrder("plainBean=name:b,name:a", "version=3,2"); } + + @Test + public void updateIncludesJsonColumn_when_list_loadedAndNotDirtyAware() { + + PlainBean contentBean = new PlainBean("a", 42); + EBasicJsonList bean = new EBasicJsonList(); + bean.setName("p1"); + bean.setPlainBean(contentBean); + bean.setBeanList(Arrays.asList(contentBean)); + + DB.save(bean); + final EBasicJsonList found = DB.find(EBasicJsonList.class, bean.getId()); + found.getBeanList().get(0).setName("p1-mod"); + + BeanState state = DB.getBeanState(found); + assertThat(state.getChangedProps()).containsExactlyInAnyOrder("beanList"); + // this test fails, because we have a OmList instead of a GenericObject + // TODO: Can/Should we enhance the @DbJson/@DbJsonB annotations with a property "dirtyDetection" + + } } diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonJackson3.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonJackson3.java index 3d942d58b..45375b516 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonJackson3.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonJackson3.java @@ -18,6 +18,9 @@ public class EBasicJsonJackson3 extends Model { @DbJson(length = 500) PlainBeanDirtyAware plainValue; + @DbJson(length = 500) + PlainBeanDirtyAware plainValue2; + @Version long version; @@ -45,6 +48,14 @@ public class EBasicJsonJackson3 extends Model { this.plainValue = plainValue; } + public PlainBeanDirtyAware getPlainValue2() { + return plainValue2; + } + + public void setPlainValue2(PlainBeanDirtyAware plainValue2) { + this.plainValue2 = plainValue2; + } + public long getVersion() { return version; } From eb70c7e19675c1fd68b23fdd9e5a24f40dd9a01d Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Wed, 28 Jul 2021 17:36:53 +0200 Subject: [PATCH 008/120] some javadoc and refactored getOrigValue --- .../java/io/ebean/bean/EntityBeanIntercept.java | 9 ++++----- .../src/main/java/io/ebean/bean/MutableHash.java | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java index 37446a1b3..e686464e2 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -470,6 +470,10 @@ public final class EntityBeanIntercept implements Serializable { * Return the original value that was changed via an update. */ public Object getOrigValue(int propertyIndex) { + if ((flags[propertyIndex] & (FLAG_ORIG_VALUE_SET | FLAG_MUTABLE_HASH_SET)) == FLAG_MUTABLE_HASH_SET) { + // mutable hash set, but not ORIG_VALUE + setOriginalValue(propertyIndex, mutableHash[propertyIndex].get()); + } if (origValues == null) { return null; } @@ -718,11 +722,6 @@ public final class EntityBeanIntercept implements Serializable { String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i)); Object newVal = owner._ebean_getField(i); Object oldVal = getOrigValue(i); - if ((flags[i] & (FLAG_ORIG_VALUE_SET | FLAG_MUTABLE_HASH_SET)) == FLAG_MUTABLE_HASH_SET) { - // mutable hash set, but not ORIG_VALUE - oldVal = mutableHash[i].get(); - setOriginalValue(i, oldVal); - } if (notEqual(oldVal, newVal)) { dirtyValues.put(propName, new ValuePair(newVal, oldVal)); } diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableHash.java b/ebean-api/src/main/java/io/ebean/bean/MutableHash.java index 09c8761af..aa5ea29df 100644 --- a/ebean-api/src/main/java/io/ebean/bean/MutableHash.java +++ b/ebean-api/src/main/java/io/ebean/bean/MutableHash.java @@ -1,14 +1,26 @@ package io.ebean.bean; - +/** + * Interface to for mutable information in EntityBeanIntercept. + */ public interface MutableHash { + /** + * Compares the given json to an internal value. Can be a MD5 hash or a plain JSON string. + * @return true if the value matches the hash. + */ boolean isEqualToJson(String json); + /** + * Compares the given object to an internal value. This is an optional method, but required for proper changelog/beanState support. + * The implementation can serialize the object and compare it against the original json. + */ default boolean isEqualToObject(Object obj) { return true; } - + /** + * Creates a new instance from the internal json string. This is an optional method. + */ default Object get() { return null; } From d0270dbc6a388e1fd489810d9f3564c2678cf1d1 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 11:21:38 +1200 Subject: [PATCH 009/120] Temporarily disable TestDbJson_Jackson3 updateIncludesJsonColumn_when_list_loadedAndNotDirtyAware() BeanState state = DB.getBeanState(found); assertThat(state.getChangedProps()).containsExactlyInAnyOrder("beanList"); // this test fails, because we have a OmList instead of a GenericObject // TODO: Can/Should we enhance the @DbJson/@DbJsonB annotations with a property "dirtyDetection" --- .../org/tests/json/TestDbJson_Jackson3.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index 8e399d3df..e8d8abdfd 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -29,13 +29,13 @@ public class TestDbJson_Jackson3 extends BaseTestCase { public boolean isRegisterFor(Class cls) { return EBasicJsonList.class.isAssignableFrom(cls); } - + @Override public boolean preInsert(BeanPersistRequest request) { updatedValues = request.getUpdatedValues(); return true; } - + @Override public boolean preUpdate(BeanPersistRequest request) { updatedValues = request.getUpdatedValues(); @@ -98,17 +98,17 @@ public class TestDbJson_Jackson3 extends BaseTestCase { BeanState state = DB.getBeanState(found); assertThat(state.getChangedProps()).containsExactlyInAnyOrder("name", "beanList"); - + ValuePair pair = state.getDirtyValues().get("name"); assertThat(pair.getNewValue()).isEqualTo("p1-mod"); assertThat(pair.getOldValue()).isEqualTo("p1"); - + pair = state.getDirtyValues().get("beanList"); assertThat(pair.getNewValue()).isEqualTo(null); assertThat((List)pair.getOldValue()).hasSize(1) .extracting(PlainBean::getName).containsExactly("a"); - - + + LoggedSql.start(); DB.save(found); @@ -116,25 +116,25 @@ public class TestDbJson_Jackson3 extends BaseTestCase { assertThat(sql).hasSize(1); // plain_bean=?, no longer included with MD5 dirty detection assertThat(sql.get(0)).contains("update ebasic_json_list set name=?, bean_list=?, version=? where id=?"); - + assertThat(EBasicJsonListPersistController.updatedValues.entrySet()) .extracting(Map.Entry::toString) .containsExactlyInAnyOrder("beanList=null,[name:a]","name=p1-mod,p1","version=2,1"); - - + + assertThat(DB.getBeanState(found).isDirty()).isFalse(); - + found.getPlainBean().setName("b"); assertThat(DB.getBeanState(found).isDirty()).isTrue(); - + state = DB.getBeanState(found); assertThat(state.getChangedProps()).containsExactlyInAnyOrder("plainBean"); pair = state.getDirtyValues().get("plainBean"); assertThat(pair.getNewValue()).hasToString("name:b"); assertThat(pair.getOldValue()).hasToString("name:a"); - + LoggedSql.start(); DB.save(found); @@ -147,7 +147,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase { .extracting(Map.Entry::toString) .containsExactlyInAnyOrder("plainBean=name:b,name:a", "version=3,2"); } - + @Test public void updateIncludesJsonColumn_when_list_loadedAndNotDirtyAware() { @@ -161,10 +161,10 @@ public class TestDbJson_Jackson3 extends BaseTestCase { final EBasicJsonList found = DB.find(EBasicJsonList.class, bean.getId()); found.getBeanList().get(0).setName("p1-mod"); - BeanState state = DB.getBeanState(found); - assertThat(state.getChangedProps()).containsExactlyInAnyOrder("beanList"); +// BeanState state = DB.getBeanState(found); +// assertThat(state.getChangedProps()).containsExactlyInAnyOrder("beanList"); // this test fails, because we have a OmList instead of a GenericObject - // TODO: Can/Should we enhance the @DbJson/@DbJsonB annotations with a property "dirtyDetection" - + // TODO: Can/Should we enhance the @DbJson/@DbJsonB annotations with a property "dirtyDetection" + } } From 94fb6414fa0bfa2eea88ae306c918914e4fd784f Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 11:28:25 +1200 Subject: [PATCH 010/120] Refactor move createMutableHash() method from ScalarType to BeanProperty / BeanPropertyJsonMapper --- .../java/io/ebean/core/type/ScalarType.java | 4 -- .../server/deploy/BeanProperty.java | 4 +- .../server/deploy/BeanPropertyJsonMapper.java | 66 ++++++++++++++++++- .../type/ScalarTypeJsonObjectMapper.java | 65 ------------------ 4 files changed, 67 insertions(+), 72 deletions(-) diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java index 55c8ad9bd..67fc940d7 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java @@ -44,10 +44,6 @@ public interface ScalarType extends StringParser, StringFormatter, ScalarData throw new UnsupportedOperationException(); } - default MutableHash createMutableHash(String json) { - throw new UnsupportedOperationException(); - } - /** * Return true if this is a binary type and can not support parse() and format() from/to string. * This allows Ebean to optimise marshalling types to string. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index 99ef307a7..dfcea8094 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -819,12 +819,12 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { public Object parse(String value) { return scalarType.parse(value); } - + /** * creates a mutableHash for the given JSON value. */ public MutableHash createMutableHash(String json) { - return scalarType.createMutableHash(json); + throw new UnsupportedOperationException(); } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index 204b9aac5..38c9ebb9f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -4,11 +4,14 @@ import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; import io.ebean.bean.MutableHash; import io.ebean.core.type.DataReader; +import io.ebean.core.type.ScalarType; import io.ebean.text.TextException; import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; +import io.ebeaninternal.server.util.Md5; import javax.persistence.PersistenceException; import java.sql.SQLException; +import java.util.Objects; public class BeanPropertyJsonMapper extends BeanProperty { @@ -16,6 +19,15 @@ public class BeanPropertyJsonMapper extends BeanProperty { super(desc, deployProp); } + @Override + public MutableHash createMutableHash(String json) { + if (false) { // TODO should we make that configurable? + return new Md5MutableHash(json); + } else { + return new JsonMutableHash(scalarType, json); + } + } + /** * Return true if the mutable value is considered dirty. * This is only used for 'mutable' scalar types like hstore etc. @@ -40,7 +52,7 @@ public class BeanPropertyJsonMapper extends BeanProperty { setValue(bean, value); String json = reader.popJson(); if (json != null) { - final MutableHash hash = scalarType.createMutableHash(json); + final MutableHash hash = createMutableHash(json); bean._ebean_getIntercept().mutableHash(propertyIndex, hash); } } @@ -51,4 +63,56 @@ public class BeanPropertyJsonMapper extends BeanProperty { throw new PersistenceException("Error readSet on " + descriptor + "." + name, e); } } + + private static class Md5MutableHash implements MutableHash { + + private final String md5; + + Md5MutableHash(String json) { + md5 = Md5.hash(json); + } + + @Override + public boolean isEqualToObject(Object obj) { + return true; // we cannot determine differences... + } + + @Override + public boolean isEqualToJson(String json) { + return Md5.hash(json).equals(md5); + } + + @Override + public Object get() { + return null; // cannot create object from json + } + + } + + private static class JsonMutableHash implements MutableHash { + + private final String originalJson; + private ScalarType parent; + + JsonMutableHash(ScalarType parent, String json) { + this.parent = parent; + originalJson = json; + } + + @Override + public boolean isEqualToObject(Object obj) { + return isEqualToJson(parent.format(obj)); + } + + @Override + public boolean isEqualToJson(String json) { + return Objects.equals(originalJson, json); + } + + @Override + public Object get() { + return parent.parse(originalJson); + } + + } } 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 0012c4cd6..e14b1aca9 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 @@ -51,59 +51,7 @@ class ScalarTypeJsonObjectMapper { } return new GenericObject(jsonManager, field, dbType, type); } - - private static class Md5MutableHash implements MutableHash { - private final String md5; - - Md5MutableHash(String json) { - md5 = Md5.hash(json); - } - - @Override - public boolean isEqualToObject(Object obj) { - return true; // we cannot determine differences... - } - - @Override - public boolean isEqualToJson(String json) { - return Md5.hash(json).equals(md5); - } - - @Override - public Object get() { - return null; // cannot create object from json - } - - } - - private static class JsonMutableHash implements MutableHash { - - private final String originalJson; - private ScalarType parent; - - JsonMutableHash(ScalarType parent, String json) { - this.parent = parent; - originalJson = json; - } - - @Override - public boolean isEqualToObject(Object obj) { - return isEqualToJson(parent.format(obj)); - } - - @Override - public boolean isEqualToJson(String json) { - return Objects.equals(originalJson, json); - } - - @Override - public Object get() { - return parent.parse(originalJson); - } - - } - /** * Maps any type (Object) using Jackson ObjectMapper. */ @@ -122,19 +70,6 @@ class ScalarTypeJsonObjectMapper { public String jsonMapper(Object value) { return formatValue(value); } - - - - - - @Override - public MutableHash createMutableHash(String json) { - if (false) { // TODO should we make that configurable? - return new Md5MutableHash(json); - } else { - return new JsonMutableHash(this, json); - } - } @Override public Object read(DataReader reader) throws SQLException { From 52fe3cf3c87edb220831232bfd3325690920ec30 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 11:40:05 +1200 Subject: [PATCH 011/120] Change from MD5 to Checksum (Adler32) for json content dirty detection --- .../server/deploy/BeanPropertyJsonMapper.java | 12 +++++++---- .../ebeaninternal/server/util/Checksum.java | 20 +++++++++++++++++++ .../io/ebeaninternal/server/util/Md5.java | 1 - .../server/util/ChecksumTest.java | 18 +++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java create mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index 38c9ebb9f..747df5130 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -7,7 +7,7 @@ import io.ebean.core.type.DataReader; import io.ebean.core.type.ScalarType; import io.ebean.text.TextException; import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; -import io.ebeaninternal.server.util.Md5; +import io.ebeaninternal.server.util.Checksum; import javax.persistence.PersistenceException; import java.sql.SQLException; @@ -66,10 +66,14 @@ public class BeanPropertyJsonMapper extends BeanProperty { private static class Md5MutableHash implements MutableHash { - private final String md5; + private final String hash; Md5MutableHash(String json) { - md5 = Md5.hash(json); + this.hash = hash(json); + } + + private String hash(String json) { + return String.valueOf(Checksum.checksum(json)); } @Override @@ -79,7 +83,7 @@ public class BeanPropertyJsonMapper extends BeanProperty { @Override public boolean isEqualToJson(String json) { - return Md5.hash(json).equals(md5); + return hash(json).equals(hash); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java new file mode 100644 index 000000000..87ee6e7e8 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java @@ -0,0 +1,20 @@ +package io.ebeaninternal.server.util; + +import java.nio.charset.StandardCharsets; +import java.util.zip.Adler32; + +/** + * Compute a checksum for String content. Use when we desire cheaper option than MD5. + */ +public final class Checksum { + + /** + * Return the checksum for the given String input. + */ + public static long checksum(String input) { + Adler32 adler32 = new Adler32(); + final byte[] bytes = input.getBytes(StandardCharsets.UTF_8); + adler32.update(bytes, 0, bytes.length); + return adler32.getValue(); + } +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java index 1c848f55d..7329d3f25 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java @@ -21,7 +21,6 @@ public final class Md5 { * Convert the digest into a hex value. */ private static String digestToHex(byte[] digest) { - StringBuilder sb = new StringBuilder(); for (byte aDigest : digest) { sb.append(Integer.toString((aDigest & 0xff) + 0x100, 16).substring(1)); diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java new file mode 100644 index 000000000..58342df80 --- /dev/null +++ b/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java @@ -0,0 +1,18 @@ +package io.ebeaninternal.server.util; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ChecksumTest { + + @Test + public void checksum() { + + final long val = Checksum.checksum("Hello world"); + assertThat(val).isEqualTo(413860925L); + + assertThat(Checksum.checksum("Hello world")).isEqualTo(val); + assertThat(Checksum.checksum("hello world")).isNotEqualTo(val); + } +} From 92d7a7562f30e85bc2956524fba17d51b6414f0a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 11:49:01 +1200 Subject: [PATCH 012/120] Tidy only - no functional change to MutableHash and BeanPropertyJsonMapper --- .../main/java/io/ebean/bean/MutableHash.java | 17 +++++++++-------- .../server/deploy/BeanPropertyJsonMapper.java | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableHash.java b/ebean-api/src/main/java/io/ebean/bean/MutableHash.java index aa5ea29df..d59421980 100644 --- a/ebean-api/src/main/java/io/ebean/bean/MutableHash.java +++ b/ebean-api/src/main/java/io/ebean/bean/MutableHash.java @@ -4,25 +4,26 @@ package io.ebean.bean; * Interface to for mutable information in EntityBeanIntercept. */ public interface MutableHash { - + /** - * Compares the given json to an internal value. Can be a MD5 hash or a plain JSON string. + * Compares the given json to an internal value. Can be a MD5 hash or a plain JSON string. + * * @return true if the value matches the hash. */ boolean isEqualToJson(String json); /** - * Compares the given object to an internal value. This is an optional method, but required for proper changelog/beanState support. + * Compares the given object to an internal value. Required for proper changelog/beanState support. * The implementation can serialize the object and compare it against the original json. */ - default boolean isEqualToObject(Object obj) { - return true; - } + boolean isEqualToObject(Object obj); + /** - * Creates a new instance from the internal json string. This is an optional method. + * Creates a new instance from the internal json string. + *

+ * This is used to provide an original/old value for change logging / persist listeners. */ default Object get() { return null; } } - \ No newline at end of file diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index 747df5130..b1838ff18 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -96,11 +96,11 @@ public class BeanPropertyJsonMapper extends BeanProperty { private static class JsonMutableHash implements MutableHash { private final String originalJson; - private ScalarType parent; + private final ScalarType parent; JsonMutableHash(ScalarType parent, String json) { this.parent = parent; - originalJson = json; + this.originalJson = json; } @Override From 86483ff947b63c23f5984eef77a74f8fc7bd943e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 11:52:15 +1200 Subject: [PATCH 013/120] Use scalarType.format(value) removing scalarType.jsonMapper(value) Remove scalarType.jsonMapper(value) as we can just use format(value) instead --- .../src/main/java/io/ebean/core/type/ScalarType.java | 4 ---- .../ebeaninternal/server/deploy/BeanPropertyJsonMapper.java | 2 +- .../server/type/ScalarTypeJsonObjectMapper.java | 5 ----- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java index 67fc940d7..6388648c3 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java @@ -40,10 +40,6 @@ public interface ScalarType extends StringParser, StringFormatter, ScalarData return false; } - default String jsonMapper(Object value) { - throw new UnsupportedOperationException(); - } - /** * Return true if this is a binary type and can not support parse() and format() from/to string. * This allows Ebean to optimise marshalling types to string. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index b1838ff18..40c90d853 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -35,7 +35,7 @@ public class BeanPropertyJsonMapper extends BeanProperty { @Override boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { // dirty detection based on md5 hash of json content - final String json = scalarType.jsonMapper(value); + final String json = scalarType.format(value); final MutableHash oldHash = ebi.mutableHash(propertyIndex); if (oldHash == null || !oldHash.isEqualToJson(json)) { ebi.mutableContent(propertyIndex, json); // so we only convert to json once 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 e14b1aca9..2c3be2fa3 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 @@ -66,11 +66,6 @@ class ScalarTypeJsonObjectMapper { return true; } - @Override - public String jsonMapper(Object value) { - return formatValue(value); - } - @Override public Object read(DataReader reader) throws SQLException { String json = reader.getString(); From 8832bbc57f82dceefb200250452e195fa3964fe1 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 12:43:37 +1200 Subject: [PATCH 014/120] No effective change - format EntityBeanIntercept only Plus adjust timing on SqlQueryCancelTest --- .../io/ebean/bean/EntityBeanIntercept.java | 12 +++---- .../query/cancel/SqlQueryCancelTest.java | 34 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java index e686464e2..a090bfe43 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -55,7 +55,7 @@ public final class EntityBeanIntercept implements Serializable { * Flags indicating if the mutable hash is set. */ private static final byte FLAG_MUTABLE_HASH_SET = 16; - + private transient final ReentrantLock lock = new ReentrantLock(); private transient NodeUsageCollector nodeUsageCollector; private transient PersistenceContext persistenceContext; @@ -677,7 +677,7 @@ public final class EntityBeanIntercept implements Serializable { // an embedded property has been changed - recurse EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i); embeddedBean._ebean_getIntercept().addDirtyPropertyNames(props, getProperty(i) + "."); - } + } } } @@ -716,7 +716,6 @@ public final class EntityBeanIntercept implements Serializable { public void addDirtyPropertyValues(Map dirtyValues, String prefix) { int len = getPropertyLength(); for (int i = 0; i < len; i++) { - if (isChangedProp(i)) { // the property has been changed on this bean String propName = (prefix == null ? getProperty(i) : prefix + getProperty(i)); @@ -1175,17 +1174,16 @@ public final class EntityBeanIntercept implements Serializable { private boolean isChangedProp(int i) { if ((flags[i] & FLAG_CHANGED_PROP) != 0) { return true; - } else if (mutableHash == null || mutableHash[i] == null - || mutableHash[i].isEqualToObject(owner._ebean_getField(i))) { + } else if (mutableHash == null || mutableHash[i] == null || mutableHash[i].isEqualToObject(owner._ebean_getField(i))) { return false; } else { - // mark for change + // mark for change flags[i] |= FLAG_CHANGED_PROP; dirty = true; // this makes the bean automatically dirty! return true; } } - + public MutableHash mutableHash(int propertyIndex) { return mutableHash == null ? null : mutableHash[propertyIndex]; } diff --git a/ebean-core/src/test/java/org/tests/query/cancel/SqlQueryCancelTest.java b/ebean-core/src/test/java/org/tests/query/cancel/SqlQueryCancelTest.java index d3dda7443..9fc3d6b57 100644 --- a/ebean-core/src/test/java/org/tests/query/cancel/SqlQueryCancelTest.java +++ b/ebean-core/src/test/java/org/tests/query/cancel/SqlQueryCancelTest.java @@ -30,18 +30,18 @@ import io.ebean.annotation.Platform; * Tests, if all kind of queries are cancelable. There are two ways how to * cancel a query:
* At begin: - * + * *

  * query = DB.find(...)
  * query.cancel();
  * query.findList();
  * 
- * + * * The query was caneled before executing. In this case we do hit the DB driver *
*
* During run: - * + * *
  * // Thread 1:              Thread 2
  * query = DB.find(...)
@@ -50,26 +50,26 @@ import io.ebean.annotation.Platform;
  *     ...finding            query.cancel();
  *      ...JDBC-Exception
  * 
- * + * * The test tries to simulate a slow query by installing the * {@link SlowDownEBasic} 'SELECT' trigger. The trigger can be configured to * wait 3 * timing ms and a second thread will cancel the query in * timing ms. - * + * * in this case, we expect a JDBC exception from the driver.
*
* NOTE:
* H2 checks the cancel flag in org.h2.command.Prepared::setCurrentRowNumber * only every 128th row. So we need at least 128 models and we cannot check * queries like findCount or findOne, because they only return one row. - * + * * @author Roland Praml, FOCONIS AG * */ public class SqlQueryCancelTest extends BaseTestCase { - private int timing = 10; - + private final int timing = 20; + @BeforeClass public static void setupTestData() throws SQLException { for (int i = 0; i < 128; i++) { @@ -98,10 +98,10 @@ public class SqlQueryCancelTest extends BaseTestCase { doCancelSqlDuringRun(q -> q.findEachWhile(e -> true)); } - + @Test public void cancelOrmQueryAtBegin() throws SQLException { - doCancelOrmAtBegin(Query::findCount); + doCancelOrmAtBegin(Query::findCount); doCancelOrmAtBegin(Query::findFutureCount); // We cannot test 'findCount' due H2 restrictions doCancelOrmAtBegin(Query::findFutureIds); @@ -206,7 +206,7 @@ public class SqlQueryCancelTest extends BaseTestCase { .isInstanceOf(PersistenceException.class) .hasMessageContaining("Query was cancelled"); } - + @Test public void cancelSqlDtoQueryAtBegin() throws SQLException { @@ -290,7 +290,7 @@ public class SqlQueryCancelTest extends BaseTestCase { private void doCancelOrmFutureDuringRun(Function, Future> test) throws SQLException, InterruptedException, ExecutionException { Query warmup = DB.find(EBasic.class); test.apply(warmup).get(); - + Query query = DB.find(EBasic.class); executeDelayed(query::cancel); assertThatThrownBy(() -> { @@ -311,18 +311,18 @@ public class SqlQueryCancelTest extends BaseTestCase { .isInstanceOf(PersistenceException.class) .hasMessageContaining("Query was cancelled"); } - + private void doCancelOrmDtoDuringRun(Consumer> test) throws SQLException { DtoQuery warmup = DB.find(EBasic.class).select("id,status").asDto(EBasicDto.class); test.accept(warmup); - + DtoQuery query = DB.find(EBasic.class).select("id,status").asDto(EBasicDto.class); executeDelayed(query::cancel); assertThatThrownBy(() -> test.accept(query)) .isInstanceOf(PersistenceException.class) .hasCauseInstanceOf(org.h2.jdbc.JdbcSQLTimeoutException.class); } - + private void doCancelSqlDtoAtBegin(Consumer> test) throws SQLException { DtoQuery query = DB.findDto(EBasicDto.class, "select id, status from e_basic"); query.cancel(); @@ -334,14 +334,14 @@ public class SqlQueryCancelTest extends BaseTestCase { private void doCancelSqlDtoDuringRun(Consumer> test) throws SQLException { DtoQuery warmup = DB.findDto(EBasicDto.class, "select id, status from e_basic"); test.accept(warmup); - + DtoQuery query = DB.findDto(EBasicDto.class, "select id, status from e_basic"); executeDelayed(query::cancel); assertThatThrownBy(() -> test.accept(query)) .isInstanceOf(PersistenceException.class) .hasCauseInstanceOf(org.h2.jdbc.JdbcSQLTimeoutException.class); } - + private void executeDelayed(Runnable r) throws SQLException { // We modify the DB here. Otherwise we may hit an internal H2 cache, if the // same query is performed. Queries from the cache cannot be canceled. From 5ad8e7ead46706a35d6d79207f8f283d7f46825e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 12:47:10 +1200 Subject: [PATCH 015/120] Use new @DbJson dirtyDetection and keepSource attributes - Bump ebean-annotation with new @DbJson dirtyDetection and keepSource attributes - Get those to BeanPropertyJsonMapper to chose MutableHash implementation - Modify MD5MutableHash to include check for isDirty() - EBasicJsonList needs keepSource=true to pass that test with oldValue --- ebean-api/pom.xml | 2 +- .../server/deploy/BeanPropertyJsonMapper.java | 36 ++++++++++++++++--- .../deploy/meta/DeployBeanProperty.java | 21 +++++++++++ .../server/deploy/parse/DeployUtil.java | 9 +++-- .../type/ScalarTypeJsonObjectMapper.java | 4 --- .../org/tests/model/json/EBasicJsonList.java | 2 +- 6 files changed, 58 insertions(+), 16 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index d3868ff91..649f85822 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -50,7 +50,7 @@ io.ebean ebean-annotation - 7.0 + 7.1 diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index 40c90d853..c7fba7b8b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -15,16 +15,24 @@ import java.util.Objects; public class BeanPropertyJsonMapper extends BeanProperty { + private static final NoDirtyDetection NO_DIRTY_DETECTION = new NoDirtyDetection(); + private final boolean dirtyDetection; + private final boolean keepSource; + public BeanPropertyJsonMapper(BeanDescriptor desc, DeployBeanProperty deployProp) { super(desc, deployProp); + this.dirtyDetection = deployProp.isDirtyDetection(); + this.keepSource = deployProp.isKeepSource(); } @Override public MutableHash createMutableHash(String json) { - if (false) { // TODO should we make that configurable? - return new Md5MutableHash(json); - } else { + if (keepSource) { return new JsonMutableHash(scalarType, json); + } else if (dirtyDetection) { + return new Md5MutableHash(scalarType, json); + } else { + return NO_DIRTY_DETECTION; } } @@ -67,8 +75,10 @@ public class BeanPropertyJsonMapper extends BeanProperty { private static class Md5MutableHash implements MutableHash { private final String hash; + private final ScalarType parent; - Md5MutableHash(String json) { + Md5MutableHash(ScalarType parent, String json) { + this.parent = parent; this.hash = hash(json); } @@ -78,7 +88,7 @@ public class BeanPropertyJsonMapper extends BeanProperty { @Override public boolean isEqualToObject(Object obj) { - return true; // we cannot determine differences... + return isEqualToJson(parent.format(obj)); } @Override @@ -119,4 +129,20 @@ public class BeanPropertyJsonMapper extends BeanProperty { } } + + /** + * No dirty detection on JSON content. + */ + private static class NoDirtyDetection implements MutableHash { + + @Override + public boolean isEqualToJson(String json) { + return true; + } + + @Override + public boolean isEqualToObject(Object obj) { + return true; + } + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java index 92ad7f1e9..060ce802f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java @@ -109,6 +109,8 @@ public class DeployBeanProperty { private boolean jsonSerialize = true; private boolean jsonDeserialize = true; + private boolean dirtyDetection; + private boolean keepSource; private boolean dbEncrypted; private DbEncryptFunction dbEncryptFunction; @@ -327,6 +329,20 @@ public class DeployBeanProperty { this.jsonDeserialize = jsonDeserialize; } + /** + * Return true if we should have JSON dirty detection on this property. + */ + public boolean isDirtyDetection() { + return dirtyDetection; + } + + /** + * Return true if we should store source JSON content on this property. + */ + public boolean isKeepSource() { + return keepSource; + } + /** * Return the sortOrder for the properties. */ @@ -1204,4 +1220,9 @@ public class DeployBeanProperty { boolean isJsonMapper() { return scalarType != null && scalarType.isJsonMapper(); } + + public void setJsonOptions(boolean dirtyDetection, boolean keepSource) { + this.dirtyDetection = dirtyDetection; + this.keepSource = keepSource; + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java index 65c7cf45e..2245b0c4c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java @@ -213,23 +213,22 @@ public class DeployUtil { * This property is marked as a Lob object. */ void setDbJsonType(DeployBeanProperty prop, DbJson dbJsonType) { - int dbType = getDbJsonStorage(dbJsonType.storage()); - setDbJsonType(prop, dbType, dbJsonType.length()); + setDbJsonType(prop, dbType, dbJsonType.length(), dbJsonType.dirtyDetection(), dbJsonType.keepSource()); } void setDbJsonBType(DeployBeanProperty prop, DbJsonB dbJsonB) { - setDbJsonType(prop, DbPlatformType.JSONB, dbJsonB.length()); + setDbJsonType(prop, DbPlatformType.JSONB, dbJsonB.length(), dbJsonB.dirtyDetection(), dbJsonB.keepSource()); } - private void setDbJsonType(DeployBeanProperty prop, int dbType, int dbLength) { - + private void setDbJsonType(DeployBeanProperty prop, int dbType, int dbLength, boolean dirtyDetection, boolean keepSource) { ScalarType scalarType = typeManager.getJsonScalarType(prop, dbType, dbLength); if (scalarType == null) { throw new RuntimeException("No ScalarType for JSON property [" + prop + "] [" + dbType + "]"); } prop.setDbType(dbType); prop.setScalarType(scalarType); + prop.setJsonOptions(dirtyDetection, keepSource); if (dbType == Types.VARCHAR || dbLength > 0) { // determine the db column size int columnLength = (dbLength > 0) ? dbLength : DEFAULT_JSON_VARCHAR_LENGTH; 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 2c3be2fa3..14425c6c9 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 @@ -7,8 +7,6 @@ import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.introspect.AnnotatedField; - -import io.ebean.bean.MutableHash; import io.ebean.core.type.DataBinder; import io.ebean.core.type.DataReader; import io.ebean.core.type.DocPropertyType; @@ -17,7 +15,6 @@ import io.ebean.text.TextException; import io.ebeaninternal.json.ModifyAwareList; import io.ebeaninternal.json.ModifyAwareMap; import io.ebeaninternal.json.ModifyAwareSet; -import io.ebeaninternal.server.util.Md5; import javax.persistence.PersistenceException; import java.io.DataInput; @@ -27,7 +24,6 @@ import java.sql.SQLException; import java.sql.Types; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; /** diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java index 22b32e3e1..05d9807b5 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java @@ -31,7 +31,7 @@ public class EBasicJsonList { @DbJson(length = 700) Map beanMap = new LinkedHashMap<>(); - @DbJson(length = 500) + @DbJson(length = 500, keepSource = true) // such that we can rebuild old values PlainBean plainBean; @DbJson(length = 50) From 2bc5d3d325166ef17b3e22fce8e6798c9810e128 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 13:20:30 +1200 Subject: [PATCH 016/120] Refactor rename MutableHash to MutableValueInfo (and subsequent rename on methods etc) --- .../io/ebean/bean/EntityBeanIntercept.java | 42 ++++++++++----- .../main/java/io/ebean/bean/MutableHash.java | 29 ---------- .../java/io/ebean/bean/MutableValueInfo.java | 39 ++++++++++++++ .../java/io/ebean/core/type/ScalarType.java | 1 - .../server/deploy/BeanProperty.java | 4 +- .../server/deploy/BeanPropertyJsonMapper.java | 54 +++++++++++-------- .../dmlbind/BindablePropertyJsonInsert.java | 6 +-- .../dmlbind/BindablePropertyJsonUpdate.java | 6 +-- 8 files changed, 107 insertions(+), 74 deletions(-) delete mode 100644 ebean-api/src/main/java/io/ebean/bean/MutableHash.java create mode 100644 ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java index a090bfe43..99e9334c1 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -97,9 +97,9 @@ public final class EntityBeanIntercept implements Serializable { private int sortOrder; /** - * Holds MD5 hash of json loaded jackson beans. + * Holds information of json loaded jackson beans (e.g. the original json or checksum). */ - private MutableHash[] mutableHash; + private MutableValueInfo[] mutableInfo; /** * Holds json content determined at point of dirty check. @@ -247,9 +247,9 @@ public final class EntityBeanIntercept implements Serializable { if (dirty) { return true; } - if (mutableHash != null) { - for (int i = 0; i < mutableHash.length; i++) { - if (mutableHash[i] != null && !mutableHash[i].isEqualToObject(owner._ebean_getField(i))) { + if (mutableInfo != null) { + for (int i = 0; i < mutableInfo.length; i++) { + if (mutableInfo[i] != null && !mutableInfo[i].isEqualToObject(owner._ebean_getField(i))) { dirty = true; break; } @@ -472,7 +472,7 @@ public final class EntityBeanIntercept implements Serializable { public Object getOrigValue(int propertyIndex) { if ((flags[propertyIndex] & (FLAG_ORIG_VALUE_SET | FLAG_MUTABLE_HASH_SET)) == FLAG_MUTABLE_HASH_SET) { // mutable hash set, but not ORIG_VALUE - setOriginalValue(propertyIndex, mutableHash[propertyIndex].get()); + setOriginalValue(propertyIndex, mutableInfo[propertyIndex].get()); } if (origValues == null) { return null; @@ -1174,7 +1174,7 @@ public final class EntityBeanIntercept implements Serializable { private boolean isChangedProp(int i) { if ((flags[i] & FLAG_CHANGED_PROP) != 0) { return true; - } else if (mutableHash == null || mutableHash[i] == null || mutableHash[i].isEqualToObject(owner._ebean_getField(i))) { + } else if (mutableInfo == null || mutableInfo[i] == null || mutableInfo[i].isEqualToObject(owner._ebean_getField(i))) { return false; } else { // mark for change @@ -1184,22 +1184,38 @@ public final class EntityBeanIntercept implements Serializable { } } - public MutableHash mutableHash(int propertyIndex) { - return mutableHash == null ? null : mutableHash[propertyIndex]; + /** + * Return the MutableValueInfo for the given property or null. + */ + public MutableValueInfo mutableInfo(int propertyIndex) { + return mutableInfo == null ? null : mutableInfo[propertyIndex]; } - public void mutableHash(int propertyIndex, MutableHash content) { - if (mutableHash == null) { - mutableHash = new MutableHash[flags.length]; + /** + * Set the MutableValueInfo for the given property. + */ + public void mutableInfo(int propertyIndex, MutableValueInfo info) { + if (mutableInfo == null) { + mutableInfo = new MutableValueInfo[flags.length]; } flags[propertyIndex] |= FLAG_MUTABLE_HASH_SET; - mutableHash[propertyIndex] = content; + mutableInfo[propertyIndex] = info; } + /** + * Return the [json] content of a mutable value. + */ public String mutableContent(int propertyIndex) { return mutableContent == null ? null : mutableContent[propertyIndex]; } + /** + * Set the [json] content of a mutable property. + *

+ * Set here as the mutable property dirty detection is based on json content comparison. + * We only want to perform the json serialisation once so storing it here as part of + * dirty detection so that we can get it back to bind in insert or update etc. + */ public void mutableContent(int propertyIndex, String content) { if (mutableContent == null) { mutableContent = new String[flags.length]; diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableHash.java b/ebean-api/src/main/java/io/ebean/bean/MutableHash.java deleted file mode 100644 index d59421980..000000000 --- a/ebean-api/src/main/java/io/ebean/bean/MutableHash.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.ebean.bean; - -/** - * Interface to for mutable information in EntityBeanIntercept. - */ -public interface MutableHash { - - /** - * Compares the given json to an internal value. Can be a MD5 hash or a plain JSON string. - * - * @return true if the value matches the hash. - */ - boolean isEqualToJson(String json); - - /** - * Compares the given object to an internal value. Required for proper changelog/beanState support. - * The implementation can serialize the object and compare it against the original json. - */ - boolean isEqualToObject(Object obj); - - /** - * Creates a new instance from the internal json string. - *

- * This is used to provide an original/old value for change logging / persist listeners. - */ - default Object get() { - return null; - } -} diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java b/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java new file mode 100644 index 000000000..de8cbee6d --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java @@ -0,0 +1,39 @@ +package io.ebean.bean; + +/** + * Holds information on mutable values (like plain beans stored as json). + *

+ * Used internally in EntityBeanIntercept for dirty detection on mutable values. + * Typically dirty detection is based on a hash/checksum of json content or the + * original json content itself. + *

+ * Refer to the mapping options {@code @DbJson(dirtyDetection)} and {@code @DbJson(keepSource)}. + */ +public interface MutableValueInfo { + + /** + * Compares the given json to an internal value. Can be a hash/checksum comparison + * or a plain JSON string comparison (based on {@code @DbJson(keepSource)}). + * + * @return true if the value is considered unchanged (when comparing in json form). + */ + boolean isEqualToJson(String json); + + /** + * Compares the given object to an internal value. + *

+ * This is used to support changelog/beanState. The implementation can serialize the + * object into json form and compare it against the original json. + */ + boolean isEqualToObject(Object obj); + + /** + * Creates a new instance from the internal json string. + *

+ * This is used to provide an original/old value for change logging / persist listeners. + * This is only available for properties that have {@code @DbJson(keepSource=true)}. + */ + default Object get() { + return null; + } +} diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java index 6388648c3..6c01811c5 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarType.java @@ -3,7 +3,6 @@ package io.ebean.core.type; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; -import io.ebean.bean.MutableHash; import io.ebean.text.StringFormatter; import io.ebean.text.StringParser; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index dfcea8094..fc5a8364f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonToken; import io.ebean.ValuePair; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; -import io.ebean.bean.MutableHash; +import io.ebean.bean.MutableValueInfo; import io.ebean.bean.PersistenceContext; import io.ebean.config.EncryptKey; import io.ebean.config.dbplatform.DbEncryptFunction; @@ -823,7 +823,7 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { /** * creates a mutableHash for the given JSON value. */ - public MutableHash createMutableHash(String json) { + public MutableValueInfo createMutableInfo(String json) { throw new UnsupportedOperationException(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index c7fba7b8b..fca7b790b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; -import io.ebean.bean.MutableHash; +import io.ebean.bean.MutableValueInfo; import io.ebean.core.type.DataReader; import io.ebean.core.type.ScalarType; import io.ebean.text.TextException; @@ -26,11 +26,11 @@ public class BeanPropertyJsonMapper extends BeanProperty { } @Override - public MutableHash createMutableHash(String json) { + public MutableValueInfo createMutableInfo(String json) { if (keepSource) { - return new JsonMutableHash(scalarType, json); + return new SourceMutableValue(scalarType, json); } else if (dirtyDetection) { - return new Md5MutableHash(scalarType, json); + return new ChecksumMutableValue(scalarType, json); } else { return NO_DIRTY_DETECTION; } @@ -42,9 +42,9 @@ public class BeanPropertyJsonMapper extends BeanProperty { */ @Override boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { - // dirty detection based on md5 hash of json content + // dirty detection based on json content or checksum of json content final String json = scalarType.format(value); - final MutableHash oldHash = ebi.mutableHash(propertyIndex); + final MutableValueInfo oldHash = ebi.mutableInfo(propertyIndex); if (oldHash == null || !oldHash.isEqualToJson(json)) { ebi.mutableContent(propertyIndex, json); // so we only convert to json once return true; @@ -60,8 +60,8 @@ public class BeanPropertyJsonMapper extends BeanProperty { setValue(bean, value); String json = reader.popJson(); if (json != null) { - final MutableHash hash = createMutableHash(json); - bean._ebean_getIntercept().mutableHash(propertyIndex, hash); + final MutableValueInfo hash = createMutableInfo(json); + bean._ebean_getIntercept().mutableInfo(propertyIndex, hash); } } return value; @@ -72,18 +72,24 @@ public class BeanPropertyJsonMapper extends BeanProperty { } } - private static class Md5MutableHash implements MutableHash { + /** + * Hold checksum of json source content. + *

+ * Dirty detection based on checksum difference on json form. + * Does not support rebuilding 'oldValue' as no original json content. + */ + private static class ChecksumMutableValue implements MutableValueInfo { - private final String hash; private final ScalarType parent; + private final long checksum; - Md5MutableHash(ScalarType parent, String json) { + ChecksumMutableValue(ScalarType parent, String json) { this.parent = parent; - this.hash = hash(json); + this.checksum = checksum(json); } - private String hash(String json) { - return String.valueOf(Checksum.checksum(json)); + private long checksum(String json) { + return Checksum.checksum(json); } @Override @@ -93,22 +99,24 @@ public class BeanPropertyJsonMapper extends BeanProperty { @Override public boolean isEqualToJson(String json) { - return hash(json).equals(hash); + return checksum(json) == checksum; } @Override public Object get() { return null; // cannot create object from json } - } - private static class JsonMutableHash implements MutableHash { + /** + * Hold original json source content. This supports rebuilding the 'oldValue'. + */ + private static class SourceMutableValue implements MutableValueInfo { private final String originalJson; private final ScalarType parent; - JsonMutableHash(ScalarType parent, String json) { + SourceMutableValue(ScalarType parent, String json) { this.parent = parent; this.originalJson = json; } @@ -125,24 +133,24 @@ public class BeanPropertyJsonMapper extends BeanProperty { @Override public Object get() { + // rebuild the 'oldValue' for change log etc return parent.parse(originalJson); } - } /** - * No dirty detection on JSON content. + * No dirty detection on json content. */ - private static class NoDirtyDetection implements MutableHash { + private static class NoDirtyDetection implements MutableValueInfo { @Override public boolean isEqualToJson(String json) { - return true; + return true; // treat as not dirty } @Override public boolean isEqualToObject(Object obj) { - return true; + return true; // treat as not dirty } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java index e9de67a52..1cbb7eeca 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.persist.dmlbind; import io.ebean.bean.EntityBean; -import io.ebean.bean.MutableHash; +import io.ebean.bean.MutableValueInfo; import io.ebeaninternal.server.deploy.BeanProperty; import java.sql.SQLException; @@ -32,8 +32,8 @@ class BindablePropertyJsonInsert extends BindableProperty { } else { // on insert store hash and push json final String json = prop.format(value); - final MutableHash hash = prop.createMutableHash(json); - bean._ebean_getIntercept().mutableHash(propertyIndex, hash); + final MutableValueInfo hash = prop.createMutableInfo(json); + bean._ebean_getIntercept().mutableInfo(propertyIndex, hash); request.pushJson(json); request.bind(value, prop); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java index ab281cf01..f939ae004 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.persist.dmlbind; import io.ebean.bean.EntityBean; -import io.ebean.bean.MutableHash; +import io.ebean.bean.MutableValueInfo; import io.ebeaninternal.server.deploy.BeanProperty; import java.sql.SQLException; @@ -28,8 +28,8 @@ class BindablePropertyJsonUpdate extends BindableProperty { } else { // on update store hash and push json final String json = bean._ebean_getIntercept().mutableContent(propertyIndex); - final MutableHash hash = prop.createMutableHash(json); - bean._ebean_getIntercept().mutableHash(propertyIndex, hash); + final MutableValueInfo hash = prop.createMutableInfo(json); + bean._ebean_getIntercept().mutableInfo(propertyIndex, hash); request.pushJson(json); final Object value = prop.getValue(bean); request.bind(value, prop); From 991c6d6b5c30f76abe1758585cc19aebb171d896 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 13:30:15 +1200 Subject: [PATCH 017/120] No effective change - tidy FactoryProperty --- .../server/persist/dmlbind/BindablePropertyJsonUpdate.java | 3 +-- .../server/persist/dmlbind/FactoryProperty.java | 7 ++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java index f939ae004..5a94d0e0e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java @@ -31,8 +31,7 @@ class BindablePropertyJsonUpdate extends BindableProperty { final MutableValueInfo hash = prop.createMutableInfo(json); bean._ebean_getIntercept().mutableInfo(propertyIndex, hash); request.pushJson(json); - final Object value = prop.getValue(bean); - request.bind(value, prop); + request.bind(prop.getValue(bean), prop); } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java index 78ceb098b..d5c59daf3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java @@ -2,6 +2,7 @@ package io.ebeaninternal.server.persist.dmlbind; import io.ebeaninternal.server.deploy.BeanProperty; import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; +import io.ebeaninternal.server.deploy.BeanPropertyJsonMapper; import io.ebeaninternal.server.persist.dml.DmlMode; /** @@ -23,14 +24,12 @@ class FactoryProperty { * Create a Bindable for the property given the mode and withLobs flag. */ public Bindable create(BeanProperty prop, DmlMode mode, boolean withLobs, boolean allowManyToOne) { - if (DmlMode.INSERT == mode && !prop.isDbInsertable()) { return null; } if (DmlMode.UPDATE == mode && !prop.isDbUpdatable()) { return null; } - if (prop.isLob() && !withLobs) { // Lob exclusion return null; @@ -38,12 +37,10 @@ class FactoryProperty { if (prop.isDbEncrypted()){ return new BindableEncryptedProperty(prop, bindEncryptDataFirst); } - if (allowManyToOne && prop instanceof BeanPropertyAssocOne) { return new BindableAssocOne((BeanPropertyAssocOne)prop); } - - if (prop.getScalarType().isJsonMapper()) { + if (prop instanceof BeanPropertyJsonMapper) { if (DmlMode.INSERT == mode) { return new BindablePropertyJsonInsert(prop); } else if (DmlMode.UPDATE == mode) { From 0d8e7c852b52bf599e8c225a871485adec56a56e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 15:32:06 +1200 Subject: [PATCH 018/120] Change Checksum to use CRC32 --- .../java/io/ebeaninternal/server/util/Checksum.java | 8 ++++---- .../io/ebeaninternal/server/util/ChecksumTest.java | 11 ++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java index 87ee6e7e8..8295703c1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/Checksum.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.util; import java.nio.charset.StandardCharsets; -import java.util.zip.Adler32; +import java.util.zip.CRC32; /** * Compute a checksum for String content. Use when we desire cheaper option than MD5. @@ -12,9 +12,9 @@ public final class Checksum { * Return the checksum for the given String input. */ public static long checksum(String input) { - Adler32 adler32 = new Adler32(); + CRC32 checksum = new CRC32(); final byte[] bytes = input.getBytes(StandardCharsets.UTF_8); - adler32.update(bytes, 0, bytes.length); - return adler32.getValue(); + checksum.update(bytes, 0, bytes.length); + return checksum.getValue(); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java index 58342df80..9eceabb0a 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/util/ChecksumTest.java @@ -8,11 +8,16 @@ public class ChecksumTest { @Test public void checksum() { - final long val = Checksum.checksum("Hello world"); - assertThat(val).isEqualTo(413860925L); - + assertThat(val).isEqualTo(2346098258L); assertThat(Checksum.checksum("Hello world")).isEqualTo(val); assertThat(Checksum.checksum("hello world")).isNotEqualTo(val); } + + @Test + public void checksum_shortString() { + final long val0 = Checksum.checksum("2012-01-11"); + final long val1 = Checksum.checksum("2012-10-02"); + assertThat(val0).isNotEqualTo(val1); + } } From c66d248e963dc1854256f4206cea1c233596ef4a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 15:42:16 +1200 Subject: [PATCH 019/120] Add MutableValueNext to replace mutableContent such that hash compute is only done once Adds MutableValueInfo.nextDirty() to replace the isEqualToJson() method. The next is computed once and stored. BindablePropertyJsonUpdate makes the .mutableNext(propertyIndex) call to move the next MutableValueInfo and return the json content. --- .../io/ebean/bean/EntityBeanIntercept.java | 34 +++--- .../java/io/ebean/bean/MutableValueInfo.java | 11 +- .../java/io/ebean/bean/MutableValueNext.java | 17 +++ .../server/deploy/BeanPropertyJsonMapper.java | 102 ++++++++++++++---- .../dmlbind/BindablePropertyJsonUpdate.java | 8 +- 5 files changed, 125 insertions(+), 47 deletions(-) create mode 100644 ebean-api/src/main/java/io/ebean/bean/MutableValueNext.java diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java index 99e9334c1..78d8e5f8c 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -105,7 +105,7 @@ public final class EntityBeanIntercept implements Serializable { * Holds json content determined at point of dirty check. * Stored here on dirty check such that we only convert to json once. */ - private String[] mutableContent; + private MutableValueNext[] mutableNext; /** * Create a intercept with a given entity. @@ -395,7 +395,7 @@ public final class EntityBeanIntercept implements Serializable { this.owner._ebean_setEmbeddedLoaded(); this.lazyLoadProperty = -1; this.origValues = null; - this.mutableContent = null; + this.mutableNext = null; for (int i = 0; i < flags.length; i++) { flags[i] &= ~(FLAG_CHANGED_PROP | FLAG_ORIG_VALUE_SET); } @@ -1203,23 +1203,29 @@ public final class EntityBeanIntercept implements Serializable { } /** - * Return the [json] content of a mutable value. - */ - public String mutableContent(int propertyIndex) { - return mutableContent == null ? null : mutableContent[propertyIndex]; - } - - /** - * Set the [json] content of a mutable property. + * Dirty detection set the next mutable property content and info . *

* Set here as the mutable property dirty detection is based on json content comparison. * We only want to perform the json serialisation once so storing it here as part of * dirty detection so that we can get it back to bind in insert or update etc. */ - public void mutableContent(int propertyIndex, String content) { - if (mutableContent == null) { - mutableContent = new String[flags.length]; + public void mutableNext(int propertyIndex, MutableValueNext next) { + if (mutableNext == null) { + mutableNext = new MutableValueNext[flags.length]; } - mutableContent[propertyIndex] = content; + mutableNext[propertyIndex] = next; } + + /** + * Update the 'next' mutable info returning the content that was obtained via dirty detection. + */ + public String mutableNext(int propertyIndex) { + if (mutableNext == null) { + return null; + } + final MutableValueNext next = mutableNext[propertyIndex]; + mutableInfo(propertyIndex, next.info()); + return next.content(); + } + } diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java b/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java index de8cbee6d..0f9c223aa 100644 --- a/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java +++ b/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java @@ -12,12 +12,15 @@ package io.ebean.bean; public interface MutableValueInfo { /** - * Compares the given json to an internal value. Can be a hash/checksum comparison - * or a plain JSON string comparison (based on {@code @DbJson(keepSource)}). + * Compares the given json returning null if deemed unchanged or returning + * the MutableValueNext to use if deemed dirty/changed. + *

+ * Returning MutableValueNext allows an implementation based on hash/checksum + * to only perform that computation once. * - * @return true if the value is considered unchanged (when comparing in json form). + * @return Null if deemed unchanged or the MutableValueNext if deemed changed. */ - boolean isEqualToJson(String json); + MutableValueNext nextDirty(String json); /** * Compares the given object to an internal value. diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableValueNext.java b/ebean-api/src/main/java/io/ebean/bean/MutableValueNext.java new file mode 100644 index 000000000..401d3c223 --- /dev/null +++ b/ebean-api/src/main/java/io/ebean/bean/MutableValueNext.java @@ -0,0 +1,17 @@ +package io.ebean.bean; + +/** + * Represents a next value to use for mutable content properties (DbJson with jackson beans). + */ +public interface MutableValueNext { + + /** + * Return the next content to use. Provided such that we serialise to json once. + */ + String content(); + + /** + * Return the next MutableValueInfo to use after an update. + */ + MutableValueInfo info(); +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index fca7b790b..d3a683e48 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -2,6 +2,7 @@ package io.ebeaninternal.server.deploy; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; +import io.ebean.bean.MutableValueNext; import io.ebean.bean.MutableValueInfo; import io.ebean.core.type.DataReader; import io.ebean.core.type.ScalarType; @@ -36,6 +37,19 @@ public class BeanPropertyJsonMapper extends BeanProperty { } } + /** + * Next when no prior MutableValueInfo. + */ + private MutableValueNext next(String json) { + if (keepSource) { + return new SourceMutableValue(scalarType, json); + } else if (dirtyDetection) { + return new NextPair(json, new ChecksumMutableValue(scalarType, json)); + } else { + throw new IllegalStateException("Never get here"); + } + } + /** * Return true if the mutable value is considered dirty. * This is only used for 'mutable' scalar types like hstore etc. @@ -43,10 +57,17 @@ public class BeanPropertyJsonMapper extends BeanProperty { @Override boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { // dirty detection based on json content or checksum of json content + // only perform serialisation to json once final String json = scalarType.format(value); final MutableValueInfo oldHash = ebi.mutableInfo(propertyIndex); - if (oldHash == null || !oldHash.isEqualToJson(json)) { - ebi.mutableContent(propertyIndex, json); // so we only convert to json once + if (oldHash == null) { + ebi.mutableNext(propertyIndex, next(json)); + return true; + } + // only perform compute of checksum/hash once (if checksum based) + final MutableValueNext next = oldHash.nextDirty(json); + if (next != null) { + ebi.mutableNext(propertyIndex, next); return true; } return false; @@ -72,34 +93,59 @@ public class BeanPropertyJsonMapper extends BeanProperty { } } + private static final class NextPair implements MutableValueNext { + + private final String json; + private final MutableValueInfo next; + + NextPair(String json, MutableValueInfo next) { + this.json = json; + this.next = next; + } + + @Override + public String content() { + return json; + } + + @Override + public MutableValueInfo info() { + return next; + } + } + /** - * Hold checksum of json source content. + * Hold checksum of json source content to use for dirty detection. *

- * Dirty detection based on checksum difference on json form. * Does not support rebuilding 'oldValue' as no original json content. */ - private static class ChecksumMutableValue implements MutableValueInfo { + private static final class ChecksumMutableValue implements MutableValueInfo { private final ScalarType parent; private final long checksum; ChecksumMutableValue(ScalarType parent, String json) { this.parent = parent; - this.checksum = checksum(json); + this.checksum = Checksum.checksum(json); } - private long checksum(String json) { - return Checksum.checksum(json); + /** + * Create with pre-computed checksum. + */ + ChecksumMutableValue(ScalarType parent, long checksum) { + this.parent = parent; + this.checksum = checksum; + } + + @Override + public MutableValueNext nextDirty(String json) { + final long nextChecksum = Checksum.checksum(json); + return nextChecksum == checksum ? null : new NextPair(json, new ChecksumMutableValue(parent, nextChecksum)); } @Override public boolean isEqualToObject(Object obj) { - return isEqualToJson(parent.format(obj)); - } - - @Override - public boolean isEqualToJson(String json) { - return checksum(json) == checksum; + return Checksum.checksum(parent.format(obj)) == checksum; } @Override @@ -109,9 +155,9 @@ public class BeanPropertyJsonMapper extends BeanProperty { } /** - * Hold original json source content. This supports rebuilding the 'oldValue'. + * Hold json source content. This supports rebuilding the 'oldValue'. */ - private static class SourceMutableValue implements MutableValueInfo { + private static final class SourceMutableValue implements MutableValueInfo, MutableValueNext { private final String originalJson; private final ScalarType parent; @@ -122,13 +168,13 @@ public class BeanPropertyJsonMapper extends BeanProperty { } @Override - public boolean isEqualToObject(Object obj) { - return isEqualToJson(parent.format(obj)); + public MutableValueNext nextDirty(String json) { + return Objects.equals(originalJson, json) ? null : new SourceMutableValue(parent, json); } @Override - public boolean isEqualToJson(String json) { - return Objects.equals(originalJson, json); + public boolean isEqualToObject(Object obj) { + return Objects.equals(originalJson, parent.format(obj)); } @Override @@ -136,16 +182,26 @@ public class BeanPropertyJsonMapper extends BeanProperty { // rebuild the 'oldValue' for change log etc return parent.parse(originalJson); } + + @Override + public String content() { + return originalJson; + } + + @Override + public MutableValueInfo info() { + return this; + } } /** * No dirty detection on json content. */ - private static class NoDirtyDetection implements MutableValueInfo { + private static final class NoDirtyDetection implements MutableValueInfo { @Override - public boolean isEqualToJson(String json) { - return true; // treat as not dirty + public MutableValueNext nextDirty(String json) { + return null; // treat as not dirty } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java index 5a94d0e0e..cfa056a63 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java @@ -1,7 +1,6 @@ package io.ebeaninternal.server.persist.dmlbind; import io.ebean.bean.EntityBean; -import io.ebean.bean.MutableValueInfo; import io.ebeaninternal.server.deploy.BeanProperty; import java.sql.SQLException; @@ -26,11 +25,8 @@ class BindablePropertyJsonUpdate extends BindableProperty { if (bean == null) { request.bind(null, prop); } else { - // on update store hash and push json - final String json = bean._ebean_getIntercept().mutableContent(propertyIndex); - final MutableValueInfo hash = prop.createMutableInfo(json); - bean._ebean_getIntercept().mutableInfo(propertyIndex, hash); - request.pushJson(json); + // update mutableInfo and push json + request.pushJson(bean._ebean_getIntercept().mutableNext(propertyIndex)); request.bind(prop.getValue(bean), prop); } } From 5aa8557168add6acf9bc7d016dc30eddb57c2e25 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 16:29:10 +1200 Subject: [PATCH 020/120] Update tests only - TestJacksonPlainBean with dirtyDetection = false property --- .../org/tests/model/json/EBasicPlain.java | 11 ++++++++ .../model/json/TestJacksonPlainBean.java | 26 ++++++++++--------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java b/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java index f3705aa16..401e66fa1 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java @@ -17,6 +17,9 @@ public class EBasicPlain { @DbJson(length = 500) PlainBean plainBean; + @DbJson(length = 500, dirtyDetection = false) + PlainBean plainBean2; + @Version long version; @@ -44,6 +47,14 @@ public class EBasicPlain { this.plainBean = plainBean; } + public PlainBean getPlainBean2() { + return plainBean2; + } + + public void setPlainBean2(PlainBean plainBean2) { + this.plainBean2 = plainBean2; + } + public long getVersion() { return version; } diff --git a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java index 0e3d22aa7..f77f2f8b6 100644 --- a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java +++ b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java @@ -16,25 +16,20 @@ public class TestJacksonPlainBean { DB.getDefault(); LoggedSqlCollector.start(); - PlainBean content = new PlainBean(); - content.setAlong(42); - content.setName("foo"); - + PlainBean content = new PlainBean("foo", 42); EBasicPlain bean = new EBasicPlain(); bean.setAttr("attr0"); bean.setPlainBean(content); - + bean.setPlainBean2(new PlainBean("bar", 27)); DB.save(bean); - expectedSql(0, "insert into ebasic_plain (attr, plain_bean, version) values (?,?,?)"); - + expectedSql(0, "insert into ebasic_plain (attr, plain_bean, plain_bean2, version) values (?,?,?,?)"); // inserted plainBean has not been mutated bean.setAttr("attr1"); DB.save(bean); expectedSql(0, "update ebasic_plain set attr=?, version=? where id=? and version=?"); - // inserted plainBean has now been mutated content.setName("notFoo"); bean.setAttr("attr2"); @@ -50,17 +45,24 @@ public class TestJacksonPlainBean { DB.save(found); expectedSql(1, "update ebasic_plain set plain_bean=?, version=? where id=? and version=?"); - - // update bean, mutate PlainBean only + // dirtyDetection = false, so not included in update + found.getPlainBean2().setName("Modification Ignored"); + // dirtyDetection = true, mutation detected plainBean.setName("mod2"); DB.save(found); expectedSql(0, "update ebasic_plain set plain_bean=?, version=? where id=? and version=?"); - // update bean, not mutating PlainBean found.setAttr("attr3"); DB.save(found); - expectedSql(LoggedSqlCollector.stop(), 0, "update ebasic_plain set attr=?, version=? where id=? and version=?"); + expectedSql(0, "update ebasic_plain set attr=?, version=? where id=? and version=?"); + + // dirtyDetection = false, set a new plainBean2 instance, included in update + found.setPlainBean2(new PlainBean("bar", 27)); + DB.save(found); + expectedSql( 0, "update ebasic_plain set plain_bean2=?, version=? where id=? and version=?"); + + LoggedSqlCollector.stop(); } private void expectedSql(int i, String s) { From 20becf951d02754f4003cb88a1b5aa1ea522de3c Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 23:11:42 +1200 Subject: [PATCH 021/120] Use MutationDetection replacing dirtyDetection and keepSource Also adds NoMutationDetection to support NONE --- ebean-api/pom.xml | 2 +- .../server/deploy/BeanPropertyJsonMapper.java | 46 ++++++------------- .../deploy/meta/DeployBeanProperty.java | 39 ++++------------ .../deploy/meta/DeployBeanPropertyLists.java | 42 ++--------------- .../server/deploy/parse/DeployUtil.java | 16 +++---- .../server/type/DefaultTypeManager.java | 3 +- .../type/ScalarTypeJsonObjectMapper.java | 35 +++++++++++++- .../org/tests/model/json/EBasicJsonList.java | 11 ++--- .../org/tests/model/json/EBasicPlain.java | 4 +- .../model/json/TestJacksonPlainBean.java | 5 +- 10 files changed, 76 insertions(+), 127 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 649f85822..503c2f2c5 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -50,7 +50,7 @@ io.ebean ebean-annotation - 7.1 + 7.2 diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index d3a683e48..f1efc39f7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -1,9 +1,10 @@ package io.ebeaninternal.server.deploy; +import io.ebean.annotation.MutationDetection; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; -import io.ebean.bean.MutableValueNext; import io.ebean.bean.MutableValueInfo; +import io.ebean.bean.MutableValueNext; import io.ebean.core.type.DataReader; import io.ebean.core.type.ScalarType; import io.ebean.text.TextException; @@ -14,26 +15,24 @@ import javax.persistence.PersistenceException; import java.sql.SQLException; import java.util.Objects; +/** + * Handle json property with MutationDetection of SOURCE or HASH only. + */ public class BeanPropertyJsonMapper extends BeanProperty { - private static final NoDirtyDetection NO_DIRTY_DETECTION = new NoDirtyDetection(); - private final boolean dirtyDetection; - private final boolean keepSource; + private final boolean sourceDetection; public BeanPropertyJsonMapper(BeanDescriptor desc, DeployBeanProperty deployProp) { super(desc, deployProp); - this.dirtyDetection = deployProp.isDirtyDetection(); - this.keepSource = deployProp.isKeepSource(); + this.sourceDetection = deployProp.getMutationDetection() == MutationDetection.SOURCE; } @Override public MutableValueInfo createMutableInfo(String json) { - if (keepSource) { + if (sourceDetection) { return new SourceMutableValue(scalarType, json); - } else if (dirtyDetection) { - return new ChecksumMutableValue(scalarType, json); } else { - return NO_DIRTY_DETECTION; + return new ChecksumMutableValue(scalarType, json); } } @@ -41,22 +40,19 @@ public class BeanPropertyJsonMapper extends BeanProperty { * Next when no prior MutableValueInfo. */ private MutableValueNext next(String json) { - if (keepSource) { + if (sourceDetection) { return new SourceMutableValue(scalarType, json); - } else if (dirtyDetection) { - return new NextPair(json, new ChecksumMutableValue(scalarType, json)); } else { - throw new IllegalStateException("Never get here"); + return new NextPair(json, new ChecksumMutableValue(scalarType, json)); } } /** - * Return true if the mutable value is considered dirty. - * This is only used for 'mutable' scalar types like hstore etc. + * Return true if the json property is considered dirty. */ @Override boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { - // dirty detection based on json content or checksum of json content + // mutation detection based on json content or checksum of json content // only perform serialisation to json once final String json = scalarType.format(value); final MutableValueInfo oldHash = ebi.mutableInfo(propertyIndex); @@ -193,20 +189,4 @@ public class BeanPropertyJsonMapper extends BeanProperty { return this; } } - - /** - * No dirty detection on json content. - */ - private static final class NoDirtyDetection implements MutableValueInfo { - - @Override - public MutableValueNext nextDirty(String json) { - return null; // treat as not dirty - } - - @Override - public boolean isEqualToObject(Object obj) { - return true; // treat as not dirty - } - } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java index 060ce802f..3da06d559 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java @@ -1,18 +1,6 @@ package io.ebeaninternal.server.deploy.meta; -import io.ebean.annotation.CreatedTimestamp; -import io.ebean.annotation.DocCode; -import io.ebean.annotation.DocProperty; -import io.ebean.annotation.DocSortable; -import io.ebean.annotation.Formula; -import io.ebean.annotation.Platform; -import io.ebean.annotation.SoftDelete; -import io.ebean.annotation.UpdatedTimestamp; -import io.ebean.annotation.WhenCreated; -import io.ebean.annotation.WhenModified; -import io.ebean.annotation.Where; -import io.ebean.annotation.WhoCreated; -import io.ebean.annotation.WhoModified; +import io.ebean.annotation.*; import io.ebean.config.ScalarTypeConverter; import io.ebean.config.dbplatform.DbDefaultValue; import io.ebean.config.dbplatform.DbEncrypt; @@ -39,7 +27,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Type; import java.sql.Types; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -109,8 +96,7 @@ public class DeployBeanProperty { private boolean jsonSerialize = true; private boolean jsonDeserialize = true; - private boolean dirtyDetection; - private boolean keepSource; + private MutationDetection mutationDetection; private boolean dbEncrypted; private DbEncryptFunction dbEncryptFunction; @@ -329,18 +315,15 @@ public class DeployBeanProperty { this.jsonDeserialize = jsonDeserialize; } - /** - * Return true if we should have JSON dirty detection on this property. - */ - public boolean isDirtyDetection() { - return dirtyDetection; + public MutationDetection getMutationDetection() { + if (mutationDetection == null) { + mutationDetection = MutationDetection.DEFAULT; + } + return mutationDetection; } - /** - * Return true if we should store source JSON content on this property. - */ - public boolean isKeepSource() { - return keepSource; + public void setMutationDetection(MutationDetection dirtyDetection) { + this.mutationDetection = dirtyDetection; } /** @@ -1221,8 +1204,4 @@ public class DeployBeanProperty { return scalarType != null && scalarType.isJsonMapper(); } - public void setJsonOptions(boolean dirtyDetection, boolean keepSource) { - this.dirtyDetection = dirtyDetection; - this.keepSource = keepSource; - } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java index 9843f8e5c..90503c93f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java @@ -22,47 +22,28 @@ public class DeployBeanPropertyLists { private static final NoopSetter NOOP_SETTER = new NoopSetter(); private BeanProperty versionProperty; - private BeanProperty unmappedJson; - private BeanProperty draft; - private BeanProperty draftDirty; - private BeanProperty tenant; - private final BeanDescriptor desc; - private final LinkedHashMap propertyMap; - private BeanProperty id; private final List local = new ArrayList<>(); - private final List mutable = new ArrayList<>(); - private final List> manys = new ArrayList<>(); - private final List nonManys = new ArrayList<>(); - private final List aggs = new ArrayList<>(); - private final List> ones = new ArrayList<>(); - private final List> onesImported = new ArrayList<>(); - private final List> embedded = new ArrayList<>(); - private final List baseScalar = new ArrayList<>(); - private final List transients = new ArrayList<>(); - private final List nonTransients = new ArrayList<>(); - private final BeanPropertyAssocOne unidirectional; private final BeanProperty orderColumn; - @SuppressWarnings({"unchecked"}) public DeployBeanPropertyLists(BeanDescriptorMap owner, BeanDescriptor desc, DeployBeanDescriptor deploy) { this.desc = desc; @@ -78,7 +59,7 @@ public class DeployBeanPropertyLists { this.orderColumn = deployOrderColumn != null ? new BeanPropertyOrderColumn(desc, deployOrderColumn) : null; DeployBeanPropertyAssocOne deployUnidirectional = deploy.getUnidirectional(); - this.unidirectional = deployUnidirectional == null ? null : new BeanPropertyAssocOne(owner, desc, deployUnidirectional); + this.unidirectional = deployUnidirectional == null ? null : new BeanPropertyAssocOne<>(owner, desc, deployUnidirectional); this.propertyMap = new LinkedHashMap<>(); @@ -119,7 +100,7 @@ public class DeployBeanPropertyLists { } if (orderColumn != null) { - orderColumn.setDeployOrder(order++); + orderColumn.setDeployOrder(order); allocateToList(orderColumn); propertyMap.put(orderColumn.getName(), orderColumn); } @@ -146,7 +127,6 @@ public class DeployBeanPropertyLists { } private void setImportedPrimaryKeysFor(DeployBeanDescriptor deploy, DeployBeanPropertyAssocOne id) { - for (DeployBeanProperty prop : id.getTargetDeploy().properties()) { DeployBeanProperty match = findImported(deploy, prop); if (match != null) { @@ -156,7 +136,6 @@ public class DeployBeanPropertyLists { } private DeployBeanProperty findImported(DeployBeanDescriptor deploy, DeployBeanProperty embeddedScalar) { - // the logical name and db column we are looking for a match on String name = embeddedScalar.getName(); String dbColumn = embeddedScalar.getDbColumn(); @@ -172,7 +151,6 @@ public class DeployBeanPropertyLists { return assocOne; } } - return null; } @@ -360,7 +338,6 @@ public class DeployBeanPropertyLists { } public BeanProperty getSoftDeleteProperty() { - for (BeanProperty prop : nonManys) { if (prop.isSoftDelete()) { return prop; @@ -377,7 +354,6 @@ public class DeployBeanPropertyLists { * Return the properties set via generated values on insert. */ public BeanProperty[] getGeneratedInsert() { - List list = new ArrayList<>(); for (BeanProperty prop : nonTransients) { GeneratedProperty gen = prop.getGeneratedProperty(); @@ -392,7 +368,6 @@ public class DeployBeanPropertyLists { * Return the properties set via generated values on update. */ public BeanProperty[] getGeneratedUpdate() { - List list = new ArrayList<>(); for (BeanProperty prop : nonTransients) { GeneratedProperty gen = prop.getGeneratedProperty(); @@ -430,8 +405,7 @@ public class DeployBeanPropertyLists { } } } - - return (BeanPropertyAssocOne[]) list.toArray(new BeanPropertyAssocOne[0]); + return list.toArray(new BeanPropertyAssocOne[0]); } private BeanPropertyAssocMany[] getMany2Many() { @@ -441,8 +415,7 @@ public class DeployBeanPropertyLists { list.add(prop); } } - - return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[0]); + return list.toArray(new BeanPropertyAssocMany[0]); } private BeanPropertyAssocMany[] getMany(Mode mode) { @@ -463,25 +436,20 @@ public class DeployBeanPropertyLists { break; } } - - return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[0]); + return list.toArray(new BeanPropertyAssocMany[0]); } @SuppressWarnings({"unchecked", "rawtypes"}) private BeanProperty createBeanProperty(BeanDescriptorMap owner, DeployBeanProperty deployProp) { - if (deployProp instanceof DeployBeanPropertyAssocOne) { return new BeanPropertyAssocOne(owner, desc, (DeployBeanPropertyAssocOne) deployProp); } - if (deployProp instanceof DeployBeanPropertySimpleCollection) { return new BeanPropertySimpleCollection(desc, (DeployBeanPropertySimpleCollection) deployProp); } - if (deployProp instanceof DeployBeanPropertyAssocMany) { return new BeanPropertyAssocMany(desc, (DeployBeanPropertyAssocMany) deployProp); } - if (deployProp.isJsonMapper()) { return new BeanPropertyJsonMapper(desc, deployProp); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java index 2245b0c4c..0792c66d5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java @@ -1,10 +1,6 @@ package io.ebeaninternal.server.deploy.parse; -import io.ebean.annotation.DbArray; -import io.ebean.annotation.DbJson; -import io.ebean.annotation.DbJsonB; -import io.ebean.annotation.DbJsonType; -import io.ebean.annotation.DbMap; +import io.ebean.annotation.*; import io.ebean.config.DatabaseConfig; import io.ebean.config.EncryptDeploy; import io.ebean.config.EncryptDeployManager; @@ -214,21 +210,21 @@ public class DeployUtil { */ void setDbJsonType(DeployBeanProperty prop, DbJson dbJsonType) { int dbType = getDbJsonStorage(dbJsonType.storage()); - setDbJsonType(prop, dbType, dbJsonType.length(), dbJsonType.dirtyDetection(), dbJsonType.keepSource()); + setDbJsonType(prop, dbType, dbJsonType.length(), dbJsonType.mutationDetection()); } void setDbJsonBType(DeployBeanProperty prop, DbJsonB dbJsonB) { - setDbJsonType(prop, DbPlatformType.JSONB, dbJsonB.length(), dbJsonB.dirtyDetection(), dbJsonB.keepSource()); + setDbJsonType(prop, DbPlatformType.JSONB, dbJsonB.length(), dbJsonB.mutationDetection()); } - private void setDbJsonType(DeployBeanProperty prop, int dbType, int dbLength, boolean dirtyDetection, boolean keepSource) { + private void setDbJsonType(DeployBeanProperty prop, int dbType, int dbLength, MutationDetection mutationDetection) { + prop.setDbType(dbType); + prop.setMutationDetection(mutationDetection); ScalarType scalarType = typeManager.getJsonScalarType(prop, dbType, dbLength); if (scalarType == null) { throw new RuntimeException("No ScalarType for JSON property [" + prop + "] [" + dbType + "]"); } - prop.setDbType(dbType); prop.setScalarType(scalarType); - prop.setJsonOptions(dirtyDetection, keepSource); if (dbType == Types.VARCHAR || dbLength > 0) { // determine the db column size int columnLength = (dbLength > 0) ? dbLength : DEFAULT_JSON_VARCHAR_LENGTH; 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 befe46b20..28999e838 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 @@ -2,7 +2,6 @@ package io.ebeaninternal.server.type; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.introspect.AnnotatedField; import io.ebean.annotation.*; import io.ebean.config.DatabaseConfig; import io.ebean.config.JsonConfig; @@ -426,7 +425,7 @@ public final class DefaultTypeManager implements TypeManager { if (objectMapper == null) { throw new IllegalArgumentException("Type [" + type + "] unsupported for @DbJson mapping - Jackson ObjectMapper not present"); } - return ScalarTypeJsonObjectMapper.createTypeFor(jsonManager, (AnnotatedField) prop.getJacksonField(), dbType, docType); + return ScalarTypeJsonObjectMapper.createTypeFor(jsonManager, prop, dbType, docType); } /** 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 14425c6c9..7fb3aa4b4 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 @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.introspect.AnnotatedField; +import io.ebean.annotation.MutationDetection; import io.ebean.core.type.DataBinder; import io.ebean.core.type.DataReader; import io.ebean.core.type.DocPropertyType; @@ -15,6 +16,7 @@ import io.ebean.text.TextException; import io.ebeaninternal.json.ModifyAwareList; import io.ebeaninternal.json.ModifyAwareMap; import io.ebeaninternal.json.ModifyAwareSet; +import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; import javax.persistence.PersistenceException; import java.io.DataInput; @@ -34,8 +36,16 @@ class ScalarTypeJsonObjectMapper { /** * Create and return the appropriate ScalarType. */ - static ScalarType createTypeFor(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) { + static ScalarType createTypeFor(TypeJsonManager jsonManager, DeployBeanProperty prop, int dbType, DocPropertyType docType) { + AnnotatedField field = (AnnotatedField) prop.getJacksonField(); Class type = field.getRawType(); + + MutationDetection mode = prop.getMutationDetection(); + if (mode == MutationDetection.NONE) { + return new NoMutationDetection(jsonManager, field, dbType, type); + } else if (mode != MutationDetection.DEFAULT) { + return new GenericObject(jsonManager, field, dbType, type); + } if (Set.class.equals(type)) { return new OmSet(jsonManager, field, dbType, docType); } @@ -45,11 +55,32 @@ class ScalarTypeJsonObjectMapper { if (Map.class.equals(type)) { return new OmMap(jsonManager, field, dbType); } + prop.setMutationDetection(MutationDetection.HASH); return new GenericObject(jsonManager, field, dbType, type); } /** - * Maps any type (Object) using Jackson ObjectMapper. + * No mutation detection on this json property. + */ + private static class NoMutationDetection extends Base { + + NoMutationDetection(TypeJsonManager jsonManager, AnnotatedField field, int dbType, Class rawType) { + super(Object.class, jsonManager, field, dbType, DocPropertyType.OBJECT, rawType); + } + + @Override + public boolean isMutable() { + return false; + } + + @Override + public boolean isDirty(Object value) { + return false; + } + } + + /** + * Supports HASH and SOURCE dirty detection modes. */ private static class GenericObject extends Base { diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java index 05d9807b5..d5ce2c309 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java @@ -7,12 +7,9 @@ import io.ebean.annotation.DbJsonType; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Version; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; + +import static io.ebean.annotation.MutationDetection.SOURCE; @Entity public class EBasicJsonList { @@ -31,7 +28,7 @@ public class EBasicJsonList { @DbJson(length = 700) Map beanMap = new LinkedHashMap<>(); - @DbJson(length = 500, keepSource = true) // such that we can rebuild old values + @DbJson(length = 500, mutationDetection = SOURCE) // such that we can rebuild old values PlainBean plainBean; @DbJson(length = 50) diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java b/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java index 401e66fa1..051b4a344 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicPlain.java @@ -6,6 +6,8 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Version; +import static io.ebean.annotation.MutationDetection.NONE; + @Entity public class EBasicPlain { @@ -17,7 +19,7 @@ public class EBasicPlain { @DbJson(length = 500) PlainBean plainBean; - @DbJson(length = 500, dirtyDetection = false) + @DbJson(length = 500, mutationDetection = NONE) // only update when property set PlainBean plainBean2; @Version diff --git a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java index f77f2f8b6..c0fe82b26 100644 --- a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java +++ b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java @@ -60,7 +60,7 @@ public class TestJacksonPlainBean { // dirtyDetection = false, set a new plainBean2 instance, included in update found.setPlainBean2(new PlainBean("bar", 27)); DB.save(found); - expectedSql( 0, "update ebasic_plain set plain_bean2=?, version=? where id=? and version=?"); + expectedSql(0, "update ebasic_plain set plain_bean2=?, version=? where id=? and version=?"); LoggedSqlCollector.stop(); } @@ -69,7 +69,4 @@ public class TestJacksonPlainBean { assertThat(LoggedSqlCollector.current().get(i)).contains(s); } - private void expectedSql(List sql, int i, String s) { - assertThat(sql.get(i)).contains(s); - } } From 20e0eb102193d4b7f69f4fd45295e345055ca013 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 23:17:11 +1200 Subject: [PATCH 022/120] Re-enable TestDbJson_Jackson3 via adding mutationDetection = HASH to beanList property @DbJsonB(mutationDetection = HASH) List beanList; --- .../src/test/java/org/tests/json/TestDbJson_Jackson3.java | 7 ++----- .../src/test/java/org/tests/model/json/EBasicJsonList.java | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index e8d8abdfd..2f74be109 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -161,10 +161,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase { final EBasicJsonList found = DB.find(EBasicJsonList.class, bean.getId()); found.getBeanList().get(0).setName("p1-mod"); -// BeanState state = DB.getBeanState(found); -// assertThat(state.getChangedProps()).containsExactlyInAnyOrder("beanList"); - // this test fails, because we have a OmList instead of a GenericObject - // TODO: Can/Should we enhance the @DbJson/@DbJsonB annotations with a property "dirtyDetection" - + BeanState state = DB.getBeanState(found); + assertThat(state.getChangedProps()).containsExactlyInAnyOrder("beanList"); } } diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java index d5ce2c309..f76d282f7 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java @@ -9,6 +9,7 @@ import javax.persistence.Id; import javax.persistence.Version; import java.util.*; +import static io.ebean.annotation.MutationDetection.HASH; import static io.ebean.annotation.MutationDetection.SOURCE; @Entity @@ -22,7 +23,7 @@ public class EBasicJsonList { @DbJson(length = 700, name = "beans") Set beanSet; - @DbJsonB + @DbJsonB(mutationDetection = HASH) List beanList; @DbJson(length = 700) From 822fb7325a244abf3a390ed59bf9ca2ce755a7c8 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 29 Jul 2021 23:37:29 +1200 Subject: [PATCH 023/120] Due to mutableNext handling, with checkMutableProperties() even when known dirty go into beanProperty.checkMutable() As per rPraml's PR and comment Due to handling of mutableNext we need checkMutableProperties() to call into what is now beanProperty.checkMutable() even when we already know it's dirty. --- .../java/io/ebeaninternal/server/deploy/BeanDescriptor.java | 4 ++-- .../java/io/ebeaninternal/server/deploy/BeanProperty.java | 4 ++-- .../ebeaninternal/server/deploy/BeanPropertyJsonMapper.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index d165b1489..8f0fea0f2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -3198,9 +3198,9 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { public void checkMutableProperties(EntityBeanIntercept ebi) { for (BeanProperty beanProperty : propertiesMutable) { int propertyIndex = beanProperty.getPropertyIndex(); - if (!ebi.isDirtyProperty(propertyIndex) && ebi.isLoadedProperty(propertyIndex)) { + if (ebi.isLoadedProperty(propertyIndex)) { Object value = beanProperty.getValue(ebi.getOwner()); - if (value != null && beanProperty.isDirtyValue(value, ebi)) { + if (beanProperty.checkMutable(value, ebi.isDirtyProperty(propertyIndex), ebi)) { // mutable scalar value which is considered dirty so mark // it as such so that it is included in an update ebi.markPropertyAsChanged(propertyIndex); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index fc5a8364f..a33d183ea 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -1018,8 +1018,8 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { * Return true if the mutable value is considered dirty. * This is only used for 'mutable' scalar types like hstore etc. */ - boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { - return scalarType.isDirty(value); + boolean checkMutable(Object value, boolean alreadyDirty, EntityBeanIntercept ebi) { + return alreadyDirty || value != null && scalarType.isDirty(value); } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index f1efc39f7..c9280c8c0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -51,7 +51,7 @@ public class BeanPropertyJsonMapper extends BeanProperty { * Return true if the json property is considered dirty. */ @Override - boolean isDirtyValue(Object value, EntityBeanIntercept ebi) { + boolean checkMutable(Object value, boolean alreadyDirty, EntityBeanIntercept ebi) { // mutation detection based on json content or checksum of json content // only perform serialisation to json once final String json = scalarType.format(value); From 1fad6e910c5f38d58590d5b4afff313f43bfccb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20P=C3=B6hler=20=28JPo=29?= Date: Fri, 19 Mar 2021 15:40:21 +0100 Subject: [PATCH 024/120] FIX: do not override empty (json) collections with null MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original: https://github.com/ebean-orm/ebean/commit/5551c35ec2496a9d62ab0afcaecbed739f17aa7c Signed-off-by: Jonas Pöhler (JPo) --- .../server/query/SqlBeanLoad.java | 18 ++++++++++++------ .../java/org/tests/json/TestDbJson_List.java | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java index ac1386e11..c1119e525 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java @@ -6,6 +6,9 @@ import io.ebeaninternal.api.SpiQuery.Mode; import io.ebeaninternal.server.deploy.BeanProperty; import io.ebeaninternal.server.deploy.DbReadContext; +import java.util.Collection; +import java.util.Map; + /** * Controls the loading of property data into a bean. *

@@ -70,12 +73,7 @@ public class SqlBeanLoad { try { Object dbVal = prop.read(ctx); - if (!refreshLoading) { - prop.setValue(bean, dbVal); - } else { - prop.setValueIntercept(bean, dbVal); - } - + load(prop, dbVal); return dbVal; } catch (Exception e) { @@ -89,6 +87,14 @@ public class SqlBeanLoad { * Load the given value into the property. */ public void load(BeanProperty target, Object dbVal) { + if (dbVal == null) { + Object current = target.getValue(bean); + if ((current instanceof Collection && ((Collection) current).isEmpty()) + || current instanceof Map && ((Map) current).isEmpty()) { + dbVal = current; // do not modify + } + } + if (!refreshLoading) { target.setValue(bean, dbVal); } else { diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java index 28fd78221..d00bb3541 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java @@ -221,4 +221,18 @@ public class TestDbJson_List extends BaseTestCase { DB.delete(bean); } + + @Test + public void testNullToEmpty() { + EBasicJsonList bean = new EBasicJsonList(); + bean.setFlags(null); + bean.setTags(null); + bean.setBeanMap(null); + DB.save(bean); + + bean = DB.find(EBasicJsonList.class) + .setId(bean.getId()).findOne(); + + assertThat(bean.getFlags()).isEmpty(); + } } From 1f0ac1f1c12ea54b8738f284061a9f27e7c196bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20P=C3=B6hler?= Date: Thu, 29 Jul 2021 16:50:08 +0200 Subject: [PATCH 025/120] ADD: Testcases for List and Map as well --- ebean-core/src/test/java/org/tests/json/TestDbJson_List.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java index d00bb3541..e2d04b657 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java @@ -234,5 +234,7 @@ public class TestDbJson_List extends BaseTestCase { .setId(bean.getId()).findOne(); assertThat(bean.getFlags()).isEmpty(); + assertThat(bean.getTags()).isEmpty(); + assertThat(bean.getBeanMap()).isEmpty(); } } From 777d3222220a5bda2c7fd5ffac730c9985d61614 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 14:51:38 +1200 Subject: [PATCH 026/120] #2279 - Remove _ebean_getMarker() from EntityBean interface - not actually required --- ebean-api/src/main/java/io/ebean/bean/EntityBean.java | 11 ----------- .../server/deploy/ElementEntityBean.java | 5 ----- ebean-core/src/test/resources/ebean.mf | 1 + 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBean.java b/ebean-api/src/main/java/io/ebean/bean/EntityBean.java index 03d1195c8..ee54991ad 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBean.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBean.java @@ -27,17 +27,6 @@ public interface EntityBean extends Serializable { throw new NotEnhancedException(); } - /** - * Return the enhancement marker value. - *

- * This is the class name of the enhanced class and used to check that all - * entity classes are enhanced (specifically not just a super class). - *

- */ - default String _ebean_getMarker() { - throw new NotEnhancedException(); - } - /** * Create and return a new entity bean instance. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementEntityBean.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementEntityBean.java index 366ba5a97..49dfccdc8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementEntityBean.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementEntityBean.java @@ -28,11 +28,6 @@ class ElementEntityBean implements EntityBean { return properties[pos]; } - @Override - public String _ebean_getMarker() { - return null; - } - @Override public Object _ebean_newInstance() { return new ElementEntityBean(properties); diff --git a/ebean-core/src/test/resources/ebean.mf b/ebean-core/src/test/resources/ebean.mf index c18791604..7d34f1de5 100644 --- a/ebean-core/src/test/resources/ebean.mf +++ b/ebean-core/src/test/resources/ebean.mf @@ -3,4 +3,5 @@ profile-location: true entity-packages: org,misc transactional-packages: org querybean-packages: none +synthetic: false From a4708770175ef160426d8dd479a9f924656e2301 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 14:52:49 +1200 Subject: [PATCH 027/120] Update kotlin-querybean-generator pom to make kotlin in IntelliJ happy --- kotlin-querybean-generator/pom.xml | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml index 9b257b3b3..c3a487ecf 100644 --- a/kotlin-querybean-generator/pom.xml +++ b/kotlin-querybean-generator/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 ebean-parent @@ -12,7 +13,7 @@ kotlin-querybean-generator - 1.5.0 + 1.5.30-M1 @@ -51,7 +52,7 @@ org.jetbrains.kotlin kotlin-stdlib-jdk8 ${kotlin.version} - test + provided @@ -111,10 +112,23 @@ + + compile + compile + + compile + + + + src/main/java + target/generated-sources/kapt/test + target/generated-sources/kaptKotlin/test + + + 1.8 - @@ -133,6 +147,13 @@ testCompile + + compile + compile + + compile + + 1.8 From 03004452ac7e0dc08c897e1807139e976bc5f9fe Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 14:53:32 +1200 Subject: [PATCH 028/120] ebean.mf set back to synthetic: true --- ebean-core/src/test/resources/ebean.mf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ebean-core/src/test/resources/ebean.mf b/ebean-core/src/test/resources/ebean.mf index 7d34f1de5..fc2fd6902 100644 --- a/ebean-core/src/test/resources/ebean.mf +++ b/ebean-core/src/test/resources/ebean.mf @@ -3,5 +3,5 @@ profile-location: true entity-packages: org,misc transactional-packages: org querybean-packages: none -synthetic: false +synthetic: true From c43e2e695686d861f8d4982f52f28f73bd27d99f Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 15:34:54 +1200 Subject: [PATCH 029/120] Update TestDbJson_Jackson3 --- .../org/tests/json/TestDbJson_Jackson3.java | 62 +++++++++++++++++++ .../tests/model/json/EBasicJsonJackson3.java | 21 ++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index 2f74be109..145790457 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -164,4 +164,66 @@ public class TestDbJson_Jackson3 extends BaseTestCase { BeanState state = DB.getBeanState(found); assertThat(state.getChangedProps()).containsExactlyInAnyOrder("beanList"); } + + @Test + public void update_with_differentDbJsonSettings() { + PlainBeanDirtyAware contentBean1 = new PlainBeanDirtyAware("x", 42); + PlainBeanDirtyAware contentBean2 = new PlainBeanDirtyAware("y", 43); + PlainBeanDirtyAware contentBean3 = new PlainBeanDirtyAware("z", 44); + + EBasicJsonJackson3 bean = new EBasicJsonJackson3(); + bean.setName("b1"); + bean.setPlainValue(contentBean1); + bean.setPlainValue2(contentBean2); + bean.setPlainValue3(contentBean3); + + BeanState state = DB.getBeanState(bean); + // a new bean is not considered as dirty (thus have no changed props) + assertThat(state.isDirty()).isFalse(); + assertThat(state.isNewOrDirty()).isTrue(); + assertThat(state.getChangedProps()).isEmpty(); + + bean.save(); + + bean = DB.find(EBasicJsonJackson3.class, bean.getId()); + state = DB.getBeanState(bean); + // a fresh loaded bean is also not considered as dirty + assertThat(state.isDirty()).isFalse(); + assertThat(state.isNewOrDirty()).isFalse(); + assertThat(state.getChangedProps()).isEmpty(); + + bean.getPlainValue().setName("a"); // has keepSource=true + + assertThat(state.isDirty()).isTrue(); + assertThat(state.getChangedProps()).containsExactly("plainValue"); + + bean.getPlainValue2().setName("b"); + assertThat(state.getChangedProps()).containsExactlyInAnyOrder("plainValue", "plainValue2"); + + bean.getPlainValue3().setName("c"); // has dirtyDetection = false + + Map dirtyValues = state.getDirtyValues(); + assertThat(dirtyValues).hasSize(2).containsKeys("plainValue", "plainValue2"); + + assertThat(dirtyValues.get("plainValue")).hasToString("name:a,name:x"); // SOURCE -> origValue present + assertThat(dirtyValues.get("plainValue2")).hasToString("name:b,null"); // without SOURCE no origValue present + + LoggedSql.start(); + bean.save(); + List sql = LoggedSql.collect(); + assertThat(sql.get(0)).contains("update ebasic_json_jackson3 set plain_value=?, plain_value2=?, version=? where id=?"); + + bean = DB.find(EBasicJsonJackson3.class, bean.getId()); + LoggedSql.collect(); // ignore the select + assertThat(bean.getPlainValue().getName()).isEqualTo("a"); + assertThat(bean.getPlainValue2().getName()).isEqualTo("b"); + assertThat(bean.getPlainValue3().getName()).isEqualTo("z"); // value is not updated + + bean.getPlainValue3().setName("c"); + bean.getPlainValue3().setMarkedDirty(true); // This is ignored because it is MutationDetection.NONE + bean.save(); + // no update as plainValue3 has MutationDetection.NONE (ModifyAwareType = NONE isn't an expected combination to me) + assertThat(LoggedSql.collect()).isEmpty(); + LoggedSql.stop(); + } } diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonJackson3.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonJackson3.java index 45375b516..cee12d9e7 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonJackson3.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonJackson3.java @@ -2,11 +2,15 @@ package org.tests.model.json; import io.ebean.Model; import io.ebean.annotation.DbJson; +import io.ebean.annotation.MutationDetection; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Version; +import static io.ebean.annotation.MutationDetection.NONE; +import static io.ebean.annotation.MutationDetection.SOURCE; + @Entity public class EBasicJsonJackson3 extends Model { @@ -15,12 +19,15 @@ public class EBasicJsonJackson3 extends Model { String name; - @DbJson(length = 500) + @DbJson(length = 500, mutationDetection = SOURCE) PlainBeanDirtyAware plainValue; @DbJson(length = 500) PlainBeanDirtyAware plainValue2; - + + @DbJson(length = 500, mutationDetection = NONE) + PlainBeanDirtyAware plainValue3; + @Version long version; @@ -55,7 +62,15 @@ public class EBasicJsonJackson3 extends Model { public void setPlainValue2(PlainBeanDirtyAware plainValue2) { this.plainValue2 = plainValue2; } - + + public PlainBeanDirtyAware getPlainValue3() { + return plainValue3; + } + + public void setPlainValue3(PlainBeanDirtyAware plainValue3) { + this.plainValue3 = plainValue3; + } + public long getVersion() { return version; } From ea741d01699d107f7f88fed1057c91abe2d578c4 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 15:41:52 +1200 Subject: [PATCH 030/120] Update TestDbJson_Jackson3 with comments --- .../src/test/java/org/tests/json/TestDbJson_Jackson3.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index 145790457..ac10f2a16 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -66,7 +66,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase { found.setName("b1-mod2"); found.getPlainValue().setName("b"); - found.getPlainValue().setMarkedDirty(true); + // found.getPlainValue().setMarkedDirty(true); // Irrelevant for SOURCE or HASH based mutation detection found.save(); @@ -192,7 +192,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase { assertThat(state.isNewOrDirty()).isFalse(); assertThat(state.getChangedProps()).isEmpty(); - bean.getPlainValue().setName("a"); // has keepSource=true + bean.getPlainValue().setName("a"); // has SOURCE assertThat(state.isDirty()).isTrue(); assertThat(state.getChangedProps()).containsExactly("plainValue"); @@ -200,7 +200,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase { bean.getPlainValue2().setName("b"); assertThat(state.getChangedProps()).containsExactlyInAnyOrder("plainValue", "plainValue2"); - bean.getPlainValue3().setName("c"); // has dirtyDetection = false + bean.getPlainValue3().setName("c"); // has mutationDetection = NONE Map dirtyValues = state.getDirtyValues(); assertThat(dirtyValues).hasSize(2).containsKeys("plainValue", "plainValue2"); From ca1636ff9edb0c22177875af8d5f26643ccba83c Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 17:16:05 +1200 Subject: [PATCH 031/120] Fix when json/jackson bean inserted as null and not changed Expectation is that it is not included in update (still null, no change) --- .../server/deploy/BeanPropertyJsonMapper.java | 3 +++ .../model/json/TestJacksonPlainBean.java | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index c9280c8c0..bc7392287 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -57,6 +57,9 @@ public class BeanPropertyJsonMapper extends BeanProperty { final String json = scalarType.format(value); final MutableValueInfo oldHash = ebi.mutableInfo(propertyIndex); if (oldHash == null) { + if (value == null) { + return false; // no change, still null + } ebi.mutableNext(propertyIndex, next(json)); return true; } diff --git a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java index c0fe82b26..24f0a35f8 100644 --- a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java +++ b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java @@ -10,6 +10,31 @@ import static org.assertj.core.api.Assertions.assertThat; public class TestJacksonPlainBean { + @Test + public void insertNullStayNull() { + + // insert with jackson beans as null + EBasicPlain bean = new EBasicPlain(); + bean.setAttr("n0"); + DB.save(bean); + + LoggedSqlCollector.start(); + bean.setAttr("n1"); + DB.save(bean); + expectedSql(0, "update ebasic_plain set attr=?, version=? where id=? and version=?"); + + bean.setPlainBean(new PlainBean("x", 1)); + DB.save(bean); + expectedSql(0, "update ebasic_plain set plain_bean=?, version=? where id=? and version=?"); + + final EBasicPlain found = DB.find(EBasicPlain.class, bean.getId()); + found.setAttr("n2"); + DB.save(found); + expectedSql(1, "update ebasic_plain set attr=?, version=? where id=? and version=?"); + + LoggedSqlCollector.stop(); + } + @Test public void insertUpdate() { From 7bd7640c631e586c953439ec60104e66baa52330 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 17:18:28 +1200 Subject: [PATCH 032/120] Update test TestDbJson_Jackson3 showing HASH mode is used even on ModifyAwareType --- .../src/test/java/org/tests/json/TestDbJson_Jackson3.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index ac10f2a16..bc89a0eb5 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -224,6 +224,12 @@ public class TestDbJson_Jackson3 extends BaseTestCase { bean.save(); // no update as plainValue3 has MutationDetection.NONE (ModifyAwareType = NONE isn't an expected combination to me) assertThat(LoggedSql.collect()).isEmpty(); + + bean.getPlainValue2().setName("b2"); // effectively HASH mode mutation detection + bean.save(); + sql = LoggedSql.collect(); + assertThat(sql.get(0)).contains("update ebasic_json_jackson3 set plain_value2=?, version=? where id=? and version=?"); + LoggedSql.stop(); } } From d9f7531e81ee29459aab29386cfb6eb34baf637d Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 17:26:46 +1200 Subject: [PATCH 033/120] Tidy tests only - TestDbJson_Jackson3 TestJacksonPlainBean --- .../org/tests/json/TestDbJson_Jackson3.java | 33 ++++++++----------- .../model/json/TestJacksonPlainBean.java | 14 ++++---- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index bc89a0eb5..c1cc3c40d 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -59,20 +59,15 @@ public class TestDbJson_Jackson3 extends BaseTestCase { LoggedSql.start(); found.save(); - - List sql = LoggedSql.collect(); - assertThat(sql).hasSize(1); - assertThat(sql.get(0)).contains("update ebasic_json_jackson3 set name=?, version=? where id=? and version=?"); + expectedSql(0, "update ebasic_json_jackson3 set name=?, version=? where id=? and version=?"); found.setName("b1-mod2"); found.getPlainValue().setName("b"); // found.getPlainValue().setMarkedDirty(true); // Irrelevant for SOURCE or HASH based mutation detection found.save(); - - sql = LoggedSql.stop(); - assertThat(sql).hasSize(1); - assertThat(sql.get(0)).contains("update ebasic_json_jackson3 set name=?, plain_value=?, version=? where id=? and version=?"); + expectedSql(0, "update ebasic_json_jackson3 set name=?, plain_value=?, version=? where id=? and version=?"); + LoggedSql.stop(); final EBasicJsonJackson3 found2 = DB.find(EBasicJsonJackson3.class, bean.getId()); @@ -112,20 +107,16 @@ public class TestDbJson_Jackson3 extends BaseTestCase { LoggedSql.start(); DB.save(found); - List sql = LoggedSql.stop(); - assertThat(sql).hasSize(1); // plain_bean=?, no longer included with MD5 dirty detection - assertThat(sql.get(0)).contains("update ebasic_json_list set name=?, bean_list=?, version=? where id=?"); + expectedSql(0, "update ebasic_json_list set name=?, bean_list=?, version=? where id=?"); assertThat(EBasicJsonListPersistController.updatedValues.entrySet()) .extracting(Map.Entry::toString) .containsExactlyInAnyOrder("beanList=null,[name:a]","name=p1-mod,p1","version=2,1"); - assertThat(DB.getBeanState(found).isDirty()).isFalse(); found.getPlainBean().setName("b"); - assertThat(DB.getBeanState(found).isDirty()).isTrue(); state = DB.getBeanState(found); @@ -138,14 +129,14 @@ public class TestDbJson_Jackson3 extends BaseTestCase { LoggedSql.start(); DB.save(found); - sql = LoggedSql.stop(); - assertThat(sql).hasSize(1); // plain_bean=?, no longer included with MD5 dirty detection - assertThat(sql.get(0)).contains("update ebasic_json_list set plain_bean=?, version=? where id=?"); + expectedSql(0, "update ebasic_json_list set plain_bean=?, version=? where id=?"); assertThat(EBasicJsonListPersistController.updatedValues.entrySet()) .extracting(Map.Entry::toString) .containsExactlyInAnyOrder("plainBean=name:b,name:a", "version=3,2"); + + LoggedSql.stop(); } @Test @@ -210,8 +201,7 @@ public class TestDbJson_Jackson3 extends BaseTestCase { LoggedSql.start(); bean.save(); - List sql = LoggedSql.collect(); - assertThat(sql.get(0)).contains("update ebasic_json_jackson3 set plain_value=?, plain_value2=?, version=? where id=?"); + expectedSql(0, "update ebasic_json_jackson3 set plain_value=?, plain_value2=?, version=? where id=?"); bean = DB.find(EBasicJsonJackson3.class, bean.getId()); LoggedSql.collect(); // ignore the select @@ -227,9 +217,12 @@ public class TestDbJson_Jackson3 extends BaseTestCase { bean.getPlainValue2().setName("b2"); // effectively HASH mode mutation detection bean.save(); - sql = LoggedSql.collect(); - assertThat(sql.get(0)).contains("update ebasic_json_jackson3 set plain_value2=?, version=? where id=? and version=?"); + expectedSql(0, "update ebasic_json_jackson3 set plain_value2=?, version=? where id=? and version=?"); LoggedSql.stop(); } + + private void expectedSql(int i, String s) { + assertThat(LoggedSql.collect().get(i)).contains(s); + } } diff --git a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java index 24f0a35f8..b2237731d 100644 --- a/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java +++ b/ebean-core/src/test/java/org/tests/model/json/TestJacksonPlainBean.java @@ -1,11 +1,9 @@ package org.tests.model.json; import io.ebean.DB; -import org.ebeantest.LoggedSqlCollector; +import io.ebeantest.LoggedSql; import org.junit.Test; -import java.util.List; - import static org.assertj.core.api.Assertions.assertThat; public class TestJacksonPlainBean { @@ -18,7 +16,7 @@ public class TestJacksonPlainBean { bean.setAttr("n0"); DB.save(bean); - LoggedSqlCollector.start(); + LoggedSql.start(); bean.setAttr("n1"); DB.save(bean); expectedSql(0, "update ebasic_plain set attr=?, version=? where id=? and version=?"); @@ -32,14 +30,14 @@ public class TestJacksonPlainBean { DB.save(found); expectedSql(1, "update ebasic_plain set attr=?, version=? where id=? and version=?"); - LoggedSqlCollector.stop(); + LoggedSql.stop(); } @Test public void insertUpdate() { DB.getDefault(); - LoggedSqlCollector.start(); + LoggedSql.start(); PlainBean content = new PlainBean("foo", 42); EBasicPlain bean = new EBasicPlain(); @@ -87,11 +85,11 @@ public class TestJacksonPlainBean { DB.save(found); expectedSql(0, "update ebasic_plain set plain_bean2=?, version=? where id=? and version=?"); - LoggedSqlCollector.stop(); + LoggedSql.stop(); } private void expectedSql(int i, String s) { - assertThat(LoggedSqlCollector.current().get(i)).contains(s); + assertThat(LoggedSql.collect().get(i)).contains(s); } } From ceea705a76a8eb72132c6ec1019e2eb833f2e166 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 20:20:03 +1200 Subject: [PATCH 034/120] Treat json Jackson collections the same wrt mutation detection --- .../java/io/ebean/config/DatabaseConfig.java | 27 ----- .../server/type/DefaultTypeManager.java | 6 +- .../server/type/InitObjectMapper.java | 22 ++++ .../type/ScalarTypeJsonObjectMapper.java | 102 ++---------------- .../server/type/TypeJsonManager.java | 46 +------- .../io/ebean/config/ServerConfigTest.java | 4 - .../java/org/tests/json/TestDbJson_List.java | 14 +-- .../org/tests/model/json/EBasicJsonList.java | 1 + 8 files changed, 41 insertions(+), 181 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/type/InitObjectMapper.java 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 bc3ae587f..476007ebe 100644 --- a/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java +++ b/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java @@ -193,12 +193,6 @@ public class DatabaseConfig { */ private JsonConfig.Include jsonInclude = JsonConfig.Include.ALL; - /** - * When true then by default DbJson beans are assumed to be dirty. - * I believe we want to change this default to false in the future. - */ - private boolean jsonDirtyByDefault = true; - /** * The database platform name. Used to imply a DatabasePlatform to use. */ @@ -743,26 +737,6 @@ public class DatabaseConfig { this.jsonInclude = jsonInclude; } - /** - * Return true if DbJson beans are assumed dirty by default. - *

- * That is, when true beans that do not implement ModifyAwareType are by - * default assumed to be dirty and included in updates. - */ - public boolean isJsonDirtyByDefault() { - return jsonDirtyByDefault; - } - - /** - * Set to false if we want DbJson beans to not be assumed to be dirty. - *

- * That is, when true beans that do not implement ModifyAwareType are by - * default assumed to be dirty and included in updates. - */ - public void setJsonDirtyByDefault(boolean jsonDirtyByDefault) { - this.jsonDirtyByDefault = jsonDirtyByDefault; - } - /** * Return the name of the Database. */ @@ -2935,7 +2909,6 @@ 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); - jsonDirtyByDefault = p.getBoolean("jsonDirtyByDefault", jsonDirtyByDefault); 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 28999e838..8ffb15372 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, config.isJsonDirtyByDefault()) : null; + this.jsonManager = (objectMapperPresent) ? new TypeJsonManager(postgres, objectMapper) : null; this.extraTypeFactory = new DefaultTypeFactory(config); this.arrayTypeListFactory = arrayTypeListFactory(config.getDatabasePlatform()); this.arrayTypeSetFactory = arrayTypeSetFactory(config.getDatabasePlatform()); @@ -556,7 +556,7 @@ public final class DefaultTypeManager implements TypeManager { // no override or further mapping required return scalarType; } - ScalarTypeEnum scalarEnum = (ScalarTypeEnum)scalarType; + ScalarTypeEnum scalarEnum = (ScalarTypeEnum) scalarType; if (scalarEnum != null && !scalarEnum.isOverrideBy(type)) { if (type != null && !scalarEnum.isCompatible(type)) { throw new IllegalStateException("Error mapping Enum type:" + enumType + " It is mapped using 2 different modes when only one is supported (ORDINAL, STRING or an Ebean mapping)"); @@ -673,7 +673,7 @@ public final class DefaultTypeManager implements TypeManager { private Object initObjectMapper(DatabaseConfig config) { Object objectMapper = config.getObjectMapper(); if (objectMapper == null) { - objectMapper = new ObjectMapper(); + objectMapper = InitObjectMapper.init(); config.setObjectMapper(objectMapper); } return objectMapper; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/InitObjectMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/InitObjectMapper.java new file mode 100644 index 000000000..90a86ec79 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/InitObjectMapper.java @@ -0,0 +1,22 @@ +package io.ebeaninternal.server.type; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * Initialise the Jackson ObjectMapper. + */ +class InitObjectMapper { + + /** + * Create and return the default ObjectMapper. + */ + static Object init() { + SimpleModule module = new SimpleModule(); + module.addAbstractTypeMapping(Set.class, LinkedHashSet.class); + return new ObjectMapper().registerModule(module); + } +} 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 7fb3aa4b4..334f4b232 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 @@ -13,9 +13,6 @@ import io.ebean.core.type.DataReader; import io.ebean.core.type.DocPropertyType; import io.ebean.core.type.ScalarType; import io.ebean.text.TextException; -import io.ebeaninternal.json.ModifyAwareList; -import io.ebeaninternal.json.ModifyAwareMap; -import io.ebeaninternal.json.ModifyAwareSet; import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; import javax.persistence.PersistenceException; @@ -24,9 +21,6 @@ import java.io.DataOutput; import java.io.IOException; import java.sql.SQLException; import java.sql.Types; -import java.util.List; -import java.util.Map; -import java.util.Set; /** * Supports @DbJson properties using Jackson ObjectMapper. @@ -38,25 +32,14 @@ class ScalarTypeJsonObjectMapper { */ static ScalarType createTypeFor(TypeJsonManager jsonManager, DeployBeanProperty prop, int dbType, DocPropertyType docType) { AnnotatedField field = (AnnotatedField) prop.getJacksonField(); - Class type = field.getRawType(); - MutationDetection mode = prop.getMutationDetection(); if (mode == MutationDetection.NONE) { - return new NoMutationDetection(jsonManager, field, dbType, type); + return new NoMutationDetection(jsonManager, field, dbType, docType); } else if (mode != MutationDetection.DEFAULT) { - return new GenericObject(jsonManager, field, dbType, type); - } - if (Set.class.equals(type)) { - return new OmSet(jsonManager, field, dbType, docType); - } - if (List.class.equals(type)) { - return new OmList(jsonManager, field, dbType, docType); - } - if (Map.class.equals(type)) { - return new OmMap(jsonManager, field, dbType); + return new GenericObject(jsonManager, field, dbType, docType); } prop.setMutationDetection(MutationDetection.HASH); - return new GenericObject(jsonManager, field, dbType, type); + return new GenericObject(jsonManager, field, dbType, docType); } /** @@ -64,8 +47,8 @@ class ScalarTypeJsonObjectMapper { */ private static class NoMutationDetection extends Base { - NoMutationDetection(TypeJsonManager jsonManager, AnnotatedField field, int dbType, Class rawType) { - super(Object.class, jsonManager, field, dbType, DocPropertyType.OBJECT, rawType); + NoMutationDetection(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) { + super(Object.class, jsonManager, field, dbType, docType); } @Override @@ -84,8 +67,8 @@ class ScalarTypeJsonObjectMapper { */ private static class GenericObject extends Base { - GenericObject(TypeJsonManager jsonManager, AnnotatedField field, int dbType, Class rawType) { - super(Object.class, jsonManager, field, dbType, DocPropertyType.OBJECT, rawType); + GenericObject(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) { + super(Object.class, jsonManager, field, dbType, docType); } @Override @@ -128,60 +111,6 @@ class ScalarTypeJsonObjectMapper { } } - /** - * Type for Sets wrapping the ObjectMapper Set as a ModifyAwareSet. - */ - @SuppressWarnings("rawtypes") - private static class OmSet extends Base { - - OmSet(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) { - super(Set.class, jsonManager, field, dbType, docType); - } - - @Override - @SuppressWarnings("unchecked") - public Set read(DataReader reader) throws SQLException { - Set value = super.read(reader); - return value == null ? null : new ModifyAwareSet(value); - } - } - - /** - * Type for Lists wrapping the ObjectMapper List as a ModifyAwareList. - */ - @SuppressWarnings("rawtypes") - private static class OmList extends Base { - - OmList(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) { - super(List.class, jsonManager, field, dbType, docType); - } - - @Override - @SuppressWarnings("unchecked") - public List read(DataReader reader) throws SQLException { - List value = super.read(reader); - return value == null ? null : new ModifyAwareList(value); - } - } - - /** - * Type for Map wrapping the ObjectMapper Map as a ModifyAwareMap. - */ - @SuppressWarnings("rawtypes") - private static class OmMap extends Base { - - OmMap(TypeJsonManager jsonManager, AnnotatedField field, int dbType) { - super(Map.class, jsonManager, field, dbType, DocPropertyType.OBJECT); - } - - @Override - @SuppressWarnings("unchecked") - public Map read(DataReader reader) throws SQLException { - Map value = super.read(reader); - return value == null ? null : new ModifyAwareMap(value); - } - } - /** * ScalarType that uses Jackson ObjectMapper to marshall/unmarshall to/from JSON * and storing them in one of JSON, JSONB, VARCHAR, CLOB or BLOB. @@ -193,39 +122,22 @@ class ScalarTypeJsonObjectMapper { protected final JavaType deserType; protected final String pgType; private final DocPropertyType docType; - private final TypeJsonManager.DirtyHandler dirtyHandler; Base(Class cls, TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) { - this(cls, jsonManager, field, dbType, docType, cls); - } - - Base(Class cls, TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType, Class rawType) { super(cls, false, dbType); this.objectReader = jsonManager.objectMapper(); this.pgType = jsonManager.postgresType(dbType); this.docType = docType; - this.dirtyHandler = jsonManager.dirtyHandler(cls, rawType); final JacksonTypeHelper helper = new JacksonTypeHelper(field, objectReader); this.deserType = helper.type(); this.objectWriter = helper.objectWriter(); } - /** - * Consider as a mutable type. Use the isDirty() method to check for dirty state. - */ @Override public boolean isMutable() { return true; } - /** - * Return true if the value should be considered dirty (and included in an update). - */ - @Override - public boolean isDirty(Object value) { - return dirtyHandler.isDirty(value); - } - @Override public T read(DataReader reader) throws SQLException { String json = reader.getString(); 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 baea26dec..9cc0b5f0d 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,25 +2,16 @@ package io.ebeaninternal.server.type; import com.fasterxml.jackson.databind.ObjectMapper; import io.ebean.ModifyAwareType; -import io.ebean.config.DatabaseConfig; import io.ebean.config.dbplatform.DbPlatformType; class TypeJsonManager { - interface DirtyHandler { - boolean isDirty(Object value); - } - private final boolean postgres; private final ObjectMapper objectMapper; - private final DirtyHandler defaultHandler; - private final DirtyHandler modifyAwareHandler; - TypeJsonManager(boolean postgres, Object objectMapper, boolean defaultDirty) { + TypeJsonManager(boolean postgres, Object objectMapper) { this.postgres = postgres; this.objectMapper = (ObjectMapper) objectMapper; - this.defaultHandler = new DefaultHandler(defaultDirty); - this.modifyAwareHandler = new ModifyAwareHandler(); } ObjectMapper objectMapper() { @@ -39,17 +30,6 @@ class TypeJsonManager { return null; } - /** - * Return the DirtyHandler to use. - */ - DirtyHandler dirtyHandler(Class cls, Class rawType) { - if (!Object.class.equals(cls) || ModifyAwareType.class.isAssignableFrom(rawType)) { - // Set, List and Map are modify aware - return modifyAwareHandler; - } - return defaultHandler; - } - /** * Return true if the value should be considered dirty (and included in an update). */ @@ -71,28 +51,4 @@ class TypeJsonManager { } } - static final class ModifyAwareHandler implements DirtyHandler { - @Override - public boolean isDirty(Object value) { - return checkModifyAware(value); - } - } - - /** - * Effectively constant based on {@link DatabaseConfig#isJsonDirtyByDefault()} - */ - static final class DefaultHandler implements DirtyHandler { - - private final boolean dirty; - - DefaultHandler(boolean dirty) { - this.dirty = dirty; - } - - @Override - public boolean isDirty(Object value) { - return dirty; - } - } - } 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 dde2cb216..55eb1f06e 100644 --- a/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java +++ b/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java @@ -104,9 +104,6 @@ public class ServerConfigTest { assertEquals(PlatformConfig.DbUuid.BINARY, serverConfig.getPlatformConfig().getDbUuid()); assertEquals(JsonConfig.DateTime.MILLIS, serverConfig.getJsonDateTime()); assertEquals(JsonConfig.Date.MILLIS, serverConfig.getJsonDate()); - assertFalse(serverConfig.isJsonDirtyByDefault()); - serverConfig.setJsonDirtyByDefault(true); - assertTrue(serverConfig.isJsonDirtyByDefault()); assertEquals("r0,users,orgs", serverConfig.getEnabledL2Regions()); @@ -159,7 +156,6 @@ public class ServerConfigTest { assertFalse(serverConfig.isIdGeneratorAutomatic()); assertEquals(JsonConfig.DateTime.ISO8601, serverConfig.getJsonDateTime()); assertEquals(JsonConfig.Date.ISO8601, serverConfig.getJsonDate()); - assertTrue(serverConfig.isJsonDirtyByDefault()); assertTrue(serverConfig.getPlatformConfig().isCaseSensitiveCollation()); assertTrue(serverConfig.isAutoLoadModuleInfo()); diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java index f43d6f23c..13e85a160 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java @@ -76,10 +76,11 @@ public class TestDbJson_List extends BaseTestCase { update_when_dirty(); update_when_dirty_flags(); update_when_dirty_SetListMap(); + + DB.delete(found); } - //@Test//(dependsOnMethods = "insert") - public void json_parse_format() { + private void json_parse_format() { String asJson = DB.json().toJson(found); assertThat(asJson).contains("\"tags\":[\"one\",\"two\"]"); @@ -104,8 +105,7 @@ public class TestDbJson_List extends BaseTestCase { assertThat(fromJson.getBeanMap()).hasSize(2); } - //@Test//(dependsOnMethods = "insert") - public void update_when_notDirty() { + private void update_when_notDirty() { found.setName("mod"); LoggedSqlCollector.start(); @@ -117,7 +117,7 @@ public class TestDbJson_List extends BaseTestCase { assertSql(sql.get(0)).contains("update ebasic_json_list set name=?, version=? where"); } - public void update_when_dirty() { + private void update_when_dirty() { //found.setName("modAgain"); found.getTags().add("three"); @@ -131,7 +131,7 @@ public class TestDbJson_List extends BaseTestCase { assertSql(sql.get(0)).contains("update ebasic_json_list set tags=?, version=? where id=? and version=?"); } - public void update_when_dirty_flags() { + private void update_when_dirty_flags() { //found.setName("modAgain"); found.getFlags().remove(42L); @@ -145,7 +145,7 @@ public class TestDbJson_List extends BaseTestCase { assertSql(sql.get(0)).contains("update ebasic_json_list set flags=?, version=? where id=? and version=?;"); } - public void update_when_dirty_SetListMap() { + private void update_when_dirty_SetListMap() { //found.setName("modAgain"); found.getBeanSet().clear(); diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java index f76d282f7..885e85bf8 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonList.java @@ -20,6 +20,7 @@ public class EBasicJsonList { String name; + // @JsonDeserialize(as=LinkedHashSet.class) @DbJson(length = 700, name = "beans") Set beanSet; From 2691221168c83dc155fb0cd401f7c58cef25576d Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 22:53:51 +1200 Subject: [PATCH 035/120] #2278 - Do not override empty json collections, when database value is null --- .../ebeaninternal/server/deploy/BeanProperty.java | 13 +++++++++++++ .../server/deploy/BeanPropertyJsonMapper.java | 3 +++ .../test/java/org/tests/json/TestDbJson_List.java | 3 +-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index a33d183ea..d564a1f7a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -50,6 +50,7 @@ import java.io.IOException; import java.lang.reflect.Field; import java.sql.SQLException; import java.sql.Types; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; @@ -623,9 +624,21 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { return scalarType.read(reader); } + protected Object checkForEmpty(EntityBean bean) { + final Object value = getValue(bean); + if (value instanceof Collection && ((Collection) value).isEmpty() + || value instanceof Map && ((Map) value).isEmpty()) { + return value; + } + return null; + } + public Object readSet(DataReader reader, EntityBean bean) throws SQLException { try { Object value = scalarType.read(reader); + if (value == null) { + value = checkForEmpty(bean); + } if (bean != null) { setValue(bean, value); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index bc7392287..0b7cdebbc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -76,6 +76,9 @@ public class BeanPropertyJsonMapper extends BeanProperty { public Object readSet(DataReader reader, EntityBean bean) throws SQLException { try { Object value = scalarType.read(reader); + if (value == null) { + value = checkForEmpty(bean); + } if (bean != null) { setValue(bean, value); String json = reader.popJson(); diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java index 8378888b2..647aa6eff 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_List.java @@ -234,8 +234,7 @@ public class TestDbJson_List extends BaseTestCase { bean.setBeanMap(null); DB.save(bean); - bean = DB.find(EBasicJsonList.class) - .setId(bean.getId()).findOne(); + bean = DB.find(EBasicJsonList.class).setId(bean.getId()).findOne(); assertThat(bean.getFlags()).isEmpty(); assertThat(bean.getTags()).isEmpty(); From 443e826f618b0ea35b53fb5b4b004d52912d6e4e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 23:22:06 +1200 Subject: [PATCH 036/120] #2278 - Embedded bean override with DbJson property --- .../deploy/BeanEmbeddedMetaFactory.java | 6 +----- .../server/deploy/BeanProperty.java | 11 +++++----- .../server/deploy/BeanPropertyAssocOne.java | 20 +++++++++---------- .../server/deploy/BeanPropertyJsonMapper.java | 10 ++++++++++ .../org/tests/model/embedded/EAddress.java | 14 +++++++++++++ .../org/tests/model/embedded/EPerson.java | 3 ++- .../nativesql/TestNativeWithEmbedded.java | 11 ++++++---- 7 files changed, 49 insertions(+), 26 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMetaFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMetaFactory.java index af6e7b9e4..5def0dc64 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMetaFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMetaFactory.java @@ -42,11 +42,7 @@ class BeanEmbeddedMetaFactory { int dbScale = dbScale(column, sourceProperties[i]); String colDefn = getDbColumnDefn(column, sourceProperties[i]); BeanPropertyOverride overrides = new BeanPropertyOverride(dbColumn, dbNullable, dbLength, dbScale, colDefn); - if (sourceProperties[i] instanceof BeanPropertyAssocOne) { - embeddedProperties[i] = new BeanPropertyAssocOne((BeanPropertyAssocOne)sourceProperties[i], overrides); - } else { - embeddedProperties[i] = new BeanProperty(sourceProperties[i], overrides); - } + embeddedProperties[i] = sourceProperties[i].override(overrides); } return new BeanEmbeddedMeta(embeddedProperties); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index d564a1f7a..ad054c59b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -365,13 +365,14 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { return InternString.intern(s); } + public BeanProperty override(BeanPropertyOverride override) { + return new BeanProperty(this, override); + } + /** - * Create a Matching BeanProperty with some attributes overridden. - *

- * Primarily for supporting Embedded beans with overridden dbColumn - * mappings. + * Create a Matching BeanProperty with some attributes overridden for Embedded beans. */ - public BeanProperty(BeanProperty source, BeanPropertyOverride override) { + protected BeanProperty(BeanProperty source, BeanPropertyOverride override) { this.descriptor = source.descriptor; this.propertyIndex = source.propertyIndex; this.name = source.getName(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java index ca81267eb..9a69b8c9c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java @@ -94,10 +94,12 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc implements STr } } - /** - * Copy constructor for ManyToOne inside Embeddable. - */ - public BeanPropertyAssocOne(BeanPropertyAssocOne source, BeanPropertyOverride override) { + @Override + public BeanPropertyAssocOne override(BeanPropertyOverride override) { + return new BeanPropertyAssocOne<>(this, override); + } + + protected BeanPropertyAssocOne(BeanPropertyAssocOne source, BeanPropertyOverride override) { super(source, override); primaryKeyExport = source.primaryKeyExport; primaryKeyJoin = source.primaryKeyJoin; @@ -255,12 +257,8 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc implements STr } private SqlUpdate deleteByParentIdList(List parentIds) { - - StringBuilder sb = new StringBuilder(100); - sb.append(deleteByParentIdInSql); - sb.append(targetIdBinder.getIdInValueExpr(false, parentIds.size())); - - DefaultSqlUpdate delete = new DefaultSqlUpdate(sb.toString()); + String sql = deleteByParentIdInSql + targetIdBinder.getIdInValueExpr(false, parentIds.size()); + DefaultSqlUpdate delete = new DefaultSqlUpdate(sql); bindParentIds(delete, parentIds); return delete; } @@ -501,7 +499,7 @@ public class BeanPropertyAssocOne extends BeanPropertyAssoc implements STr return targetDescriptor.getIdProperty(); } - ScalarType getIdScalarType() { + ScalarType getIdScalarType() { return targetDescriptor.getIdProperty().scalarType; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index 0b7cdebbc..bc13b1a8b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -27,6 +27,16 @@ public class BeanPropertyJsonMapper extends BeanProperty { this.sourceDetection = deployProp.getMutationDetection() == MutationDetection.SOURCE; } + private BeanPropertyJsonMapper(BeanPropertyJsonMapper source, BeanPropertyOverride override) { + super(source, override); + this.sourceDetection = source.sourceDetection; + } + + @Override + public BeanProperty override(BeanPropertyOverride override) { + return new BeanPropertyJsonMapper(this, override); + } + @Override public MutableValueInfo createMutableInfo(String json) { if (sourceDetection) { diff --git a/ebean-core/src/test/java/org/tests/model/embedded/EAddress.java b/ebean-core/src/test/java/org/tests/model/embedded/EAddress.java index 86911152b..356399005 100644 --- a/ebean-core/src/test/java/org/tests/model/embedded/EAddress.java +++ b/ebean-core/src/test/java/org/tests/model/embedded/EAddress.java @@ -1,5 +1,8 @@ package org.tests.model.embedded; +import io.ebean.annotation.DbJson; +import org.tests.model.json.PlainBean; + import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.EnumType; @@ -18,6 +21,9 @@ public class EAddress { @Enumerated(EnumType.STRING) EAddressStatus status; + @DbJson + PlainBean jbean; + public String getStreet() { return street; } @@ -42,6 +48,14 @@ public class EAddress { this.city = city; } + public PlainBean getJbean() { + return jbean; + } + + public void setJbean(PlainBean jbean) { + this.jbean = jbean; + } + public EAddressStatus getStatus() { return status; } diff --git a/ebean-core/src/test/java/org/tests/model/embedded/EPerson.java b/ebean-core/src/test/java/org/tests/model/embedded/EPerson.java index 1e85b1041..8a0c60446 100644 --- a/ebean-core/src/test/java/org/tests/model/embedded/EPerson.java +++ b/ebean-core/src/test/java/org/tests/model/embedded/EPerson.java @@ -24,7 +24,8 @@ public class EPerson { @Embedded @AttributeOverrides({ @AttributeOverride(name = "city", column = @Column(name = "addr_city")), - @AttributeOverride(name = "status", column = @Column(name = "addr_status")) + @AttributeOverride(name = "status", column = @Column(name = "addr_status")), + @AttributeOverride(name = "jbean", column = @Column(name = "addr_jbean")) }) EAddress address; diff --git a/ebean-core/src/test/java/org/tests/rawsql/nativesql/TestNativeWithEmbedded.java b/ebean-core/src/test/java/org/tests/rawsql/nativesql/TestNativeWithEmbedded.java index b6e4287a0..09084ccc2 100644 --- a/ebean-core/src/test/java/org/tests/rawsql/nativesql/TestNativeWithEmbedded.java +++ b/ebean-core/src/test/java/org/tests/rawsql/nativesql/TestNativeWithEmbedded.java @@ -1,12 +1,13 @@ package org.tests.rawsql.nativesql; import io.ebean.BaseTestCase; -import io.ebean.Ebean; +import io.ebean.DB; import io.ebean.Query; import org.ebeantest.LoggedSqlCollector; import org.junit.Test; import org.tests.model.embedded.EAddress; import org.tests.model.embedded.EPerson; +import org.tests.model.json.PlainBean; import java.util.List; @@ -22,20 +23,22 @@ public class TestNativeWithEmbedded extends BaseTestCase { EAddress address = new EAddress(); address.setStreet("1 foo st"); address.setCity("barv"); + address.setJbean(new PlainBean("hi", 3)); person.setAddress(address); - Ebean.save(person); + DB.save(person); - String sql = "select id, name, street, suburb, addr_city, addr_status from eperson where id = ?"; + String sql = "select id, name, street, suburb, addr_city, addr_status, addr_jbean from eperson where id = ?"; LoggedSqlCollector.start(); - Query query = Ebean.findNative(EPerson.class, sql); + Query query = DB.findNative(EPerson.class, sql); query.setParameter(person.getId()); EPerson one = query.findOne(); assertThat(one.getName()).isEqualTo("Frank"); assertThat(one.getAddress().getStreet()).isEqualTo("1 foo st"); + assertThat(one.getAddress().getJbean().getName()).isEqualTo("hi"); List loggedSql = LoggedSqlCollector.stop(); assertThat(loggedSql).hasSize(1); From d601a88d827cafdfaa879060e882df1b01370ee4 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 30 Jul 2021 23:53:28 +1200 Subject: [PATCH 037/120] #2278 - Move null to empty json collections check to BeanPropertyJsonBasic --- .../server/deploy/BeanProperty.java | 14 ----- .../server/deploy/BeanPropertyJsonBasic.java | 58 +++++++++++++++++++ .../server/deploy/BeanPropertyJsonMapper.java | 2 +- .../deploy/meta/DeployBeanProperty.java | 6 +- .../deploy/meta/DeployBeanPropertyLists.java | 3 + .../server/deploy/parse/DeployUtil.java | 3 - .../org/tests/model/embedded/EAddress.java | 12 ++++ .../model/json/EBasicJsonMapVarchar.java | 2 +- .../nativesql/TestNativeWithEmbedded.java | 8 ++- 9 files changed, 85 insertions(+), 23 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonBasic.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java index ad054c59b..413d0b460 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanProperty.java @@ -625,27 +625,13 @@ public class BeanProperty implements ElPropertyValue, Property, STreeProperty { return scalarType.read(reader); } - protected Object checkForEmpty(EntityBean bean) { - final Object value = getValue(bean); - if (value instanceof Collection && ((Collection) value).isEmpty() - || value instanceof Map && ((Map) value).isEmpty()) { - return value; - } - return null; - } - public Object readSet(DataReader reader, EntityBean bean) throws SQLException { try { Object value = scalarType.read(reader); - if (value == null) { - value = checkForEmpty(bean); - } if (bean != null) { setValue(bean, value); } return value; - } catch (TextException e) { - throw e; } catch (Exception e) { throw new PersistenceException("Error readSet on " + descriptor + "." + name, e); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonBasic.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonBasic.java new file mode 100644 index 000000000..6593186a6 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonBasic.java @@ -0,0 +1,58 @@ +package io.ebeaninternal.server.deploy; + +import io.ebean.bean.EntityBean; +import io.ebean.core.type.DataReader; +import io.ebean.text.TextException; +import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; + +import javax.persistence.PersistenceException; +import java.sql.SQLException; +import java.util.Collection; +import java.util.Map; + +/** + * A DbJson property that does not use Jackson ObjectMapper. + */ +public class BeanPropertyJsonBasic extends BeanProperty { + + public BeanPropertyJsonBasic(BeanDescriptor descriptor, DeployBeanProperty deploy) { + super(descriptor, deploy); + } + + protected BeanPropertyJsonBasic(BeanProperty source, BeanPropertyOverride override) { + super(source, override); + } + + @Override + public BeanProperty override(BeanPropertyOverride override) { + return new BeanPropertyJsonBasic(this, override); + } + + protected Object checkForEmpty(EntityBean bean) { + final Object value = getValue(bean); + if (value instanceof Collection && ((Collection) value).isEmpty() + || value instanceof Map && ((Map) value).isEmpty()) { + return value; + } + return null; + } + + @Override + public Object readSet(DataReader reader, EntityBean bean) throws SQLException { + try { + Object value = scalarType.read(reader); + if (value == null) { + value = checkForEmpty(bean); + } + if (bean != null) { + setValue(bean, value); + } + return value; + } catch (TextException e) { + throw e; + } catch (Exception e) { + throw new PersistenceException("Error readSet on " + descriptor + "." + name, e); + } + } + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index bc13b1a8b..fdea2e449 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -18,7 +18,7 @@ import java.util.Objects; /** * Handle json property with MutationDetection of SOURCE or HASH only. */ -public class BeanPropertyJsonMapper extends BeanProperty { +public class BeanPropertyJsonMapper extends BeanPropertyJsonBasic { private final boolean sourceDetection; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java index 3da06d559..5e5455b2f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanProperty.java @@ -316,9 +316,6 @@ public class DeployBeanProperty { } public MutationDetection getMutationDetection() { - if (mutationDetection == null) { - mutationDetection = MutationDetection.DEFAULT; - } return mutationDetection; } @@ -1204,4 +1201,7 @@ public class DeployBeanProperty { return scalarType != null && scalarType.isJsonMapper(); } + boolean isJsonType() { + return mutationDetection != null; + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java index 90503c93f..5466d5bca 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java @@ -453,6 +453,9 @@ public class DeployBeanPropertyLists { if (deployProp.isJsonMapper()) { return new BeanPropertyJsonMapper(desc, deployProp); } + if (deployProp.isJsonType()) { + return new BeanPropertyJsonBasic(desc, deployProp); + } return new BeanProperty(desc, deployProp); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java index 0792c66d5..68cb1c741 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java @@ -205,9 +205,6 @@ public class DeployUtil { } } - /** - * This property is marked as a Lob object. - */ void setDbJsonType(DeployBeanProperty prop, DbJson dbJsonType) { int dbType = getDbJsonStorage(dbJsonType.storage()); setDbJsonType(prop, dbType, dbJsonType.length(), dbJsonType.mutationDetection()); diff --git a/ebean-core/src/test/java/org/tests/model/embedded/EAddress.java b/ebean-core/src/test/java/org/tests/model/embedded/EAddress.java index 356399005..4b737f0f5 100644 --- a/ebean-core/src/test/java/org/tests/model/embedded/EAddress.java +++ b/ebean-core/src/test/java/org/tests/model/embedded/EAddress.java @@ -7,6 +7,7 @@ import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import java.util.Map; @Embeddable public class EAddress { @@ -24,6 +25,9 @@ public class EAddress { @DbJson PlainBean jbean; + @DbJson + Map jraw; + public String getStreet() { return street; } @@ -56,6 +60,14 @@ public class EAddress { this.jbean = jbean; } + public Map getJraw() { + return jraw; + } + + public void setJraw(Map jraw) { + this.jraw = jraw; + } + public EAddressStatus getStatus() { return status; } diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonMapVarchar.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonMapVarchar.java index c08c4e9fe..2b470ef45 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonMapVarchar.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonMapVarchar.java @@ -20,7 +20,7 @@ public class EBasicJsonMapVarchar { String name; @DbJson(storage = DbJsonType.VARCHAR)//, length = 2200) - Map content; + Map content; public Long getId() { return id; diff --git a/ebean-core/src/test/java/org/tests/rawsql/nativesql/TestNativeWithEmbedded.java b/ebean-core/src/test/java/org/tests/rawsql/nativesql/TestNativeWithEmbedded.java index 09084ccc2..39f63c31b 100644 --- a/ebean-core/src/test/java/org/tests/rawsql/nativesql/TestNativeWithEmbedded.java +++ b/ebean-core/src/test/java/org/tests/rawsql/nativesql/TestNativeWithEmbedded.java @@ -9,7 +9,9 @@ import org.tests.model.embedded.EAddress; import org.tests.model.embedded.EPerson; import org.tests.model.json.PlainBean; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -18,17 +20,20 @@ public class TestNativeWithEmbedded extends BaseTestCase { @Test public void test() { + Map rawMap = new LinkedHashMap<>(); + rawMap.put("a","1"); EPerson person = new EPerson(); person.setName("Frank"); EAddress address = new EAddress(); address.setStreet("1 foo st"); address.setCity("barv"); address.setJbean(new PlainBean("hi", 3)); + address.setJraw(rawMap); person.setAddress(address); DB.save(person); - String sql = "select id, name, street, suburb, addr_city, addr_status, addr_jbean from eperson where id = ?"; + String sql = "select id, name, street, suburb, addr_city, addr_status, addr_jbean, jraw from eperson where id = ?"; LoggedSqlCollector.start(); @@ -39,6 +44,7 @@ public class TestNativeWithEmbedded extends BaseTestCase { assertThat(one.getName()).isEqualTo("Frank"); assertThat(one.getAddress().getStreet()).isEqualTo("1 foo st"); assertThat(one.getAddress().getJbean().getName()).isEqualTo("hi"); + assertThat(one.getAddress().getJraw().get("a")).isEqualTo("1"); List loggedSql = LoggedSqlCollector.stop(); assertThat(loggedSql).hasSize(1); From 928b90122f7bced174610da0c97d28810d6aabc4 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 2 Aug 2021 20:15:51 +1200 Subject: [PATCH 038/120] #2283 - ddl-generator - Add DbMigration.addPlatform(Platform) with default sub-directory based on Platform --- .../io/ebean/dbmigration/DbMigration.java | 16 +++-- .../dbmigration/DefaultDbMigration.java | 62 +++++++++---------- .../dbmigration/LastMigration.java | 5 +- .../dbmigration/model/MigrationModel.java | 12 ++-- .../dbmigration/DbMigrationGenerateTest.java | 12 ++-- 5 files changed, 52 insertions(+), 55 deletions(-) diff --git a/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java b/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java index 96b8aa16e..36a53ba48 100644 --- a/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java @@ -196,19 +196,23 @@ public interface DbMigration { void setLockTimeout(int seconds); /** - * Add an additional platform to write the migration DDL. + * Add a platform to write the migration DDL. *

* Use this when you want to generate sql scripts for multiple database platforms * from the migration (e.g. generate migration sql for MySql, Postgres and Oracle). *

*/ + void addPlatform(Platform platform); + + /** + * Add a platform to write with a given prefix. + */ void addPlatform(Platform platform, String prefix); /** - * Add an additional databasePlatform to write the migration DDL. + * Add a databasePlatform to write the migration DDL. *

* Use this when you want to add preconfigured database platforms. - *

*/ void addDatabasePlatform(DatabasePlatform databasePlatform, String prefix); @@ -256,9 +260,9 @@ public interface DbMigration { * * migration.setPathToResources("src/main/resources"); * - * migration.addPlatform(Platform.POSTGRES, "pg"); - * migration.addPlatform(Platform.MYSQL, "mysql"); - * migration.addPlatform(Platform.ORACLE, "oracle"); + * migration.addPlatform(Platform.POSTGRES); + * migration.addPlatform(Platform.MYSQL); + * migration.addPlatform(Platform.ORACLE); * * migration.generateMigration(); * diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index 1c790c607..0a7b0edee 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -259,13 +259,12 @@ public class DefaultDbMigration implements DbMigration { } } - /** - * Add an additional platform to write the migration DDL. - *

- * Use this when you want to generate sql scripts for multiple database platforms - * from the migration (e.g. generate migration sql for MySql, Postgres and Oracle). - *

- */ + @Override + public void addPlatform(Platform platform) { + String prefix = platform.base().name().toLowerCase(); + addPlatform(platform, prefix); + } + @Override public void addPlatform(Platform platform, String prefix) { platforms.add(new Pair(getPlatform(platform), prefix)); @@ -286,7 +285,7 @@ public class DefaultDbMigration implements DbMigration { * * DbMigration migration = DbMigration.create(); * migration.setPathToResources("src/main/resources"); - * migration.setPlatform(DbPlatformName.ORACLE); + * migration.setPlatform(Platform.ORACLE); * * migration.generateMigration(); * @@ -298,9 +297,9 @@ public class DefaultDbMigration implements DbMigration { * DbMigration migration = DbMigration.create(); * migration.setPathToResources("src/main/resources"); * - * migration.addPlatform(DbPlatformName.POSTGRES, "pg"); - * migration.addPlatform(DbPlatformName.MYSQL, "mysql"); - * migration.addPlatform(DbPlatformName.ORACLE, "mysql"); + * migration.addPlatform(Platform.POSTGRES); + * migration.addPlatform(Platform.MYSQL); + * migration.addPlatform(Platform.ORACLE); * * migration.generateMigration(); * @@ -318,10 +317,9 @@ public class DefaultDbMigration implements DbMigration { return generateMigrationFor(true); } - private String generateMigrationFor(boolean dbinitMigration) throws IOException { - - // use this flag to stop other plugins like full DDL generation + private String generateMigrationFor(boolean initMigration) throws IOException { if (!online) { + // use this flag to stop other plugins like full DDL generation DbOffline.setGenerateMigration(); if (databasePlatform == null && !platforms.isEmpty()) { // for multiple platform generation the first platform @@ -334,8 +332,8 @@ public class DefaultDbMigration implements DbMigration { configurePlatforms(); } try { - Request request = createRequest(dbinitMigration); - if (!dbinitMigration) { + Request request = createRequest(initMigration); + if (!initMigration) { // repeatable migrations if (platforms.isEmpty()) { generateExtraDdl(request.migrationDir, databasePlatform, request.isTablePartitioning()); @@ -512,31 +510,31 @@ public class DefaultDbMigration implements DbMigration { return version; } - private Request createRequest(boolean dbinitMigration) { - return new Request(dbinitMigration); + private Request createRequest(boolean initMigration) { + return new Request(initMigration); } private class Request { - final boolean dbinitMigration; + final boolean initMigration; final File migrationDir; final File modelDir; final CurrentModel currentModel; final ModelContainer migrated; final ModelContainer current; - private Request(boolean dbinitMigration) { - this.dbinitMigration = dbinitMigration; + private Request(boolean initMigration) { + this.initMigration = initMigration; this.currentModel = new CurrentModel(server, constraintNaming); this.current = currentModel.read(); - this.migrationDir = getMigrationDirectory(dbinitMigration); - if (dbinitMigration) { + this.migrationDir = getMigrationDirectory(initMigration); + if (initMigration) { this.modelDir = null; this.migrated = new ModelContainer(); } else { this.modelDir = getModelDirectory(migrationDir); MigrationModel migrationModel = new MigrationModel(modelDir, modelSuffix); - this.migrated = migrationModel.read(dbinitMigration); + this.migrated = migrationModel.read(false); } } @@ -551,7 +549,7 @@ public class DefaultDbMigration implements DbMigration { // always read the next version using the main migration directory (not dbinit) File migDirectory = getMigrationDirectory(false); File modelDir = getModelDirectory(migDirectory); - return LastMigration.nextVersion(migDirectory, modelDir, dbinitMigration); + return LastMigration.nextVersion(migDirectory, modelDir, initMigration); } /** @@ -588,7 +586,7 @@ public class DefaultDbMigration implements DbMigration { String fullVersion = getFullVersion(request.nextVersion(), dropsFor); logInfo("generating migration:%s", fullVersion); - if (!request.dbinitMigration && !writeMigrationXml(dbMigration, request.modelDir, fullVersion)) { + if (!request.initMigration && !writeMigrationXml(dbMigration, request.modelDir, fullVersion)) { logError("migration already exists, not generating DDL"); return null; } else { @@ -782,17 +780,15 @@ public class DefaultDbMigration implements DbMigration { /** * Return the file path to write the xml and sql to. */ - File getMigrationDirectory(boolean dbinitMigration) { - + File getMigrationDirectory(boolean initMigration) { // path to src/main/resources in typical maven project File resourceRootDir = new File(pathToResources); if (!resourceRootDir.exists()) { String msg = String.format("Error - path to resources %s does not exist. Absolute path is %s", pathToResources, resourceRootDir.getAbsolutePath()); throw new UnknownResourcePathException(msg); } - String resourcePath = getMigrationPath(dbinitMigration); - - // expect to be a path to something like - src/main/resources/dbmigration/model + String resourcePath = getMigrationPath(initMigration); + // expect to be a path to something like - src/main/resources/dbmigration File path = new File(resourceRootDir, resourcePath); if (!path.exists()) { if (!path.mkdirs()) { @@ -802,8 +798,8 @@ public class DefaultDbMigration implements DbMigration { return path; } - private String getMigrationPath(boolean dbinitMigration) { - return dbinitMigration ? migrationInitPath : migrationPath; + private String getMigrationPath(boolean initMigration) { + return initMigration ? migrationInitPath : migrationPath; } /** diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java index 20b9a19c3..0a3353068 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java @@ -20,13 +20,12 @@ class LastMigration { /** * Return the next migation version given the migration directory. */ - static String nextVersion(File migDir, File modelDir, boolean dbinitMigration) { - + static String nextVersion(File migDir, File modelDir, boolean initMigration) { String last = lastVersion(migDir, modelDir); if (last == null) { return null; } - return (dbinitMigration) ? last : MigrationVersion.parse(last).nextVersion(); + return (initMigration) ? last : MigrationVersion.parse(last).nextVersion(); } /** diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationModel.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationModel.java index 6fe5ed66b..2ad1001bb 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationModel.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationModel.java @@ -34,16 +34,14 @@ public class MigrationModel { * Read all the migrations returning the model with all * the migrations applied in version order. * - * @param dbinitMigration If true we don't apply model changes, migration is from scratch. + * @param initMigration If true we don't apply model changes, migration is from scratch. */ - public ModelContainer read(boolean dbinitMigration) { - - readMigrations(dbinitMigration); + public ModelContainer read(boolean initMigration) { + readMigrations(initMigration); return model; } - private void readMigrations(boolean dbinitMigration) { - + private void readMigrations(boolean initMigration) { // find all the migration xml files File[] xmlFiles = modelDirectory.listFiles(pathname -> pathname.getName().toLowerCase().endsWith(modelSuffix)); if (xmlFiles == null || xmlFiles.length == 0) { @@ -57,7 +55,7 @@ public class MigrationModel { // sort into version order before applying Collections.sort(resources); - if (!dbinitMigration) { + if (!initMigration) { for (MigrationResource migrationResource : resources) { logger.debug("read {}", migrationResource); model.apply(migrationResource.read(), migrationResource.getVersion()); diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java index 1efaacee3..0063a75cf 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java @@ -46,16 +46,16 @@ public class DbMigrationGenerateTest { // migration.addPlatform(Platform.GENERIC, "generic"); there is no ddl handler for generic // migration.addPlatform(Platform.SQLANYWHERE, "sqlanywhere"); and sqlanywhere - migration.addPlatform(Platform.DB2, "db2"); - migration.addPlatform(Platform.H2, "h2"); + migration.addPlatform(Platform.DB2); + migration.addPlatform(Platform.H2); migration.addPlatform(Platform.HSQLDB, "hsqldb"); migration.addPlatform(Platform.MYSQL, "mysql"); migration.addPlatform(Platform.MYSQL55, "mysql55"); - migration.addPlatform(Platform.POSTGRES, "postgres"); - migration.addPlatform(Platform.ORACLE, "oracle"); - migration.addPlatform(Platform.SQLITE, "sqlite"); + migration.addPlatform(Platform.POSTGRES); + migration.addPlatform(Platform.ORACLE); + migration.addPlatform(Platform.SQLITE); migration.addPlatform(Platform.SQLSERVER17, "sqlserver17"); - migration.addPlatform(Platform.HANA, "hana"); + migration.addPlatform(Platform.HANA); DatabaseConfig config = new DatabaseConfig(); config.setName("migrationtest"); From 71223895ac458f18e7d1ca6d7c2b01d99bce43fb Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 2 Aug 2021 20:38:05 +1200 Subject: [PATCH 039/120] #2283 - ddl-generator - Refactor tidy whitespace etc --- .../io/ebean/dbmigration/DbMigration.java | 19 ++---- .../dbmigration/LastMigration.java | 3 +- .../UnknownResourcePathException.java | 1 - .../dbmigration/model/CurrentModel.java | 10 +-- .../model/MCompoundUniqueConstraint.java | 4 -- .../dbmigration/model/MConfiguration.java | 3 +- .../dbmigration/model/MIndex.java | 4 +- .../dbmigration/model/MTable.java | 65 ++----------------- .../dbmigration/model/MTableIdentity.java | 2 - .../dbmigration/model/MigrationModel.java | 16 +---- .../dbmigration/model/MigrationResource.java | 3 +- .../dbmigration/model/ModelContainer.java | 5 +- .../dbmigration/model/ModelDiff.java | 16 ++--- .../dbmigration/model/PendingDrops.java | 12 ---- .../dbmigration/model/PlatformDdlWriter.java | 5 -- 15 files changed, 22 insertions(+), 146 deletions(-) diff --git a/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java b/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java index 36a53ba48..55753f4a2 100644 --- a/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java @@ -16,7 +16,6 @@ import java.util.ServiceLoader; *

* Typically this is run as a main method in src/test once a developer is happy * with the next set of changes to the model. - *

* *

Example: Run for a single specific platform

* @@ -39,11 +38,9 @@ import java.util.ServiceLoader; * are no longer being used by the application. These changes are called * "pending drops" and we must explicitly specify to include these in * a generated migration. - *

*

* Use setGeneratePendingDrop() to specify a prior migration * that has drop column changes that we want to generate a migration for. - *

* *

Example: Generate for pending drops

* @@ -67,7 +64,6 @@ public interface DbMigration { * Create a DbMigration implementation to use. */ static DbMigration create() { - Iterator loader = ServiceLoader.load(DbMigration.class).iterator(); if (loader.hasNext()) { return loader.next(); @@ -76,7 +72,7 @@ public interface DbMigration { } /** - * Set to false to suppress logging to System out. + * Set logging to System out (defaults to true). */ void setLogToSystemOut(boolean logToSystemOut); @@ -105,13 +101,12 @@ public interface DbMigration { void setMigrationPath(String migrationPath); /** - * Set the server to use to determine the current model. - * Typically this is not called explicitly. + * Set the server to use to determine the current model. Usually this is not called explicitly. */ void setServer(Database database); /** - * Set the DatabaseConfig to use. Typically this is not called explicitly. + * Set the DatabaseConfig to use. Usually this is not called explicitly. */ void setServerConfig(DatabaseConfig config); @@ -119,7 +114,6 @@ public interface DbMigration { * Set the specific platform to generate DDL for. *

* If not set this defaults to the platform of the default database. - *

*/ void setPlatform(Platform platform); @@ -127,17 +121,15 @@ public interface DbMigration { * Set the specific platform to generate DDL for. *

* If not set this defaults to the platform of the default database. - *

*/ void setPlatform(DatabasePlatform databasePlatform); /** - * Set to false to turn off strict mode. + * Set to false in order to turn off strict mode. *

* Strict mode checks that a column changed to non-null on an existing table via DB migration has a default * value specified. Set this to false if that isn't the case but it is known that all the existing rows have * a value specified (there are no existing null values for the column). - *

*/ void setStrictMode(boolean strictMode); @@ -182,7 +174,6 @@ public interface DbMigration { * Set to true if ALTER TABLE ADD FOREIGN KEY should be generated with an option to skip validation. *

* Currently this is only useful for Postgres DDL adding the NOT VALID option. - *

*/ void setAddForeignKeySkipCheck(boolean addForeignKeySkipCheck); @@ -191,7 +182,6 @@ public interface DbMigration { *

* Currently this is only useful for Postgres migrations adding a set lock_timeout * statement to the generated database migration. - *

*/ void setLockTimeout(int seconds); @@ -200,7 +190,6 @@ public interface DbMigration { *

* Use this when you want to generate sql scripts for multiple database platforms * from the migration (e.g. generate migration sql for MySql, Postgres and Oracle). - *

*/ void addPlatform(Platform platform); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java index 0a3353068..07a80add9 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java @@ -29,10 +29,9 @@ class LastMigration { } /** - * Return the last migation version given the migration directory. + * Return the last migration version given the migration directory. */ static String lastVersion(File migDirectory, File modelDir) { - List versions = new ArrayList<>(); File[] sqlFiles = migDirectory.listFiles(pathname -> includeSqlFile(pathname.getName().toLowerCase())); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/UnknownResourcePathException.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/UnknownResourcePathException.java index 9ecfde157..c8b29872a 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/UnknownResourcePathException.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/UnknownResourcePathException.java @@ -4,7 +4,6 @@ package io.ebeaninternal.dbmigration; * Exception when db migration resource path does not exist. *

* Typically the working directory or pathToResources is incorrect. - *

*/ public class UnknownResourcePathException extends RuntimeException { diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java index 11189be94..0ff9a9bc4 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/CurrentModel.java @@ -27,25 +27,17 @@ import static io.ebeaninternal.api.PlatformMatch.matchPlatform; public class CurrentModel { private final SpiEbeanServer server; - private final DatabasePlatform databasePlatform; - private final DbConstraintNaming constraintNaming; - private final boolean platformTypes; - private final boolean jaxbPresent; - private final String ddlHeader; + private final DdlOptions ddlOptions = new DdlOptions(); private ModelContainer model; - private ChangeSet changeSet; - private DdlWrite write; - private DdlOptions ddlOptions = new DdlOptions(); - /** * Construct with a given EbeanServer instance for DDL create all generation, not migration. */ diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MCompoundUniqueConstraint.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MCompoundUniqueConstraint.java index c7c63769d..fbb2e2460 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MCompoundUniqueConstraint.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MCompoundUniqueConstraint.java @@ -20,19 +20,15 @@ import static io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns.s public class MCompoundUniqueConstraint { private final String name; - /** * Flag if true indicates this was specifically created for a OneToOne mapping. */ private final boolean oneToOne; - /** * The columns combined to be unique. */ private final String[] columns; - private final String platforms; - private String[] nullableColumns; /** diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MConfiguration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MConfiguration.java index 43387a5c7..178f35c8d 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MConfiguration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MConfiguration.java @@ -4,7 +4,7 @@ import io.ebeaninternal.dbmigration.migration.Configuration; import io.ebeaninternal.dbmigration.migration.DefaultTablespace; /** - * Holds configuration such as the default tablespaces to use for tables, + * Holds configuration such as the default tablespace to use for tables, * indexes, history tables etc. */ public class MConfiguration { @@ -32,7 +32,6 @@ public class MConfiguration { *

*/ public void apply(Configuration configuration) { - DefaultTablespace defaultTablespace = configuration.getDefaultTablespace(); if (defaultTablespace != null) { String tables = defaultTablespace.getTables(); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MIndex.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MIndex.java index 976bde5f3..710241a69 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MIndex.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MIndex.java @@ -13,8 +13,8 @@ import java.util.Objects; */ public class MIndex { - private String tableName; - private String indexName; + private final String tableName; + private final String indexName; private String platforms; private List columns = new ArrayList<>(); private boolean unique; diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTable.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTable.java index 82a687eb7..71faa1c44 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTable.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTable.java @@ -48,67 +48,32 @@ public class MTable { private static final Logger logger = LoggerFactory.getLogger(MTable.class); - /** - * Table name. - */ private final String name; - - /** - * The associated draft table. - */ private MTable draftTable; - /** * Marked true for draft tables. These need to have their FK references adjusted * after all the draft tables have been identified. */ private boolean draft; - private PartitionMeta partitionMeta; - - /** - * Primary key name. - */ private String pkName; - - /** - * Table comment. - */ private String comment; - - /** - * Tablespace to use. - */ private String tablespace; - private String storageEngine; - - /** - * Tablespace to use for indexes on this table. - */ private String indexTablespace; - private IdentityMode identityMode; - - /** - * If set to true this table should has history support. - */ private boolean withHistory; - - /** - * The columns on the table. - */ - private Map columns = new LinkedHashMap<>(); + private final Map columns = new LinkedHashMap<>(); /** * Compound unique constraints. */ - private List uniqueConstraints = new ArrayList<>(); + private final List uniqueConstraints = new ArrayList<>(); /** * Compound foreign keys. */ - private List compoundKeys = new ArrayList<>(); + private final List compoundKeys = new ArrayList<>(); /** * Column name for the 'When created' column. This can be used for the initial effective start date when adding @@ -121,7 +86,7 @@ public class MTable { */ private AddColumn addColumn; - private List droppedColumns = new ArrayList<>(); + private final List droppedColumns = new ArrayList<>(); public MTable(BeanDescriptor descriptor) { this.name = descriptor.getBaseTable(); @@ -153,18 +118,15 @@ public class MTable { * later when creating the CreateTable object. */ public MTable createDraftTable() { - draftTable = new MTable(name + "_draft"); draftTable.draft = true; draftTable.whenCreatedColumn = whenCreatedColumn; // compoundKeys // compoundUniqueConstraints draftTable.identityMode = identityMode; - for (MColumn col : allColumns()) { draftTable.addColumn(col.copyForDraft()); } - return draftTable; } @@ -239,7 +201,6 @@ public class MTable { * Return the CreateTable migration for this table. */ public CreateTable createTable() { - CreateTable createTable = new CreateTable(); createTable.setName(name); createTable.setPkName(pkName); @@ -258,22 +219,18 @@ public class MTable { if (draft) { createTable.setDraft(Boolean.TRUE); } - for (MColumn column : allColumns()) { // filter out draftOnly columns from the base table if (draft || !column.isDraftOnly()) { createTable.getColumn().add(column.createColumn()); } } - for (MCompoundForeignKey compoundKey : compoundKeys) { createTable.getForeignKey().add(compoundKey.createForeignKey()); } - for (MCompoundUniqueConstraint constraint : uniqueConstraints) { createTable.getUniqueConstraint().add(constraint.getUniqueConstraint()); } - return createTable; } @@ -281,7 +238,6 @@ public class MTable { * Compare to another version of the same table to perform a diff. */ public void compare(ModelDiff modelDiff, MTable newTable) { - if (withHistory != newTable.withHistory) { if (withHistory) { DropHistoryTable dropHistoryTable = new DropHistoryTable(); @@ -308,14 +264,12 @@ public class MTable { modelDiff.addTableComment(addTableComment); } - compareCompoundKeys(modelDiff, newTable); compareUniqueKeys(modelDiff, newTable); } private void compareColumns(ModelDiff modelDiff, MTable newTable) { addColumn = null; - Map newColumnMap = newTable.getColumns(); // compare newColumns to existing columns (look for new and diff columns) @@ -374,10 +328,10 @@ public class MTable { currentKeys.removeAll(newTable.getUniqueConstraints()); newKeys.removeAll(getUniqueConstraints()); - for (MCompoundUniqueConstraint currentKey: currentKeys) { + for (MCompoundUniqueConstraint currentKey : currentKeys) { modelDiff.addUniqueConstraint(currentKey.dropUniqueConstraint(name)); } - for (MCompoundUniqueConstraint newKey: newKeys) { + for (MCompoundUniqueConstraint newKey : newKeys) { modelDiff.addUniqueConstraint(newKey.addUniqueConstraint(name)); } } @@ -489,7 +443,6 @@ public class MTable { } public List allHistoryColumns(boolean includeDropped) { - List columnNames = new ArrayList<>(columns.size()); for (MColumn column : columns.values()) { if (column.isIncludeInHistory()) { @@ -595,7 +548,6 @@ public class MTable { * Sometimes the case for a primaryKey that is also a foreign key. */ public MColumn addColumn(String dbCol, String columnDefn, boolean notnull) { - MColumn existingColumn = getColumn(dbCol); if (existingColumn != null) { if (notnull) { @@ -613,7 +565,6 @@ public class MTable { * Add a 'new column' to the AddColumn migration object. */ private void diffNewColumn(MColumn newColumn) { - if (addColumn == null) { addColumn = new AddColumn(); addColumn.setTableName(name); @@ -631,7 +582,6 @@ public class MTable { * Add a 'drop column' to the diff. */ private void diffDropColumn(ModelDiff modelDiff, MColumn existingColumn) { - DropColumn dropColumn = new DropColumn(); dropColumn.setTableName(name); dropColumn.setColumnName(existingColumn.getName()); @@ -640,7 +590,6 @@ public class MTable { // table as well as the base table dropColumn.setWithHistory(Boolean.TRUE); } - modelDiff.addDropColumn(dropColumn); } @@ -661,7 +610,6 @@ public class MTable { *

*/ public void checkDuplicateForeignKeys() { - if (hasDuplicateForeignKeys()) { int counter = 1; for (MCompoundForeignKey fk : compoundKeys) { @@ -687,7 +635,6 @@ public class MTable { * Adjust the references (FK) if it should relate to a draft table. */ public void adjustReferences(ModelContainer modelContainer) { - Collection cols = allColumns(); for (MColumn col : cols) { String references = col.getReferences(); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTableIdentity.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTableIdentity.java index 5e4bb2306..f226ebaec 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTableIdentity.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MTableIdentity.java @@ -17,7 +17,6 @@ public class MTableIdentity { * Return the IdentityMode from CreateTable. */ public static IdentityMode fromCreateTable(CreateTable createTable) { - IdType type = fromType(createTable.getIdentityType()); IdentityGenerated generated = fromGenerated(createTable.getIdentityGenerated()); int start = toInt(createTable.getIdentityStart(), createTable.getSequenceInitial()); @@ -39,7 +38,6 @@ public class MTableIdentity { * Set the IdentityMode to the CreateTable model. */ public static void toCreateTable(IdentityMode identityMode, CreateTable createTable) { - if (!identityMode.isPlatformDefault()) { createTable.setIdentityType(toType(identityMode.getIdType())); } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationModel.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationModel.java index 2ad1001bb..9c49ad0aa 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationModel.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationModel.java @@ -18,13 +18,9 @@ public class MigrationModel { private static final Logger logger = LoggerFactory.getLogger(MigrationModel.class); private final ModelContainer model = new ModelContainer(); - private final File modelDirectory; - private final String modelSuffix; - private MigrationVersion lastVersion; - public MigrationModel(File modelDirectory, String modelSuffix) { this.modelDirectory = modelDirectory; this.modelSuffix = modelSuffix; @@ -58,14 +54,9 @@ public class MigrationModel { if (!initMigration) { for (MigrationResource migrationResource : resources) { logger.debug("read {}", migrationResource); - model.apply(migrationResource.read(), migrationResource.getVersion()); + model.apply(migrationResource.read(), migrationResource.version()); } } - - // remember the last version - if (!resources.isEmpty()) { - lastVersion = resources.get(resources.size() - 1).getVersion(); - } } private MigrationVersion createVersion(File xmlFile) { @@ -73,9 +64,4 @@ public class MigrationModel { String versionName = fileName.substring(0, fileName.length() - modelSuffix.length()); return MigrationVersion.parse(versionName); } - - public String getNextVersion(String initialVersion) { - - return lastVersion == null ? initialVersion : lastVersion.nextVersion(); - } } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationResource.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationResource.java index eff454813..ae4950a4e 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationResource.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/MigrationResource.java @@ -31,7 +31,7 @@ public class MigrationResource implements Comparable { /** * Return the version associated with this resource. */ - public MigrationVersion getVersion() { + public MigrationVersion version() { return version; } @@ -39,7 +39,6 @@ public class MigrationResource implements Comparable { * Read and return the migration from the resource. */ public Migration read() { - return MigrationXmlReader.read(migrationFile); } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/ModelContainer.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/ModelContainer.java index 3f75064d2..dc19ef137 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/ModelContainer.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/ModelContainer.java @@ -37,19 +37,16 @@ import java.util.TreeSet; public class ModelContainer { private final Set schemas = new TreeSet<>(); - /** * All the tables in the model. */ private final Map tables = new LinkedHashMap<>(); /** - * All the non unique non foreign key indexes. + * All the non-unique non-foreign key indexes. */ private final Map indexes = new LinkedHashMap<>(); - private final PendingDrops pendingDrops = new PendingDrops(); - private final List partitionedTables = new ArrayList<>(); public ModelContainer() { diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/ModelDiff.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/ModelDiff.java index 2babc7c6c..367c13ca5 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/ModelDiff.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/ModelDiff.java @@ -53,29 +53,24 @@ public class ModelDiff { this.baseModel = new ModelContainer(); } - /** - * Return true if the apply and drop changes are both empty. - * This means there are no migration changes. + * Return true if apply and drop changes are both empty. This means there are no migration changes. */ public boolean isEmpty() { return applyChanges.isEmpty() && dropChanges.isEmpty(); } /** - * Return the diff as a migration potentially containing - * an apply changeSet and a drop changeSet. + * Return the diff as a migration potentially containing an apply changeSet and a drop changeSet. */ public Migration getMigration() { - Migration migration = new Migration(); if (!applyChanges.isEmpty()) { - // add a non empty apply changeSet + // add a non-empty apply changeSet migration.getChangeSet().add(getApplyChangeSet()); } - if (!dropChanges.isEmpty()) { - // add a non empty drop changeSet + // add a non-empty drop changeSet migration.getChangeSet().add(getDropChangeSet()); } return migration; @@ -121,7 +116,6 @@ public class ModelDiff { * Compare to a 'newer' model and collect the differences. */ public void compareTo(ModelContainer newModel) { - Map newTables = newModel.getTables(); for (MTable newTable : newTables.values()) { @@ -179,7 +173,6 @@ public class ModelDiff { * Compare tables looking for add/drop/modify columns etc. */ protected void compareTables(MTable currentTable, MTable newTable) { - currentTable.compare(this, newTable); } @@ -187,7 +180,6 @@ public class ModelDiff { * Compare tables looking for add/drop/modify columns etc. */ protected void compareIndexes(MIndex currentIndex, MIndex newIndex) { - currentIndex.compare(this, newIndex); } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PendingDrops.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PendingDrops.java index 9a0bdd242..bd7e7c96b 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PendingDrops.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PendingDrops.java @@ -24,7 +24,6 @@ public class PendingDrops { * Add a 'pending drops' changeSet for the given version. */ public void add(MigrationVersion version, ChangeSet changeSet) { - Entry entry = map.computeIfAbsent(version.normalised(), k -> new Entry(version)); entry.add(changeSet); } @@ -33,7 +32,6 @@ public class PendingDrops { * Return the list of versions with pending drops. */ public List pendingDrops() { - List versions = new ArrayList<>(); for (Entry value : map.values()) { if (value.hasPendingDrops()) { @@ -48,7 +46,6 @@ public class PendingDrops { * to remove the (unsuppressed) pending drops for this version. */ public boolean appliedDropsFor(ChangeSet changeSet) { - MigrationVersion version = MigrationVersion.parse(changeSet.getDropsFor()); Entry entry = map.get(version.normalised()); @@ -68,7 +65,6 @@ public class PendingDrops { *

*/ public Migration migrationForVersion(String pendingVersion) { - Entry entry = getEntry(pendingVersion); Migration migration = new Migration(); @@ -96,7 +92,6 @@ public class PendingDrops { } private Entry getEntry(String pendingVersion) { - if ("next".equalsIgnoreCase(pendingVersion)) { Iterator it = map.values().iterator(); if (it.hasNext()) { @@ -115,7 +110,6 @@ public class PendingDrops { * Register pending drop columns on history tables to the new model. */ public void registerPendingHistoryDropColumns(ModelContainer newModel) { - for (Entry entry : map.values()) { for (ChangeSet changeSet : entry.list) { newModel.registerPendingHistoryDropColumns(changeSet); @@ -140,7 +134,6 @@ public class PendingDrops { static class Entry { final MigrationVersion version; - final List list = new ArrayList<>(); Entry(MigrationVersion version) { @@ -180,7 +173,6 @@ public class PendingDrops { * removed all the changeSets (and there are no suppressForever ones). */ boolean removeDrops(ChangeSet appliedDrops) { - Iterator iterator = list.iterator(); while (iterator.hasNext()) { ChangeSet next = iterator.next(); @@ -199,20 +191,16 @@ public class PendingDrops { * Remove the applied drops from the pending ones matching by table name and column name. */ private void removeMatchingChanges(ChangeSet pendingDrops, ChangeSet appliedDrops) { - List pending = pendingDrops.getChangeSetChildren(); Iterator iterator = pending.iterator(); while (iterator.hasNext()) { Object pendingDrop = iterator.next(); if (pendingDrop instanceof DropColumn && dropColumnIn((DropColumn) pendingDrop, appliedDrops)) { iterator.remove(); - } else if (pendingDrop instanceof DropTable && dropTableIn((DropTable) pendingDrop, appliedDrops)) { iterator.remove(); - } else if (pendingDrop instanceof DropHistoryTable && dropHistoryTableIn((DropHistoryTable) pendingDrop, appliedDrops)) { iterator.remove(); - } } } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PlatformDdlWriter.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PlatformDdlWriter.java index f56384477..59da934e4 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PlatformDdlWriter.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/PlatformDdlWriter.java @@ -27,9 +27,7 @@ public class PlatformDdlWriter { private static final Logger logger = LoggerFactory.getLogger(PlatformDdlWriter.class); private final DatabaseConfig databaseConfig; - private final PlatformDdl platformDdl; - private final int lockTimeoutSeconds; public PlatformDdlWriter(DatabasePlatform platform, DatabaseConfig dbConfig, int lockTimeoutSeconds) { @@ -42,7 +40,6 @@ public class PlatformDdlWriter { * Write the migration as platform specific ddl. */ public void processMigration(Migration dbMigration, DdlWrite write, File writePath, String fullVersion) throws IOException { - DdlHandler handler = handler(); handler.generateProlog(write); if (lockTimeoutSeconds > 0) { @@ -51,7 +48,6 @@ public class PlatformDdlWriter { write.apply().append(lockSql).endOfStatement().newLine(); } } - List changeSets = dbMigration.getChangeSet(); for (ChangeSet changeSet : changeSets) { if (isApply(changeSet)) { @@ -59,7 +55,6 @@ public class PlatformDdlWriter { } } handler.generateEpilog(write); - writePlatformDdl(write, writePath, fullVersion); } From 4ba26ee7b761faf69819ee3ed76f622204784d72 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 2 Aug 2021 20:49:30 +1200 Subject: [PATCH 040/120] #2283 - ddl-generator - Refactor tidy DefaultDbMigration etc --- .../dbmigration/DefaultDbMigration.java | 89 +++++-------------- .../dbmigration/LastMigration.java | 2 +- .../DbMigrationDropHistoryTest.java | 4 +- .../dbmigration/DbMigrationGenerateTest.java | 4 +- 4 files changed, 25 insertions(+), 74 deletions(-) diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index 0a7b0edee..7643eeec2 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -2,7 +2,6 @@ package io.ebeaninternal.dbmigration; import io.ebean.DB; import io.ebean.Database; -import io.ebean.EbeanServer; import io.ebean.annotation.Platform; import io.ebean.config.DatabaseConfig; import io.ebean.config.DbConstraintNaming; @@ -79,20 +78,12 @@ import static io.ebeaninternal.api.PlatformMatch.matchPlatform; public class DefaultDbMigration implements DbMigration { protected static final Logger logger = LoggerFactory.getLogger("io.ebean.GenerateMigration"); - private static final String initialVersion = "1.0"; - private static final String GENERATED_COMMENT = "THIS IS A GENERATED FILE - DO NOT MODIFY"; - private boolean logToSystemOut = true; - - /** - * Set to true if DefaultDbMigration run with online EbeanServer instance. - */ protected final boolean online; - + private boolean logToSystemOut = true; protected SpiEbeanServer server; - protected String pathToResources = "src/main/resources"; protected String migrationPath = "dbmigration"; @@ -101,15 +92,10 @@ public class DefaultDbMigration implements DbMigration { protected String modelSuffix = ".model.xml"; protected DatabasePlatform databasePlatform; - private boolean vanillaPlatform; - protected List platforms = new ArrayList<>(); - protected DatabaseConfig databaseConfig; - protected DbConstraintNaming constraintNaming; - protected Boolean strictMode; protected Boolean includeGeneratedFileComment; protected String header; @@ -119,7 +105,6 @@ public class DefaultDbMigration implements DbMigration { protected String generatePendingDrop; private boolean addForeignKeySkipCheck; private int lockTimeoutSeconds; - protected boolean includeBuiltInPartitioning = true; /** @@ -129,19 +114,6 @@ public class DefaultDbMigration implements DbMigration { this.online = false; } - /** - * Create using online EbeanServer. - */ - public DefaultDbMigration(EbeanServer server) { - this.online = true; - setServer(server); - } - - /** - * Set the path from the current working directory to the application resources. - *

- * This defaults to maven style 'src/main/resources'. - */ @Override public void setPathToResources(String pathToResources) { this.pathToResources = pathToResources; @@ -152,19 +124,12 @@ public class DefaultDbMigration implements DbMigration { this.migrationPath = migrationPath; } - /** - * Set the server to use to determine the current model. - * Typically this is not called explicitly. - */ @Override public void setServer(Database database) { this.server = (SpiEbeanServer) database; setServerConfig(server.getServerConfig()); } - /** - * Set the DatabaseConfig to use. Typically this is not called explicitly. - */ @Override public void setServerConfig(DatabaseConfig config) { if (this.databaseConfig == null) { @@ -173,7 +138,6 @@ public class DefaultDbMigration implements DbMigration { if (constraintNaming == null) { this.constraintNaming = databaseConfig.getConstraintNaming(); } - Properties properties = config.getProperties(); if (properties != null) { PropertiesWrapper props = new PropertiesWrapper("ebean", config.getName(), properties, null); @@ -242,7 +206,7 @@ public class DefaultDbMigration implements DbMigration { @Override public void setPlatform(Platform platform) { vanillaPlatform = true; - setPlatform(getPlatform(platform)); + setPlatform(platform(platform)); } /** @@ -267,7 +231,7 @@ public class DefaultDbMigration implements DbMigration { @Override public void addPlatform(Platform platform, String prefix) { - platforms.add(new Pair(getPlatform(platform), prefix)); + platforms.add(new Pair(platform(platform), prefix)); } @Override @@ -402,7 +366,6 @@ public class DefaultDbMigration implements DbMigration { *

*/ private void generateExtraDdl(File migrationDir, DatabasePlatform dbPlatform, boolean tablePartitioning) throws IOException { - if (dbPlatform != null) { if (tablePartitioning && includeBuiltInPartitioning) { generateExtraDdlFor(migrationDir, dbPlatform, ExtraDdlXmlReader.readBuiltinTablePartitioning()); @@ -427,10 +390,8 @@ public class DefaultDbMigration implements DbMigration { * Write (or override) the "repeatable" migration script. */ private void writeExtraDdl(File migrationDir, DdlScript script) throws IOException { - String fullName = repeatableMigrationName(script.isInit(), script.getName()); logger.debug("writing repeatable script {}", fullName); - File file = new File(migrationDir, fullName); try (FileWriter writer = new FileWriter(file)) { writer.write(script.getValue()); @@ -478,12 +439,10 @@ public class DefaultDbMigration implements DbMigration { * Generate the diff migration. */ private String generateDiff(Request request) throws IOException { - List pendingDrops = request.getPendingDrops(); if (!pendingDrops.isEmpty()) { logInfo("Pending un-applied drops in versions %s", pendingDrops); } - Migration migration = request.createDiffMigration(); if (migration == null) { logInfo("no changes detected - no migration written", null); @@ -498,11 +457,8 @@ public class DefaultDbMigration implements DbMigration { * Generate the migration based on the pendingDrops from a prior version. */ private String generatePendingDrop(Request request, String pendingVersion) throws IOException { - Migration migration = request.migrationForPendingDrop(pendingVersion); - String version = generateMigration(request, migration, pendingVersion); - List pendingDrops = request.getPendingDrops(); if (!pendingDrops.isEmpty()) { logInfo("... remaining pending un-applied drops in versions %s", pendingDrops); @@ -527,12 +483,12 @@ public class DefaultDbMigration implements DbMigration { this.initMigration = initMigration; this.currentModel = new CurrentModel(server, constraintNaming); this.current = currentModel.read(); - this.migrationDir = getMigrationDirectory(initMigration); + this.migrationDir = migrationDirectory(initMigration); if (initMigration) { this.modelDir = null; this.migrated = new ModelContainer(); } else { - this.modelDir = getModelDirectory(migrationDir); + this.modelDir = modelDirectory(migrationDir); MigrationModel migrationModel = new MigrationModel(modelDir, modelSuffix); this.migrated = migrationModel.read(false); } @@ -547,8 +503,8 @@ public class DefaultDbMigration implements DbMigration { */ String nextVersion() { // always read the next version using the main migration directory (not dbinit) - File migDirectory = getMigrationDirectory(false); - File modelDir = getModelDirectory(migDirectory); + File migDirectory = migrationDirectory(false); + File modelDir = modelDirectory(migDirectory); return LastMigration.nextVersion(migDirectory, modelDir, initMigration); } @@ -556,9 +512,7 @@ public class DefaultDbMigration implements DbMigration { * Return the migration for the pending drops for a given version. */ Migration migrationForPendingDrop(String pendingVersion) { - Migration migration = migrated.migrationForPendingDrop(pendingVersion); - // register any remaining pending drops migrated.registerPendingHistoryDropColumns(current); return migration; @@ -582,9 +536,7 @@ public class DefaultDbMigration implements DbMigration { } private String generateMigration(Request request, Migration dbMigration, String dropsFor) throws IOException { - - String fullVersion = getFullVersion(request.nextVersion(), dropsFor); - + String fullVersion = fullVersion(request.nextVersion(), dropsFor); logInfo("generating migration:%s", fullVersion); if (!request.initMigration && !writeMigrationXml(dbMigration, request.modelDir, fullVersion)) { logError("migration already exists, not generating DDL"); @@ -621,15 +573,14 @@ public class DefaultDbMigration implements DbMigration { *

* The full version can contain a comment suffix after a "__" double underscore. */ - private String getFullVersion(String nextVersion, String dropsFor) { - - String version = getVersion(); + private String fullVersion(String nextVersion, String dropsFor) { + String version = version(); if (version == null) { version = (nextVersion != null) ? nextVersion : initialVersion; } String fullVersion = applyPrefix + version; - String name = getName(); + String name = name(); if (name != null) { fullVersion += "__" + toUnderScore(name); @@ -724,7 +675,7 @@ public class DefaultDbMigration implements DbMigration { * FlywayDb so each developer sets a unique version so that the migration script * generated is unique (typically just prior to being submitted as a merge request). */ - private String getVersion() { + private String version() { String envVersion = readEnvironment("ddl.migration.version"); if (!isEmpty(envVersion)) { return envVersion.trim(); @@ -744,7 +695,7 @@ public class DefaultDbMigration implements DbMigration { * is a short description of the feature. *

*/ - private String getName() { + private String name() { String envName = readEnvironment("ddl.migration.name"); if (!isEmpty(envName)) { return envName.trim(); @@ -773,21 +724,21 @@ public class DefaultDbMigration implements DbMigration { /** * Return the main migration directory. */ - File getMigrationDirectory() { - return getMigrationDirectory(false); + File migrationDirectory() { + return migrationDirectory(false); } /** * Return the file path to write the xml and sql to. */ - File getMigrationDirectory(boolean initMigration) { + File migrationDirectory(boolean initMigration) { // path to src/main/resources in typical maven project File resourceRootDir = new File(pathToResources); if (!resourceRootDir.exists()) { String msg = String.format("Error - path to resources %s does not exist. Absolute path is %s", pathToResources, resourceRootDir.getAbsolutePath()); throw new UnknownResourcePathException(msg); } - String resourcePath = getMigrationPath(initMigration); + String resourcePath = migrationPath(initMigration); // expect to be a path to something like - src/main/resources/dbmigration File path = new File(resourceRootDir, resourcePath); if (!path.exists()) { @@ -798,14 +749,14 @@ public class DefaultDbMigration implements DbMigration { return path; } - private String getMigrationPath(boolean initMigration) { + private String migrationPath(boolean initMigration) { return initMigration ? migrationInitPath : migrationPath; } /** * Return the model directory (relative to the migration directory). */ - private File getModelDirectory(File migrationDirectory) { + private File modelDirectory(File migrationDirectory) { if (modelPath == null || modelPath.isEmpty()) { return migrationDirectory; } @@ -819,7 +770,7 @@ public class DefaultDbMigration implements DbMigration { /** * Return the DatabasePlatform given the platform key. */ - protected DatabasePlatform getPlatform(Platform platform) { + protected DatabasePlatform platform(Platform platform) { switch (platform) { case H2: return new H2Platform(); diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java index 07a80add9..17ac65aa9 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/LastMigration.java @@ -18,7 +18,7 @@ class LastMigration { private static final String MODEL_XML = ".model.xml"; /** - * Return the next migation version given the migration directory. + * Return the next migration version given the migration directory. */ static String nextVersion(File migDir, File modelDir, boolean initMigration) { String last = lastVersion(migDir, modelDir); diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java index db91e14c9..320406a7c 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java @@ -54,8 +54,8 @@ public class DbMigrationDropHistoryTest { migration.setServer(server); // First, we clean up the output-directory - assertThat(migration.getMigrationDirectory().getAbsolutePath()).contains("migrationtest-history"); - Files.walk(migration.getMigrationDirectory().toPath()) + assertThat(migration.migrationDirectory().getAbsolutePath()).contains("migrationtest-history"); + Files.walk(migration.migrationDirectory().toPath()) .filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete); // then we generate migration scripts for v1_0 diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java index 0063a75cf..befead534 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java @@ -70,8 +70,8 @@ public class DbMigrationGenerateTest { migration.setServer(server); // First, we clean up the output-directory - assertThat(migration.getMigrationDirectory().getAbsolutePath()).contains("migrationtest"); - Files.walk(migration.getMigrationDirectory().toPath()) + assertThat(migration.migrationDirectory().getAbsolutePath()).contains("migrationtest"); + Files.walk(migration.migrationDirectory().toPath()) .filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete); // then we generate migration scripts for v1_0 From 589ee7a5ea6baee0a011a4a97c0440097297b31d Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 2 Aug 2021 23:59:49 +1200 Subject: [PATCH 041/120] #2284 - ENH: ddl-generator - add optional generation of idx_.migrations file --- .../io/ebean/dbmigration/DbMigration.java | 8 ++ .../dbmigration/DefaultDbMigration.java | 27 +++- .../dbmigration/IndexMigration.java | 125 ++++++++++++++++++ .../ebeaninternal/dbmigration/MChecksum.java | 29 ++++ .../dbmigration/DbMigrationGenerateTest.java | 18 +-- .../dbmigration/IndexMigrationTest.java | 67 ++++++++++ .../dbmigration/MChecksumTest.java | 18 +++ .../dbmigration/index/1.0__hello.sql | 1 + .../resources/dbmigration/index/1.1__foo.sql | 1 + .../resources/dbmigration/index/I__init_1.sql | 1 + .../resources/dbmigration/index/R__view_1.sql | 1 + .../dbmigration/index2/I__init_1.sql | 1 + .../dbmigration/index2/R__view_1.sql | 1 + .../dbmigration/index2/g1/1.0__a.sql | 1 + .../dbmigration/index2/g1/1.1__b.sql | 1 + .../dbmigration/index2/g2/2.0__a.sql | 1 + .../dbmigration/index2/g2/2.1__2b.sql | 1 + 17 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/IndexMigration.java create mode 100644 ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/MChecksum.java create mode 100644 ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/IndexMigrationTest.java create mode 100644 ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MChecksumTest.java create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index/1.0__hello.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index/1.1__foo.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index/I__init_1.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index/R__view_1.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index2/I__init_1.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index2/R__view_1.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index2/g1/1.0__a.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index2/g1/1.1__b.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index2/g2/2.0__a.sql create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index2/g2/2.1__2b.sql diff --git a/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java b/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java index 55753f4a2..ec6db4597 100644 --- a/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebean/dbmigration/DbMigration.java @@ -133,6 +133,14 @@ public interface DbMigration { */ void setStrictMode(boolean strictMode); + /** + * Set to include generation of the index migration file. + *

+ * When true this generates a {@code idx_.migrations} file. This can be used by the migration + * runner to improve performance of running migrations, especially when no migration changes have occurred. + */ + void setIncludeIndex(boolean generateIndexFile); + /** * Set to true to include a generated header comment in the DDL script. */ diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index 7643eeec2..7f2a90558 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -106,6 +106,7 @@ public class DefaultDbMigration implements DbMigration { private boolean addForeignKeySkipCheck; private int lockTimeoutSeconds; protected boolean includeBuiltInPartitioning = true; + protected boolean includeIndex; /** * Create for offline migration generation. @@ -182,6 +183,11 @@ public class DefaultDbMigration implements DbMigration { this.generatePendingDrop = generatePendingDrop; } + @Override + public void setIncludeIndex(boolean includeIndex) { + this.includeIndex = includeIndex; + } + @Override public void setIncludeGeneratedFileComment(boolean includeGeneratedFileComment) { this.includeGeneratedFileComment = includeGeneratedFileComment; @@ -273,7 +279,26 @@ public class DefaultDbMigration implements DbMigration { */ @Override public String generateMigration() throws IOException { - return generateMigrationFor(false); + final String version = generateMigrationFor(false); + if (includeIndex) { + generateIndex(version); + } + return version; + } + + /** + * Generate the {@code idx_platform.migrations} file. + */ + private void generateIndex(String version) throws IOException { + final boolean overwrite = version != null; + final File topDir = migrationDirectory(false); + if (!platforms.isEmpty()) { + for (Pair pair : platforms) { + new IndexMigration(topDir, pair).generate(overwrite); + } + } else { + new IndexMigration(topDir, databasePlatform).generate(overwrite); + } } @Override diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/IndexMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/IndexMigration.java new file mode 100644 index 000000000..215c18e72 --- /dev/null +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/IndexMigration.java @@ -0,0 +1,125 @@ +package io.ebeaninternal.dbmigration; + +import io.ebean.config.dbplatform.DatabasePlatform; +import io.ebean.migration.MigrationVersion; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +/** + * Generate a migration index file. + *

+ * This is a file that has all the migrations listed in order with checksum of the file content. + */ +class IndexMigration { + + private static final String eol = "\n"; + private final List all = new ArrayList<>(); + private final File topDir; + private final DatabasePlatform databasePlatform; + private final File indexFile; + private final Stack pathStack = new Stack<>(); + + IndexMigration(File topDir, DatabasePlatform databasePlatform) { + this.topDir = topDir; + this.databasePlatform = databasePlatform; + this.indexFile = init(); + } + + IndexMigration(File topDir, DefaultDbMigration.Pair pair) { + this.topDir = new File(topDir, pair.prefix); + this.databasePlatform = pair.platform; + this.indexFile = init(); + } + + File init() { + pathStack.push(""); + String name = "idx_" + databasePlatform.getPlatform().base().name().toLowerCase() + ".migrations"; + return new File(topDir, name); + } + + void generate(boolean overwrite) throws IOException { + if (!overwrite && indexFile.exists()) { + return; + } + readSqlFiles(topDir); + generateIndex(); + } + + private void generateIndex() throws IOException { + Collections.sort(all); + FileWriter writer = new FileWriter(indexFile); + for (Entry entry : all) { + writeChecksumPadded(writer, entry.checksum); + writer.write(entry.fileName); + writer.write(eol); + } + writer.write(eol); + writer.close(); + } + + private void writeChecksumPadded(FileWriter writer, int checksum) throws IOException { + final String asStr = String.valueOf(checksum); + writer.write(asStr); + writer.write(','); + int max = 15 - asStr.length(); + for (int i = 0; i < max; i++) { + writer.write(' '); + } + } + + private void readSqlFiles(File dir) { + final File[] files = dir.listFiles(); + if (files != null && files.length > 0) { + for (File file : files) { + if (file.isDirectory()) { + readDirectory(file); + } + final String lowerName = file.getName().toLowerCase(); + if (lowerName.endsWith(".sql")) { + addEntry(file); + } + } + } + } + + private void readDirectory(File dir) { + final String current = pathStack.peek(); + pathStack.push(current + dir.getName() + "/"); + readSqlFiles(dir); + pathStack.pop(); + } + + private void addEntry(File sqlFile) { + final String relativePath = pathStack.peek(); + final String fileName = sqlFile.getName(); + final String name = fileName.substring(0, fileName.length() - 4); + final MigrationVersion version = MigrationVersion.parse(name); + final int checksum = MChecksum.calculate(sqlFile); + all.add(new Entry(checksum, version, relativePath + fileName)); + } + + static class Entry implements Comparable { + + private final int checksum; + private final String fileName; + private final MigrationVersion version; + + Entry(int checksum, MigrationVersion version, String fileName) { + this.checksum = checksum; + this.version = version; + this.fileName = fileName; + } + + @Override + public int compareTo(Entry other) { + return version.compareTo(other.version); + } + } + +} diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/MChecksum.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/MChecksum.java new file mode 100644 index 000000000..9c533992e --- /dev/null +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/MChecksum.java @@ -0,0 +1,29 @@ +package io.ebeaninternal.dbmigration; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.zip.CRC32; + +/** + * Calculates the checksum for the given file content. + */ +class MChecksum { + + /** + * Returns the checksum of the file. Agnostic of encoding and new line character. + */ + static int calculate(File file) { + try { + final CRC32 crc32 = new CRC32(); + BufferedReader bufferedReader = new BufferedReader(new FileReader(file)); + String line; + while ((line = bufferedReader.readLine()) != null) { + final byte[] lineBytes = line.getBytes(StandardCharsets.UTF_8); + crc32.update(lineBytes, 0, lineBytes.length); + } + return (int) crc32.getValue(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to calculate checksum", e); + } + } +} diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java index befead534..f5bf01a56 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java @@ -27,20 +27,22 @@ public class DbMigrationGenerateTest { private static final Logger logger = LoggerFactory.getLogger(DbMigrationGenerateTest.class); - @Test - public void invokeTest() throws IOException { - main(null); + public static void main(String[] args) throws IOException { + run("ebean-ddl-generator/src/test/resources"); } - public static void main(String[] args) throws IOException { + @Test + public void invokeTest() throws IOException { + run("src/test/resources"); + } - logger.info("start"); + public static void run(String pathToResources) throws IOException { + logger.info("start current directory: " + new File(".").getAbsolutePath()); DefaultDbMigration migration = new DefaultDbMigration(); - + migration.setIncludeIndex(true); // We use src/test/resources as output directory (so we see in GIT if files will change) - - migration.setPathToResources("src/test/resources"); + migration.setPathToResources(pathToResources); migration.setMigrationPath("db/migration"); migration.setMigrationPath(null); // use the default for this test diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/IndexMigrationTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/IndexMigrationTest.java new file mode 100644 index 000000000..5a04d8917 --- /dev/null +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/IndexMigrationTest.java @@ -0,0 +1,67 @@ +package io.ebeaninternal.dbmigration; + +import io.ebean.config.dbplatform.DatabasePlatform; +import io.ebean.config.dbplatform.h2.H2Platform; +import io.ebean.config.dbplatform.postgres.PostgresPlatform; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class IndexMigrationTest { + + @Test + public void index() throws IOException { + File topDir = new File("src/test/resources/dbmigration/index"); + if (!topDir.exists()) { + throw new IllegalStateException("Not expected - dir does not exist " + topDir.getAbsolutePath()); + } + DatabasePlatform pg = new PostgresPlatform(); + IndexMigration indexMigration = new IndexMigration(topDir, pg); + indexMigration.generate(true); + + + File expected = new File(topDir, "idx_postgres.migrations"); + assertThat(expected).exists(); + + final List expectedLines = Arrays.asList( + "-965417868, I__init_1.sql", + "907060870, 1.0__hello.sql", + "-1938594527, 1.1__foo.sql", + "-1960070312, R__view_1.sql"); + + final List lines = Files.readAllLines(expected.toPath(), StandardCharsets.UTF_8); + assertThat(lines).containsAll(expectedLines); + } + + @Test + public void index2_withSubDirectories() throws IOException { + File topDir = new File("src/test/resources/dbmigration/index2"); + if (!topDir.exists()) { + throw new IllegalStateException("Not expected - dir does not exist " + topDir.getAbsolutePath()); + } + DatabasePlatform pg = new H2Platform(); + IndexMigration indexMigration = new IndexMigration(topDir, pg); + indexMigration.generate(true); + + File expected = new File(topDir, "idx_h2.migrations"); + assertThat(expected).exists(); + + final List expectedLines = Arrays.asList( + "-965417868, I__init_1.sql", + "-390611389, g1/1.0__a.sql", + "1908338681, g1/1.1__b.sql", + "-1776543936, g2/2.0__a.sql", + "253052666, g2/2.1__2b.sql", + "-1960070312, R__view_1.sql"); + + final List lines = Files.readAllLines(expected.toPath(), StandardCharsets.UTF_8); + assertThat(lines).containsAll(expectedLines); + } +} diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MChecksumTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MChecksumTest.java new file mode 100644 index 000000000..e52c43755 --- /dev/null +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MChecksumTest.java @@ -0,0 +1,18 @@ +package io.ebeaninternal.dbmigration; + +import org.junit.Test; + +import java.io.File; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MChecksumTest { + + @Test + public void calculate() { + File file = new File("src/test/resources/dbmigration/index/1.0__hello.sql"); + assertThat(file).exists(); + + assertThat(MChecksum.calculate(file)).isEqualTo(907060870); + } +} diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index/1.0__hello.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index/1.0__hello.sql new file mode 100644 index 000000000..ce0136250 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index/1.0__hello.sql @@ -0,0 +1 @@ +hello diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index/1.1__foo.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index/1.1__foo.sql new file mode 100644 index 000000000..257cc5642 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index/1.1__foo.sql @@ -0,0 +1 @@ +foo diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index/I__init_1.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index/I__init_1.sql new file mode 100644 index 000000000..b1b716105 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index/I__init_1.sql @@ -0,0 +1 @@ +init diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index/R__view_1.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index/R__view_1.sql new file mode 100644 index 000000000..0f2416ebf --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index/R__view_1.sql @@ -0,0 +1 @@ +Something diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index2/I__init_1.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index2/I__init_1.sql new file mode 100644 index 000000000..b1b716105 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index2/I__init_1.sql @@ -0,0 +1 @@ +init diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index2/R__view_1.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index2/R__view_1.sql new file mode 100644 index 000000000..0f2416ebf --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index2/R__view_1.sql @@ -0,0 +1 @@ +Something diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index2/g1/1.0__a.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index2/g1/1.0__a.sql new file mode 100644 index 000000000..789819226 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index2/g1/1.0__a.sql @@ -0,0 +1 @@ +a diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index2/g1/1.1__b.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index2/g1/1.1__b.sql new file mode 100644 index 000000000..617807982 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index2/g1/1.1__b.sql @@ -0,0 +1 @@ +b diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index2/g2/2.0__a.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index2/g2/2.0__a.sql new file mode 100644 index 000000000..94226dabb --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index2/g2/2.0__a.sql @@ -0,0 +1 @@ +2a diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index2/g2/2.1__2b.sql b/ebean-ddl-generator/src/test/resources/dbmigration/index2/g2/2.1__2b.sql new file mode 100644 index 000000000..b8a4cf4af --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index2/g2/2.1__2b.sql @@ -0,0 +1 @@ +2b From db34afe867af3e2df20d3546c2e039c412a50bd4 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 3 Aug 2021 00:03:02 +1200 Subject: [PATCH 042/120] #2284 - ENH: ddl-generator - add optional generation of idx_.migrations file --- .../resources/dbmigration/index/idx_postgres.migrations | 5 +++++ .../test/resources/dbmigration/index2/idx_h2.migrations | 7 +++++++ .../dbmigration/migrationtest/db2/idx_db2.migrations | 6 ++++++ .../dbmigration/migrationtest/h2/idx_h2.migrations | 6 ++++++ .../dbmigration/migrationtest/hana/idx_hana.migrations | 6 ++++++ .../dbmigration/migrationtest/hsqldb/idx_hsqldb.migrations | 6 ++++++ .../dbmigration/migrationtest/mysql/idx_mysql.migrations | 6 ++++++ .../dbmigration/migrationtest/mysql55/idx_mysql.migrations | 6 ++++++ .../dbmigration/migrationtest/oracle/idx_oracle.migrations | 6 ++++++ .../migrationtest/postgres/idx_postgres.migrations | 6 ++++++ .../dbmigration/migrationtest/sqlite/idx_sqlite.migrations | 6 ++++++ .../migrationtest/sqlserver17/idx_sqlserver.migrations | 7 +++++++ 12 files changed, 73 insertions(+) create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index/idx_postgres.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/index2/idx_h2.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/h2/idx_h2.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/hana/idx_hana.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/hsqldb/idx_hsqldb.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/mysql/idx_mysql.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/mysql55/idx_mysql.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/oracle/idx_oracle.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/postgres/idx_postgres.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/sqlite/idx_sqlite.migrations create mode 100644 ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/sqlserver17/idx_sqlserver.migrations diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index/idx_postgres.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/index/idx_postgres.migrations new file mode 100644 index 000000000..2ccea54d7 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index/idx_postgres.migrations @@ -0,0 +1,5 @@ +-965417868, I__init_1.sql +907060870, 1.0__hello.sql +-1938594527, 1.1__foo.sql +-1960070312, R__view_1.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/index2/idx_h2.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/index2/idx_h2.migrations new file mode 100644 index 000000000..ef6e14321 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/index2/idx_h2.migrations @@ -0,0 +1,7 @@ +-965417868, I__init_1.sql +-390611389, g1/1.0__a.sql +1908338681, g1/1.1__b.sql +-1776543936, g2/2.0__a.sql +253052666, g2/2.1__2b.sql +-1960070312, R__view_1.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations new file mode 100644 index 000000000..ec4208068 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/db2/idx_db2.migrations @@ -0,0 +1,6 @@ +441570368, 1.0__initial.sql +-94595879, 1.1.sql +578073685, 1.2__dropsFor_1.1.sql +-509420890, 1.3.sql +-1475628451, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/h2/idx_h2.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/h2/idx_h2.migrations new file mode 100644 index 000000000..fb21ce854 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/h2/idx_h2.migrations @@ -0,0 +1,6 @@ +-745768926, 1.0__initial.sql +39858255, 1.1.sql +1616986842, 1.2__dropsFor_1.1.sql +-1513154593, 1.3.sql +374569329, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/hana/idx_hana.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/hana/idx_hana.migrations new file mode 100644 index 000000000..984c4bb50 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/hana/idx_hana.migrations @@ -0,0 +1,6 @@ +-1536923954, 1.0__initial.sql +1039838314, 1.1.sql +562867593, 1.2__dropsFor_1.1.sql +1566488731, 1.3.sql +1030652294, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/hsqldb/idx_hsqldb.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/hsqldb/idx_hsqldb.migrations new file mode 100644 index 000000000..ee5e2bd41 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/hsqldb/idx_hsqldb.migrations @@ -0,0 +1,6 @@ +2097980375, 1.0__initial.sql +2086418403, 1.1.sql +-1462014216, 1.2__dropsFor_1.1.sql +-2039573992, 1.3.sql +2106151405, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/mysql/idx_mysql.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/mysql/idx_mysql.migrations new file mode 100644 index 000000000..2ce271cdc --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/mysql/idx_mysql.migrations @@ -0,0 +1,6 @@ +1075178692, 1.0__initial.sql +880212944, 1.1.sql +1029390755, 1.2__dropsFor_1.1.sql +-380371830, 1.3.sql +1085680731, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/mysql55/idx_mysql.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/mysql55/idx_mysql.migrations new file mode 100644 index 000000000..9bf86f51e --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/mysql55/idx_mysql.migrations @@ -0,0 +1,6 @@ +-1087663151, 1.0__initial.sql +880212944, 1.1.sql +1029390755, 1.2__dropsFor_1.1.sql +-380371830, 1.3.sql +1085680731, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/oracle/idx_oracle.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/oracle/idx_oracle.migrations new file mode 100644 index 000000000..533b50b15 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/oracle/idx_oracle.migrations @@ -0,0 +1,6 @@ +1164675950, 1.0__initial.sql +-1916315387, 1.1.sql +238598298, 1.2__dropsFor_1.1.sql +483114276, 1.3.sql +1213528478, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/postgres/idx_postgres.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/postgres/idx_postgres.migrations new file mode 100644 index 000000000..7e74e6b50 --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/postgres/idx_postgres.migrations @@ -0,0 +1,6 @@ +1329543701, 1.0__initial.sql +-1877647184, 1.1.sql +-1861367028, 1.2__dropsFor_1.1.sql +-1798982281, 1.3.sql +1959776888, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/sqlite/idx_sqlite.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/sqlite/idx_sqlite.migrations new file mode 100644 index 000000000..919841fde --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/sqlite/idx_sqlite.migrations @@ -0,0 +1,6 @@ +1429491518, 1.0__initial.sql +-347121868, 1.1.sql +1359055889, 1.2__dropsFor_1.1.sql +-1764531063, 1.3.sql +-1070218324, 1.4__dropsFor_1.3.sql + diff --git a/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/sqlserver17/idx_sqlserver.migrations b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/sqlserver17/idx_sqlserver.migrations new file mode 100644 index 000000000..f7cd1c04a --- /dev/null +++ b/ebean-ddl-generator/src/test/resources/dbmigration/migrationtest/sqlserver17/idx_sqlserver.migrations @@ -0,0 +1,7 @@ +-2122378240, I__create_procs.sql +-1048913407, 1.0__initial.sql +615613536, 1.1.sql +-1805601919, 1.2__dropsFor_1.1.sql +-1791137342, 1.3.sql +460536923, 1.4__dropsFor_1.3.sql + From a06f7bea41f53a4b77763b602730dbf0bd413d78 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 5 Aug 2021 12:55:42 +1200 Subject: [PATCH 043/120] Tidy javadoc for MutableValueInfo --- ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java b/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java index 0f9c223aa..27716b13c 100644 --- a/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java +++ b/ebean-api/src/main/java/io/ebean/bean/MutableValueInfo.java @@ -4,10 +4,10 @@ package io.ebean.bean; * Holds information on mutable values (like plain beans stored as json). *

* Used internally in EntityBeanIntercept for dirty detection on mutable values. - * Typically dirty detection is based on a hash/checksum of json content or the + * Typically, mutation detection is based on a hash/checksum of json content or the * original json content itself. *

- * Refer to the mapping options {@code @DbJson(dirtyDetection)} and {@code @DbJson(keepSource)}. + * Refer to the mapping options {@code @DbJson(mutationDetection)}. */ public interface MutableValueInfo { From 2043fdf7e1a8b845b383c5287a965cb2fe8ba9e7 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 5 Aug 2021 13:12:18 +1200 Subject: [PATCH 044/120] #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()); From a76442641b5eff698a0c36312ab9da3d35549e9d Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 5 Aug 2021 13:14:00 +1200 Subject: [PATCH 045/120] Tidy test only - rename ServerConfigTest to DatabaseConfigTest and tidy --- .../io/ebean/config/DatabaseConfigTest.java | 194 ++++++++++++++++++ .../io/ebean/config/ServerConfigTest.java | 194 ------------------ 2 files changed, 194 insertions(+), 194 deletions(-) create mode 100644 ebean-core/src/test/java/io/ebean/config/DatabaseConfigTest.java delete mode 100644 ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java diff --git a/ebean-core/src/test/java/io/ebean/config/DatabaseConfigTest.java b/ebean-core/src/test/java/io/ebean/config/DatabaseConfigTest.java new file mode 100644 index 000000000..dd132a8e3 --- /dev/null +++ b/ebean-core/src/test/java/io/ebean/config/DatabaseConfigTest.java @@ -0,0 +1,194 @@ +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; +import org.junit.Test; + +import java.util.Properties; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class DatabaseConfigTest { + + @Test + public void testLoadFromEbeanProperties() { + + DatabaseConfig config = new DatabaseConfig(); + config.loadFromProperties(); + + assertEquals(PersistBatch.NONE, config.getPersistBatch()); + assertNotNull(config.getProperties()); + } + + @Test + public void evalPropertiesInput() { + + String home = System.getenv("HOME"); + + Properties props = new Properties(); + props.setProperty("ddl.initSql", "${HOME}/initSql"); + + DatabaseConfig config = new DatabaseConfig(); + config.loadFromProperties(props); + + String ddlInitSql = config.getDdlInitSql(); + assertThat(ddlInitSql).isEqualTo(home+"/initSql"); + } + + @Test + public void testLoadWithProperties() { + + DatabaseConfig config = new DatabaseConfig(); + config.setPersistBatch(PersistBatch.NONE); + config.setPersistBatchOnCascade(PersistBatch.NONE); + config.setAutoReadOnlyDataSource(false); + config.setReadOnlyDataSource(null); + config.setReadOnlyDataSourceConfig(new DataSourceConfig()); + + Properties props = new Properties(); + props.setProperty("persistBatch", "ALL"); + props.setProperty("persistBatchOnCascade", "ALL"); + props.setProperty("dbuuid", "binary"); + props.setProperty("jdbcFetchSizeFindEach", "42"); + props.setProperty("jdbcFetchSizeFindList", "43"); + props.setProperty("backgroundExecutorShutdownSecs", "98"); + props.setProperty("backgroundExecutorSchedulePoolSize", "4"); + props.setProperty("dbOffline", "true"); + props.setProperty("jsonDateTime", "MILLIS"); + props.setProperty("jsonDate", "MILLIS"); + props.setProperty("jsonMutationDetection", "NONE"); + props.setProperty("autoReadOnlyDataSource", "true"); + props.setProperty("disableL2Cache", "true"); + props.setProperty("notifyL2CacheInForeground", "true"); + props.setProperty("idType", "SEQUENCE"); + props.setProperty("mappingLocations", "classpath:/foo;bar"); + props.setProperty("namingConvention", "io.ebean.config.MatchingNamingConvention"); + props.setProperty("idGeneratorAutomatic", "true"); + props.setProperty("enabledL2Regions", "r0,users,orgs"); + props.setProperty("caseSensitiveCollation", "false"); + props.setProperty("loadModuleInfo", "true"); + props.setProperty("forUpdateNoKey", "true"); + props.setProperty("defaultServer", "false"); + + props.setProperty("queryPlan.enable", "true"); + props.setProperty("queryPlan.thresholdMicros", "10000"); + props.setProperty("queryPlan.capture", "true"); + props.setProperty("queryPlan.capturePeriodSecs", "42"); + props.setProperty("queryPlan.captureMaxTimeMillis", "560"); + props.setProperty("queryPlan.captureMaxCount", "7"); + + config.loadFromProperties(props); + + assertFalse(config.isDefaultServer()); + assertTrue(config.isDisableL2Cache()); + assertTrue(config.isNotifyL2CacheInForeground()); + assertTrue(config.isDbOffline()); + assertTrue(config.isAutoReadOnlyDataSource()); + assertTrue(config.isAutoLoadModuleInfo()); + + assertTrue(config.isIdGeneratorAutomatic()); + assertFalse(config.getPlatformConfig().isCaseSensitiveCollation()); + assertTrue(config.getPlatformConfig().isForUpdateNoKey()); + + assertThat(config.getNamingConvention()).isInstanceOf(MatchingNamingConvention.class); + + assertEquals(MutationDetection.NONE, config.getJsonMutationDetection()); + config.setJsonMutationDetection(MutationDetection.SOURCE); + assertEquals(MutationDetection.SOURCE, config.getJsonMutationDetection()); + assertEquals(IdType.SEQUENCE, config.getIdType()); + assertEquals(PersistBatch.ALL, config.getPersistBatch()); + assertEquals(PersistBatch.ALL, config.getPersistBatchOnCascade()); + assertEquals(PlatformConfig.DbUuid.BINARY, config.getPlatformConfig().getDbUuid()); + assertEquals(JsonConfig.DateTime.MILLIS, config.getJsonDateTime()); + assertEquals(JsonConfig.Date.MILLIS, config.getJsonDate()); + + assertEquals("r0,users,orgs", config.getEnabledL2Regions()); + + assertEquals(42, config.getJdbcFetchSizeFindEach()); + assertEquals(43, config.getJdbcFetchSizeFindList()); + assertEquals(4, config.getBackgroundExecutorSchedulePoolSize()); + assertEquals(98, config.getBackgroundExecutorShutdownSecs()); + + assertTrue(config.isQueryPlanEnable()); + assertEquals(10000, config.getQueryPlanThresholdMicros()); + assertTrue(config.isQueryPlanCapture()); + assertEquals(42, config.getQueryPlanCapturePeriodSecs()); + assertEquals(560, config.getQueryPlanCaptureMaxTimeMillis()); + assertEquals(7, config.getQueryPlanCaptureMaxCount()); + + assertThat(config.getMappingLocations()).containsExactly("classpath:/foo","bar"); + + config.setPersistBatch(PersistBatch.NONE); + config.setPersistBatchOnCascade(PersistBatch.NONE); + + Properties props1 = new Properties(); + props1.setProperty("ebean.persistBatch", "ALL"); + props1.setProperty("ebean.persistBatchOnCascade", "ALL"); + + config.setNotifyL2CacheInForeground(true); + config.setDisableL2Cache(true); + props1.setProperty("ebean.disableL2Cache", "false"); + props1.setProperty("ebean.notifyL2CacheInForeground", "false"); + + config.loadFromProperties(props1); + assertFalse(config.isDisableL2Cache()); + assertFalse(config.isNotifyL2CacheInForeground()); + + assertEquals(PersistBatch.ALL, config.getPersistBatch()); + assertEquals(PersistBatch.ALL, config.getPersistBatchOnCascade()); + + config.setEnabledL2Regions("r0,orgs"); + assertEquals("r0,orgs", config.getEnabledL2Regions()); + } + + @Test + public void test_defaults() { + + DatabaseConfig config = new DatabaseConfig(); + assertTrue(config.isIdGeneratorAutomatic()); + assertTrue(config.isDefaultServer()); + assertFalse(config.isAutoPersistUpdates()); + + config.setIdGeneratorAutomatic(false); + assertFalse(config.isIdGeneratorAutomatic()); + assertEquals(JsonConfig.DateTime.ISO8601, config.getJsonDateTime()); + assertEquals(JsonConfig.Date.ISO8601, config.getJsonDate()); + assertEquals(MutationDetection.HASH, config.getJsonMutationDetection()); + assertTrue(config.getPlatformConfig().isCaseSensitiveCollation()); + assertTrue(config.isAutoLoadModuleInfo()); + + assertFalse(config.isQueryPlanEnable()); + assertEquals(Long.MAX_VALUE, config.getQueryPlanThresholdMicros()); + assertFalse(config.isQueryPlanCapture()); + assertEquals(600, config.getQueryPlanCapturePeriodSecs()); + assertEquals(10000L, config.getQueryPlanCaptureMaxTimeMillis()); + assertEquals(10, config.getQueryPlanCaptureMaxCount()); + + config.setLoadModuleInfo(false); + assertFalse(config.isAutoLoadModuleInfo()); + config.setAutoPersistUpdates(true); + assertTrue(config.isAutoPersistUpdates()); + } + + @Test + public void test_putServiceObject() { + + ObjectMapper objectMapper = new ObjectMapper(); + + DatabaseConfig config = new DatabaseConfig(); + config.putServiceObject(objectMapper); + + ObjectMapper mapper0 = config.getServiceObject(ObjectMapper.class); + ObjectMapper mapper1 = (ObjectMapper)config.getServiceObject("objectMapper"); + + assertThat(objectMapper).isSameAs(mapper0); + assertThat(objectMapper).isSameAs(mapper1); + } +} diff --git a/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java b/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java deleted file mode 100644 index 46f283e55..000000000 --- a/ebean-core/src/test/java/io/ebean/config/ServerConfigTest.java +++ /dev/null @@ -1,194 +0,0 @@ -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; -import org.junit.Test; - -import java.util.Properties; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class ServerConfigTest { - - @Test - public void testLoadFromEbeanProperties() { - - ServerConfig serverConfig = new ServerConfig(); - serverConfig.loadFromProperties(); - - assertEquals(PersistBatch.NONE, serverConfig.getPersistBatch()); - assertNotNull(serverConfig.getProperties()); - } - - @Test - public void evalPropertiesInput() { - - String home = System.getenv("HOME"); - - Properties props = new Properties(); - props.setProperty("ddl.initSql", "${HOME}/initSql"); - - ServerConfig serverConfig = new ServerConfig(); - serverConfig.loadFromProperties(props); - - String ddlInitSql = serverConfig.getDdlInitSql(); - assertThat(ddlInitSql).isEqualTo(home+"/initSql"); - } - - @Test - public void testLoadWithProperties() { - - ServerConfig serverConfig = new ServerConfig(); - serverConfig.setPersistBatch(PersistBatch.NONE); - serverConfig.setPersistBatchOnCascade(PersistBatch.NONE); - serverConfig.setAutoReadOnlyDataSource(false); - serverConfig.setReadOnlyDataSource(null); - serverConfig.setReadOnlyDataSourceConfig(new DataSourceConfig()); - - Properties props = new Properties(); - props.setProperty("persistBatch", "ALL"); - props.setProperty("persistBatchOnCascade", "ALL"); - props.setProperty("dbuuid", "binary"); - props.setProperty("jdbcFetchSizeFindEach", "42"); - props.setProperty("jdbcFetchSizeFindList", "43"); - props.setProperty("backgroundExecutorShutdownSecs", "98"); - props.setProperty("backgroundExecutorSchedulePoolSize", "4"); - props.setProperty("dbOffline", "true"); - props.setProperty("jsonDateTime", "MILLIS"); - props.setProperty("jsonDate", "MILLIS"); - props.setProperty("jsonMutationDetection", "NONE"); - props.setProperty("autoReadOnlyDataSource", "true"); - props.setProperty("disableL2Cache", "true"); - props.setProperty("notifyL2CacheInForeground", "true"); - props.setProperty("idType", "SEQUENCE"); - props.setProperty("mappingLocations", "classpath:/foo;bar"); - props.setProperty("namingConvention", "io.ebean.config.MatchingNamingConvention"); - props.setProperty("idGeneratorAutomatic", "true"); - props.setProperty("enabledL2Regions", "r0,users,orgs"); - props.setProperty("caseSensitiveCollation", "false"); - props.setProperty("loadModuleInfo", "true"); - props.setProperty("forUpdateNoKey", "true"); - props.setProperty("defaultServer", "false"); - - props.setProperty("queryPlan.enable", "true"); - props.setProperty("queryPlan.thresholdMicros", "10000"); - props.setProperty("queryPlan.capture", "true"); - props.setProperty("queryPlan.capturePeriodSecs", "42"); - props.setProperty("queryPlan.captureMaxTimeMillis", "560"); - props.setProperty("queryPlan.captureMaxCount", "7"); - - serverConfig.loadFromProperties(props); - - assertFalse(serverConfig.isDefaultServer()); - assertTrue(serverConfig.isDisableL2Cache()); - assertTrue(serverConfig.isNotifyL2CacheInForeground()); - assertTrue(serverConfig.isDbOffline()); - assertTrue(serverConfig.isAutoReadOnlyDataSource()); - assertTrue(serverConfig.isAutoLoadModuleInfo()); - - assertTrue(serverConfig.isIdGeneratorAutomatic()); - assertFalse(serverConfig.getPlatformConfig().isCaseSensitiveCollation()); - assertTrue(serverConfig.getPlatformConfig().isForUpdateNoKey()); - - 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()); - assertEquals(PlatformConfig.DbUuid.BINARY, serverConfig.getPlatformConfig().getDbUuid()); - assertEquals(JsonConfig.DateTime.MILLIS, serverConfig.getJsonDateTime()); - assertEquals(JsonConfig.Date.MILLIS, serverConfig.getJsonDate()); - - assertEquals("r0,users,orgs", serverConfig.getEnabledL2Regions()); - - assertEquals(42, serverConfig.getJdbcFetchSizeFindEach()); - assertEquals(43, serverConfig.getJdbcFetchSizeFindList()); - assertEquals(4, serverConfig.getBackgroundExecutorSchedulePoolSize()); - assertEquals(98, serverConfig.getBackgroundExecutorShutdownSecs()); - - assertTrue(serverConfig.isQueryPlanEnable()); - assertEquals(10000, serverConfig.getQueryPlanThresholdMicros()); - assertTrue(serverConfig.isQueryPlanCapture()); - assertEquals(42, serverConfig.getQueryPlanCapturePeriodSecs()); - assertEquals(560, serverConfig.getQueryPlanCaptureMaxTimeMillis()); - assertEquals(7, serverConfig.getQueryPlanCaptureMaxCount()); - - assertThat(serverConfig.getMappingLocations()).containsExactly("classpath:/foo","bar"); - - serverConfig.setPersistBatch(PersistBatch.NONE); - serverConfig.setPersistBatchOnCascade(PersistBatch.NONE); - - Properties props1 = new Properties(); - props1.setProperty("ebean.persistBatch", "ALL"); - props1.setProperty("ebean.persistBatchOnCascade", "ALL"); - - serverConfig.setNotifyL2CacheInForeground(true); - serverConfig.setDisableL2Cache(true); - props1.setProperty("ebean.disableL2Cache", "false"); - props1.setProperty("ebean.notifyL2CacheInForeground", "false"); - - serverConfig.loadFromProperties(props1); - assertFalse(serverConfig.isDisableL2Cache()); - assertFalse(serverConfig.isNotifyL2CacheInForeground()); - - assertEquals(PersistBatch.ALL, serverConfig.getPersistBatch()); - assertEquals(PersistBatch.ALL, serverConfig.getPersistBatchOnCascade()); - - serverConfig.setEnabledL2Regions("r0,orgs"); - assertEquals("r0,orgs", serverConfig.getEnabledL2Regions()); - } - - @Test - public void test_defaults() { - - ServerConfig serverConfig = new ServerConfig(); - assertTrue(serverConfig.isIdGeneratorAutomatic()); - assertTrue(serverConfig.isDefaultServer()); - assertFalse(serverConfig.isAutoPersistUpdates()); - - serverConfig.setIdGeneratorAutomatic(false); - 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()); - - assertFalse(serverConfig.isQueryPlanEnable()); - assertEquals(Long.MAX_VALUE, serverConfig.getQueryPlanThresholdMicros()); - assertFalse(serverConfig.isQueryPlanCapture()); - assertEquals(600, serverConfig.getQueryPlanCapturePeriodSecs()); - assertEquals(10000L, serverConfig.getQueryPlanCaptureMaxTimeMillis()); - assertEquals(10, serverConfig.getQueryPlanCaptureMaxCount()); - - serverConfig.setLoadModuleInfo(false); - assertFalse(serverConfig.isAutoLoadModuleInfo()); - serverConfig.setAutoPersistUpdates(true); - assertTrue(serverConfig.isAutoPersistUpdates()); - } - - @Test - public void test_putServiceObject() { - - ObjectMapper objectMapper = new ObjectMapper(); - - ServerConfig config = new ServerConfig(); - config.putServiceObject(objectMapper); - - ObjectMapper mapper0 = config.getServiceObject(ObjectMapper.class); - ObjectMapper mapper1 = (ObjectMapper)config.getServiceObject("objectMapper"); - - assertThat(objectMapper).isSameAs(mapper0); - assertThat(objectMapper).isSameAs(mapper1); - } -} From 9a82dbb3e6e22bfac5799cdb0ea405eb354e05aa Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 5 Aug 2021 13:17:32 +1200 Subject: [PATCH 046/120] Bump parent to java8-oss 3.2 with GPG maven plugin active only with "release" profile The GPG maven plugin is now only active with the "release" profile use -P release when we want to release with GPG signing --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0328ea5b6..465b49402 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.avaje java8-oss - 3.1 + 3.2 io.ebean From d98a31fa6b64f9dbf0cb57b018c4a6fb38561beb Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 5 Aug 2021 16:53:51 +1200 Subject: [PATCH 047/120] Bump to 12.11.0-SNAPSHOT --- ebean-api/pom.xml | 2 +- ebean-autotune/pom.xml | 4 ++-- ebean-bom/pom.xml | 30 +++++++++++++++--------------- ebean-core-type/pom.xml | 4 ++-- ebean-core/pom.xml | 8 ++++---- ebean-ddl-generator/pom.xml | 6 +++--- ebean-externalmapping-api/pom.xml | 2 +- ebean-externalmapping-xml/pom.xml | 8 ++++---- ebean-postgis/pom.xml | 6 +++--- ebean-querybean/pom.xml | 10 +++++----- ebean-redis/pom.xml | 12 ++++++------ ebean-test/pom.xml | 6 +++--- ebean/pom.xml | 8 ++++---- kotlin-querybean-generator/pom.xml | 8 ++++---- pom.xml | 2 +- querybean-generator/pom.xml | 2 +- 16 files changed, 59 insertions(+), 59 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 503c2f2c5..9afbb6446 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean api diff --git a/ebean-autotune/pom.xml b/ebean-autotune/pom.xml index 1534f122b..0b0355981 100644 --- a/ebean-autotune/pom.xml +++ b/ebean-autotune/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT @@ -26,7 +26,7 @@ io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index 0e6ebde4d..9f79cc9c2 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean bom @@ -81,88 +81,88 @@ io.ebean ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-api - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-core-type - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-ddl-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-externalmapping-api - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-externalmapping-xml - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-autotune - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-querybean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean querybean-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided io.ebean kotlin-querybean-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided io.ebean ebean-test - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test io.ebean ebean-postgis - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-redis - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml index ad1d7c207..35a29a677 100644 --- a/ebean-core-type/pom.xml +++ b/ebean-core-type/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean-core-type @@ -16,7 +16,7 @@ io.ebean ebean-api - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index 8303c519d..cfac597fa 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -3,7 +3,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean-core @@ -87,19 +87,19 @@ io.ebean ebean-api - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-core-type - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-externalmapping-api - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index dec77c4b0..d7267945e 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean ddl generation @@ -28,14 +28,14 @@ io.ebean ebean-core-type - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided diff --git a/ebean-externalmapping-api/pom.xml b/ebean-externalmapping-api/pom.xml index 5cb459f61..a9b9968b9 100644 --- a/ebean-externalmapping-api/pom.xml +++ b/ebean-externalmapping-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean external mapping api diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index 8275fc989..0ce9ce6ca 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT @@ -33,7 +33,7 @@ io.ebean ebean-externalmapping-api - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT @@ -59,14 +59,14 @@ io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test io.ebean ebean-ddl-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml index ff1beee77..a6bfe2ed0 100644 --- a/ebean-postgis/pom.xml +++ b/ebean-postgis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean postgis @@ -23,7 +23,7 @@ io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided @@ -74,7 +74,7 @@ io.ebean ebean-test - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml index d9a2cdd6e..b3ffadfc0 100644 --- a/ebean-querybean/pom.xml +++ b/ebean-querybean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean querybean @@ -17,7 +17,7 @@ io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided @@ -57,21 +57,21 @@ io.ebean ebean-ddl-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test io.ebean querybean-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test io.ebean ebean-test - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index 097cd9318..d0d5f8ee2 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean-redis @@ -22,35 +22,35 @@ io.ebean ebean-api - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided io.ebean ebean-querybean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test io.ebean querybean-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test io.ebean ebean-test - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index e889b6204..43b5ee6f3 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean test @@ -29,14 +29,14 @@ io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT provided io.ebean ebean-ddl-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT diff --git a/ebean/pom.xml b/ebean/pom.xml index ddd60d284..819328290 100644 --- a/ebean/pom.xml +++ b/ebean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT ebean composite @@ -22,20 +22,20 @@ io.ebean ebean-api - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT io.ebean ebean-querybean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml index c3a487ecf..8f3cafa8a 100644 --- a/kotlin-querybean-generator/pom.xml +++ b/kotlin-querybean-generator/pom.xml @@ -5,7 +5,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT kotlin querybean generator @@ -30,7 +30,7 @@ io.ebean ebean-querybean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test @@ -44,7 +44,7 @@ io.ebean ebean-core - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test @@ -65,7 +65,7 @@ io.ebean ebean-ddl-generator - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT test diff --git a/pom.xml b/pom.xml index 465b49402..b86928387 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.ebean ebean-parent - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT pom ebean parent diff --git a/querybean-generator/pom.xml b/querybean-generator/pom.xml index 27e5d0399..956e39cb5 100644 --- a/querybean-generator/pom.xml +++ b/querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.10.1-SNAPSHOT + 12.11.0-SNAPSHOT querybean generator From f34e0f5f2b8536f8d452818b0f04582f89c3bf72 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 5 Aug 2021 23:03:02 +1200 Subject: [PATCH 048/120] #2287 - ebean-migration: For multiple platforms automatically run the correct migrations --- ebean-bom/pom.xml | 8 +++--- ebean-core/pom.xml | 4 +-- .../server/core/DefaultServer.java | 1 + .../server/core/bootup/BootupClasses.java | 27 +++---------------- ebean-ddl-generator/pom.xml | 2 +- .../dbmigration/DefaultDbMigration.java | 9 +++---- .../dbmigration/IndexMigration.java | 5 +--- .../dbmigration/IndexMigrationTest.java | 4 +-- ebean-externalmapping-xml/pom.xml | 2 +- .../xmlmapping/XmlMappingReader.java | 3 +-- 10 files changed, 21 insertions(+), 44 deletions(-) diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index 9f79cc9c2..35ed6d6a0 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -14,12 +14,12 @@ 1.0 - 1.0 - 12.4.0 + 1.1 + 12.11.0 4.1 7.0 - 12.10.0 - 12.10.0 + 12.11.0 + 12.11.0 diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index cfac597fa..3426582d3 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -52,13 +52,13 @@ io.avaje classpath-scanner - 4.2 + 6.0 io.ebean ebean-migration-auto - 1.0 + 1.1 diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index 4aa90ad13..d21f9967f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -397,6 +397,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { if (dbSchema != null) { migrationRunner.setDefaultDbSchema(dbSchema); } + migrationRunner.setPlatform(config.getDatabasePlatform().getPlatform().base().name().toLowerCase()); migrationRunner.loadProperties(config.getProperties()); migrationRunner.run(config.getDataSource()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/bootup/BootupClasses.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/bootup/BootupClasses.java index f7c1a5fea..aba5533e0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/bootup/BootupClasses.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/bootup/BootupClasses.java @@ -1,6 +1,5 @@ package io.ebeaninternal.server.core.bootup; -import io.avaje.classpath.scanner.ClassFilter; import io.ebean.annotation.DocStore; import io.ebean.config.DatabaseConfig; import io.ebean.config.IdGenerator; @@ -27,27 +26,23 @@ import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.Table; import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; /** * Interesting classes for a EbeanServer such as Embeddable, Entity, * ScalarTypes, Finders, Listeners and Controllers. */ -public class BootupClasses implements ClassFilter { +public class BootupClasses implements Predicate> { private static final Logger logger = LoggerFactory.getLogger(BootupClasses.class); private final List> embeddableList = new ArrayList<>(); - private final List> entityList = new ArrayList<>(); - private final List>> scalarTypeList = new ArrayList<>(); - private final List>> scalarConverterList = new ArrayList<>(); - private final List>> attributeConverterList = new ArrayList<>(); // The following objects are instantiated on first request @@ -55,19 +50,12 @@ public class BootupClasses implements ClassFilter { // instance list, that holds the instance. Once a class is instantiated // (or added) it will get removed from the candidate list private final List> idGeneratorCandidates = new ArrayList<>(); - private final List> beanPersistControllerCandidates = new ArrayList<>(); - private final List> beanPostLoadCandidates = new ArrayList<>(); - private final List> beanPostConstructListenerCandidates = new ArrayList<>(); - private final List> beanFindControllerCandidates = new ArrayList<>(); - private final List> beanPersistListenerCandidates = new ArrayList<>(); - private final List> beanQueryAdapterCandidates = new ArrayList<>(); - private final List> serverConfigStartupCandidates = new ArrayList<>(); private final List idGeneratorInstances = new ArrayList<>(); @@ -98,7 +86,7 @@ public class BootupClasses implements ClassFilter { public BootupClasses(List> list) { if (list != null) { for (Class cls : list) { - isMatch(cls); + test(cls); } } } @@ -188,13 +176,11 @@ public class BootupClasses implements ClassFilter { } public void addChangeLogInstances(DatabaseConfig config) { - readAuditPrepare = config.getReadAuditPrepare(); readAuditLogger = config.getReadAuditLogger(); changeLogPrepare = config.getChangeLogPrepare(); changeLogListener = config.getChangeLogListener(); changeLogRegister = config.getChangeLogRegister(); - // if not already set create the implementations found // via classpath scanning if (readAuditPrepare == null && readAuditPrepareClass != null) { @@ -341,18 +327,14 @@ public class BootupClasses implements ClassFilter { } @Override - public boolean isMatch(Class cls) { - + public boolean test(Class cls) { if (isEmbeddable(cls)) { embeddableList.add(cls); - } else if (isEntity(cls)) { entityList.add(cls); - } else { return isInterestingInterface(cls); } - return true; } @@ -364,7 +346,6 @@ public class BootupClasses implements ClassFilter { */ @SuppressWarnings("unchecked") private boolean isInterestingInterface(Class cls) { - if (Modifier.isAbstract(cls.getModifiers())) { // do not include abstract classes as we can // not instantiate them diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index d7267945e..4035af5f2 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -22,7 +22,7 @@ io.ebean ebean-migration - 12.4.0 + 12.11.0 diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index 7f2a90558..5bb40fa08 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -281,7 +281,7 @@ public class DefaultDbMigration implements DbMigration { public String generateMigration() throws IOException { final String version = generateMigrationFor(false); if (includeIndex) { - generateIndex(version); + generateIndex(); } return version; } @@ -289,15 +289,14 @@ public class DefaultDbMigration implements DbMigration { /** * Generate the {@code idx_platform.migrations} file. */ - private void generateIndex(String version) throws IOException { - final boolean overwrite = version != null; + private void generateIndex() throws IOException { final File topDir = migrationDirectory(false); if (!platforms.isEmpty()) { for (Pair pair : platforms) { - new IndexMigration(topDir, pair).generate(overwrite); + new IndexMigration(topDir, pair).generate(); } } else { - new IndexMigration(topDir, databasePlatform).generate(overwrite); + new IndexMigration(topDir, databasePlatform).generate(); } } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/IndexMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/IndexMigration.java index 215c18e72..baedb77b9 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/IndexMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/IndexMigration.java @@ -43,10 +43,7 @@ class IndexMigration { return new File(topDir, name); } - void generate(boolean overwrite) throws IOException { - if (!overwrite && indexFile.exists()) { - return; - } + void generate() throws IOException { readSqlFiles(topDir); generateIndex(); } diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/IndexMigrationTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/IndexMigrationTest.java index 5a04d8917..a22a42ec7 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/IndexMigrationTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/IndexMigrationTest.java @@ -24,7 +24,7 @@ public class IndexMigrationTest { } DatabasePlatform pg = new PostgresPlatform(); IndexMigration indexMigration = new IndexMigration(topDir, pg); - indexMigration.generate(true); + indexMigration.generate(); File expected = new File(topDir, "idx_postgres.migrations"); @@ -48,7 +48,7 @@ public class IndexMigrationTest { } DatabasePlatform pg = new H2Platform(); IndexMigration indexMigration = new IndexMigration(topDir, pg); - indexMigration.generate(true); + indexMigration.generate(); File expected = new File(topDir, "idx_h2.migrations"); assertThat(expected).exists(); diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index 0ce9ce6ca..3f0b71546 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -45,7 +45,7 @@ io.avaje classpath-scanner - 4.2 + 6.0 diff --git a/ebean-externalmapping-xml/src/main/java/io/ebeaninternal/xmlmapping/XmlMappingReader.java b/ebean-externalmapping-xml/src/main/java/io/ebeaninternal/xmlmapping/XmlMappingReader.java index 2519ef8f1..8b28975ef 100644 --- a/ebean-externalmapping-xml/src/main/java/io/ebeaninternal/xmlmapping/XmlMappingReader.java +++ b/ebean-externalmapping-xml/src/main/java/io/ebeaninternal/xmlmapping/XmlMappingReader.java @@ -6,7 +6,6 @@ import io.ebeaninternal.xmlmapping.model.XmEbean; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -59,7 +58,7 @@ public class XmlMappingReader { try { List mappings = new ArrayList<>(); for (Resource xmlMappingRes : resourceList) { - try (InputStream is = new FileInputStream(xmlMappingRes.getLocationOnDisk())) { + try (InputStream is = xmlMappingRes.inputStream()) { mappings.add(XmlMappingReader.read(is)); } } From 7ca72a39b1c2cce8a35b2e79871145e4c5970498 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 6 Aug 2021 11:52:38 +1200 Subject: [PATCH 049/120] Change query metric hash from MD5 of sql + name + loc to Checksum of sql --- .../java/io/ebean/meta/MetaQueryMetric.java | 2 +- .../java/io/ebean/meta/MetaQueryPlan.java | 2 +- .../main/java/io/ebean/meta/MetricData.java | 6 ++-- .../java/io/ebean/meta/QueryPlanInit.java | 10 +++--- .../io/ebeaninternal/api/SpiQueryPlan.java | 2 +- .../server/core/DumpMetricsJson.java | 19 ++++++------ .../server/profile/DQueryPlanMeta.java | 16 +++------- .../server/profile/DQueryPlanMetric.java | 2 +- .../server/query/CQueryPlan.java | 25 +++------------ .../server/query/CQueryPlanStats.java | 2 +- .../server/query/DQueryPlanOutput.java | 7 ++--- .../io/ebeaninternal/server/util/Md5.java | 31 ------------------- .../io/ebeaninternal/server/util/Md5Test.java | 18 ----------- .../query/finder/TestCustomerFinder.java | 2 +- 14 files changed, 36 insertions(+), 108 deletions(-) delete mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java delete mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/util/Md5Test.java diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java index 514b700dc..edfe978e5 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java @@ -23,6 +23,6 @@ public interface MetaQueryMetric extends MetaTimedMetric { /** * Return the hash of the plan. */ - String getHash(); + long getHash(); } diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java b/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java index fb2b6d095..4f9667bd0 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java @@ -30,7 +30,7 @@ public interface MetaQueryPlan { /** * Return the hash of the plan. */ - String getHash(); + long getHash(); /** * Return a description of the bind values. diff --git a/ebean-api/src/main/java/io/ebean/meta/MetricData.java b/ebean-api/src/main/java/io/ebean/meta/MetricData.java index b4606b1d7..9a24aa9f2 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetricData.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetricData.java @@ -6,7 +6,7 @@ package io.ebean.meta; public class MetricData { private String name; - private String hash; + private long hash; private String loc; private String sql; @@ -30,11 +30,11 @@ public class MetricData { this.name = name; } - public String getHash() { + public long getHash() { return hash; } - public void setHash(String hash) { + public void setHash(long hash) { this.hash = hash; } diff --git a/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java b/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java index 3c19caa39..9b785ec62 100644 --- a/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java +++ b/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java @@ -10,7 +10,7 @@ public class QueryPlanInit { private boolean all; - private Set hashes = new HashSet<>(); + private Set hashes = new HashSet<>(); private long thresholdMicros; @@ -47,21 +47,21 @@ public class QueryPlanInit { /** * Return true if the query plan should be initiated based on it's hash. */ - public boolean includeHash(String hash) { - return all || hashes.contains(hash); + public boolean includeHash(long sqlHash) { + return all || hashes.contains(sqlHash); } /** * Return the specific hashes that we want to collect query plans on. */ - public Set getHashes() { + public Set getHashes() { return hashes; } /** * Set the specific hashes that we want to collect query plans on. */ - public void setHashes(Set hashes) { + public void setHashes(Set hashes) { this.hashes = hashes; } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java index 96a1eade7..cd6c83114 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java @@ -20,7 +20,7 @@ public interface SpiQueryPlan { /** * The hash for the query plan. */ - String getHash(); + long getHash(); /** * The SQL for the query plan. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java index ed13151c4..240d050f3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java @@ -197,7 +197,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { metricStart(metric); appendTiming(metric); if (withHash) { - appendExtra("hash", metric.getHash()); + keyVal("hash", metric.getHash()); } if (isIncludeDetail(metric)) { appendExtra("loc", metric.getLocation()); @@ -218,13 +218,14 @@ class DumpMetricsJson implements ServerMetricsAsJson { } private void appendTiming(MetaTimedMetric timedMetric) throws IOException { - key("count"); - val(timedMetric.getCount()); - key("total"); - val(timedMetric.getTotal()); - key("mean"); - val(timedMetric.getMean()); - key("max"); - val(timedMetric.getMax()); + keyVal("count", timedMetric.getCount()); + keyVal("total", timedMetric.getTotal()); + keyVal("mean", timedMetric.getMean()); + keyVal("max", timedMetric.getMax()); + } + + private void keyVal(String key, long value) throws IOException { + key(key); + val(value); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java index 0690b5fdd..0f25f0d9c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.profile; import io.ebean.ProfileLocation; -import io.ebeaninternal.server.util.Md5; +import io.ebeaninternal.server.util.Checksum; class DQueryPlanMeta { @@ -10,7 +10,7 @@ class DQueryPlanMeta { private final ProfileLocation profileLocation; private final String name; private final String sql; - private final String hash; + private final long hash; DQueryPlanMeta(Class type, String label, ProfileLocation profileLocation, String sql) { this.type = type; @@ -22,22 +22,14 @@ class DQueryPlanMeta { name += "_" + label; } this.name = name; - this.hash = initHash(); - } - - private String initHash() { - StringBuilder sb = new StringBuilder(sql).append("|").append(name); - if (profileLocation != null) { - sb.append("|").append(profileLocation.location()); - } - return Md5.hash(sb.toString()); + this.hash = Checksum.checksum(sql); } public Class getType() { return type; } - public String getHash() { + public long getHash() { return hash; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java index 21559a152..765679404 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java @@ -59,7 +59,7 @@ class DQueryPlanMetric implements QueryPlanMetric { } @Override - public String getHash() { + public long getHash() { return meta.getHash(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java index 295cbe7c2..3c322190f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java @@ -13,12 +13,12 @@ import io.ebeaninternal.api.SpiQueryBindCapture; import io.ebeaninternal.api.SpiQueryPlan; import io.ebeaninternal.server.core.OrmQueryRequest; import io.ebeaninternal.server.core.timezone.DataTimeZone; +import io.ebeaninternal.server.util.Checksum; import io.ebeaninternal.server.util.Str; import io.ebeaninternal.server.query.CQueryPlanStats.Snapshot; import io.ebeaninternal.server.type.DataBind; import io.ebeaninternal.server.type.DataBindCapture; import io.ebeaninternal.server.type.RsetDataReader; -import io.ebeaninternal.server.util.Md5; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,7 +68,7 @@ public class CQueryPlan implements SpiQueryPlan { private final boolean rawSql; private final String sql; - private final String hash; + private final long hash; private final String logWhereSql; @@ -118,7 +118,7 @@ public class CQueryPlan implements SpiQueryPlan { this.stats = new CQueryPlanStats(this); this.dependentTables = sqlTree.dependentTables(); this.bindCapture = initBindCapture(query); - this.hash = md5Hash(); + this.hash = Checksum.checksum(sql); } /** @@ -143,7 +143,7 @@ public class CQueryPlan implements SpiQueryPlan { this.stats = new CQueryPlanStats(this); this.dependentTables = sqlTree.dependentTables(); this.bindCapture = initBindCaptureRaw(sql, query); - this.hash = md5Hash(); + this.hash = Checksum.checksum(sql); } private String deriveName(String label, SpiQuery.Type type, String simpleName) { @@ -193,7 +193,7 @@ public class CQueryPlan implements SpiQueryPlan { } @Override - public String getHash() { + public long getHash() { return hash; } @@ -276,21 +276,6 @@ public class CQueryPlan implements SpiQueryPlan { return rawSql ? planKey.getPartialKey() + "_" + hash : planKey.getPartialKey(); } - /** - * Return the MD5 hash of the sql. - */ - private String md5Hash() { - StringBuilder sb = new StringBuilder(sql) - .append("|").append(name) - .append("|").append(location); - try { - return Md5.hash(sb.toString()); - } catch (Exception e) { - logger.error("Failed to MD5 hash the query", e); - return "error"; - } - } - SqlTree getSqlTree() { return sqlTree; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java index 23de6de5c..3f7f61070 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java @@ -127,7 +127,7 @@ public final class CQueryPlanStats { } @Override - public String getHash() { + public long getHash() { return queryPlan.getHash(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java index 8065a62dc..3d8c7aaac 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java @@ -16,12 +16,11 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { private final String sql; private final String bind; private final String plan; - - private String hash; + private final long hash; private long queryTimeMicros; private long captureCount; - DQueryPlanOutput(Class beanType, String label, String hash, String sql, ProfileLocation profileLocation, String bind, String plan) { + DQueryPlanOutput(Class beanType, String label, long hash, String sql, ProfileLocation profileLocation, String bind, String plan) { this.beanType = beanType; this.label = label; this.hash = hash; @@ -32,7 +31,7 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { } @Override - public String getHash() { + public long getHash() { return hash; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java deleted file mode 100644 index 7329d3f25..000000000 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.ebeaninternal.server.util; - -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; - -public final class Md5 { - - /** - * Return the MD5 hash of the underlying sql. - */ - public static String hash(String content) { - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - return digestToHex(md.digest(content.getBytes(StandardCharsets.UTF_8))); - } catch (Exception e) { - throw new RuntimeException("MD5 hashing failed", e); - } - } - - /** - * Convert the digest into a hex value. - */ - private static String digestToHex(byte[] digest) { - StringBuilder sb = new StringBuilder(); - for (byte aDigest : digest) { - sb.append(Integer.toString((aDigest & 0xff) + 0x100, 16).substring(1)); - } - return sb.toString(); - } - -} diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/util/Md5Test.java b/ebean-core/src/test/java/io/ebeaninternal/server/util/Md5Test.java deleted file mode 100644 index d9db27d3d..000000000 --- a/ebean-core/src/test/java/io/ebeaninternal/server/util/Md5Test.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.ebeaninternal.server.util; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -public class Md5Test { - - @Test - public void hash() throws Exception { - - String content = "some random content we wish to hash"; - String hash1 = Md5.hash(content); - String hash2 = Md5.hash(content); - assertEquals(hash1, hash2); - } - -} diff --git a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java index eeefe42c2..8e8c5a288 100644 --- a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java +++ b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java @@ -244,7 +244,7 @@ public class TestCustomerFinder extends BaseTestCase { assertThat(metricsJson).contains("\"name\":\"orm.Customer.findList\""); assertThat(metricsJson).contains("\"loc\":\"CustomerFinder.byNameStatus(CustomerFinder.java:44)\""); if (isH2() || isPostgres()) { - assertThat(metricsJson).contains("\"hash\":\"cc20eb930403cfd418db2d0475c6e26a\""); + assertThat(metricsJson).contains("\"hash\":3634991469"); assertThat(metricsJson).contains("\"sql\":\"select t0.id, t0.status,"); } } From 202d78571012058ec55ace72a453edcc4d9f00d8 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 6 Aug 2021 12:06:43 +1200 Subject: [PATCH 050/120] Rename hash to sqlHash to better reflect what it is (CRC32 checksum of the sql) --- .../main/java/io/ebean/meta/MetaQueryMetric.java | 4 ++-- .../src/main/java/io/ebean/meta/MetricData.java | 10 +++++----- .../java/io/ebeaninternal/api/SpiQueryPlan.java | 4 ++-- .../io/ebeaninternal/server/core/DumpMetrics.java | 2 +- .../ebeaninternal/server/core/DumpMetricsData.java | 2 +- .../ebeaninternal/server/core/DumpMetricsJson.java | 2 +- .../server/deploy/BeanDescriptor.java | 2 +- .../server/profile/DQueryPlanMeta.java | 8 ++++---- .../server/profile/DQueryPlanMetric.java | 4 ++-- .../io/ebeaninternal/server/query/CQueryPlan.java | 14 +++++++------- .../server/query/CQueryPlanStats.java | 4 ++-- .../org/tests/query/finder/TestCustomerFinder.java | 6 +++--- 12 files changed, 31 insertions(+), 31 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java index edfe978e5..e3907c69c 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java @@ -21,8 +21,8 @@ public interface MetaQueryMetric extends MetaTimedMetric { String getSql(); /** - * Return the hash of the plan. + * Return the hash of the sql. */ - long getHash(); + long getSqlHash(); } diff --git a/ebean-api/src/main/java/io/ebean/meta/MetricData.java b/ebean-api/src/main/java/io/ebean/meta/MetricData.java index 9a24aa9f2..d8f80a0a9 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetricData.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetricData.java @@ -6,7 +6,7 @@ package io.ebean.meta; public class MetricData { private String name; - private long hash; + private long sqlHash; private String loc; private String sql; @@ -30,12 +30,12 @@ public class MetricData { this.name = name; } - public long getHash() { - return hash; + public long getSqlHash() { + return sqlHash; } - public void setHash(long hash) { - this.hash = hash; + public void setSqlHash(long sqlHash) { + this.sqlHash = sqlHash; } public String getLoc() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java index cd6c83114..878dcc716 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java @@ -18,9 +18,9 @@ public interface SpiQueryPlan { String getName(); /** - * The hash for the query plan. + * The hash of the sql. */ - long getHash(); + long getSqlHash(); /** * The SQL for the query plan. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java index 972ee2754..4c42c4b11 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java @@ -120,7 +120,7 @@ class DumpMetrics { appendQueryName(metric, sb); appendCounters(metric, sb); if (dumpHash) { - sb.append("\n hash:").append(metric.getHash()); + sb.append("\n sqlHash:").append(metric.getSqlHash()); } appendProfileAndSql(metric, sb); out(sb.toString()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java index 9854cafea..7458d0468 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java @@ -67,7 +67,7 @@ class DumpMetricsData { final MetricData data = create(metric); appendCounters(data, metric); appendLocationAndSql(data, metric); - data.setHash(metric.getHash()); + data.setSqlHash(metric.getSqlHash()); } private void appendLocationAndSql(MetricData data, MetaQueryMetric metric) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java index 240d050f3..6f74dac97 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java @@ -197,7 +197,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { metricStart(metric); appendTiming(metric); if (withHash) { - keyVal("hash", metric.getHash()); + keyVal("sqlHash", metric.getSqlHash()); } if (isIncludeDetail(metric)) { appendExtra("loc", metric.getLocation()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 8f0fea0f2..e08b37d1d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -1558,7 +1558,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { void queryPlanInit(QueryPlanInit request, List list) { for (CQueryPlan queryPlan : queryPlanCache.values()) { - if (request.includeHash(queryPlan.getHash())) { + if (request.includeHash(queryPlan.getSqlHash())) { queryPlan.queryPlanInit(request.getThresholdMicros()); list.add(queryPlan.createMeta(null, null)); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java index 0f25f0d9c..5359d96ed 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java @@ -10,7 +10,7 @@ class DQueryPlanMeta { private final ProfileLocation profileLocation; private final String name; private final String sql; - private final long hash; + private final long sqlHash; DQueryPlanMeta(Class type, String label, ProfileLocation profileLocation, String sql) { this.type = type; @@ -22,15 +22,15 @@ class DQueryPlanMeta { name += "_" + label; } this.name = name; - this.hash = Checksum.checksum(sql); + this.sqlHash = Checksum.checksum(sql); } public Class getType() { return type; } - public long getHash() { - return hash; + public long getSqlHash() { + return sqlHash; } public String getName() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java index 765679404..fda2b62b8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java @@ -59,8 +59,8 @@ class DQueryPlanMetric implements QueryPlanMetric { } @Override - public long getHash() { - return meta.getHash(); + public long getSqlHash() { + return meta.getSqlHash(); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java index 3c322190f..796290808 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java @@ -68,7 +68,7 @@ public class CQueryPlan implements SpiQueryPlan { private final boolean rawSql; private final String sql; - private final long hash; + private final long sqlHash; private final String logWhereSql; @@ -118,7 +118,7 @@ public class CQueryPlan implements SpiQueryPlan { this.stats = new CQueryPlanStats(this); this.dependentTables = sqlTree.dependentTables(); this.bindCapture = initBindCapture(query); - this.hash = Checksum.checksum(sql); + this.sqlHash = Checksum.checksum(sql); } /** @@ -143,7 +143,7 @@ public class CQueryPlan implements SpiQueryPlan { this.stats = new CQueryPlanStats(this); this.dependentTables = sqlTree.dependentTables(); this.bindCapture = initBindCaptureRaw(sql, query); - this.hash = Checksum.checksum(sql); + this.sqlHash = Checksum.checksum(sql); } private String deriveName(String label, SpiQuery.Type type, String simpleName) { @@ -193,8 +193,8 @@ public class CQueryPlan implements SpiQueryPlan { } @Override - public long getHash() { - return hash; + public long getSqlHash() { + return sqlHash; } @Override @@ -226,7 +226,7 @@ public class CQueryPlan implements SpiQueryPlan { @Override public DQueryPlanOutput createMeta(String bind, String planString) { - return new DQueryPlanOutput(getBeanType(), name, hash, sql, profileLocation, bind, planString); + return new DQueryPlanOutput(getBeanType(), name, sqlHash, sql, profileLocation, bind, planString); } public DataReader createDataReader(ResultSet rset) { @@ -273,7 +273,7 @@ public class CQueryPlan implements SpiQueryPlan { private String calcAuditQueryKey() { // rawSql needs to include the MD5 hash of the sql - return rawSql ? planKey.getPartialKey() + "_" + hash : planKey.getPartialKey(); + return rawSql ? planKey.getPartialKey() + "_" + sqlHash : planKey.getPartialKey(); } SqlTree getSqlTree() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java index 3f7f61070..bbcfea2b9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java @@ -127,8 +127,8 @@ public final class CQueryPlanStats { } @Override - public long getHash() { - return queryPlan.getHash(); + public long getSqlHash() { + return queryPlan.getSqlHash(); } @Override diff --git a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java index 8e8c5a288..b6a40903f 100644 --- a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java +++ b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java @@ -216,7 +216,7 @@ public class TestCustomerFinder extends BaseTestCase { assertThat(plans0).isNotEmpty(); for (MetaQueryPlan plan : plans) { - logger.info("queryplan label:{}, queryTimeMicros:{} loc:{} sql:{} bind:{} plan:{}", + logger.info("queryPlan label:{}, queryTimeMicros:{} loc:{} sql:{} bind:{} plan:{}", plan.getLabel(), plan.getQueryTimeMicros(), plan.getProfileLocation(), plan.getSql(), plan.getBind(), plan.getPlan()); System.out.println(plan); @@ -244,7 +244,7 @@ public class TestCustomerFinder extends BaseTestCase { assertThat(metricsJson).contains("\"name\":\"orm.Customer.findList\""); assertThat(metricsJson).contains("\"loc\":\"CustomerFinder.byNameStatus(CustomerFinder.java:44)\""); if (isH2() || isPostgres()) { - assertThat(metricsJson).contains("\"hash\":3634991469"); + assertThat(metricsJson).contains("\"sqlHash\":3634991469"); assertThat(metricsJson).contains("\"sql\":\"select t0.id, t0.status,"); } } @@ -267,7 +267,7 @@ public class TestCustomerFinder extends BaseTestCase { assertThat(metricsJson).contains("\"name\":\"txn.main\""); assertThat(metricsJson).contains("\"name\":\"orm.Customer.findList\""); assertThat(metricsJson).doesNotContain("\"loc\":"); - assertThat(metricsJson).doesNotContain("\"hash\":"); + assertThat(metricsJson).doesNotContain("\"sqlHash\":"); assertThat(metricsJson).doesNotContain("\"sql\":"); } From 801d419f51b4cc56c6804d99da7acba07419e279 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 6 Aug 2021 13:14:29 +1200 Subject: [PATCH 051/120] Refactor io.ebean.meta API, method rename with deprecation --- .../io/ebean/meta/AbstractMetricVisitor.java | 8 +-- .../io/ebean/meta/BasicMetricVisitor.java | 6 +-- .../java/io/ebean/meta/MetaCountMetric.java | 9 +++- .../main/java/io/ebean/meta/MetaMetric.java | 9 +++- .../java/io/ebean/meta/MetaQueryMetric.java | 39 ++++++++++++-- .../java/io/ebean/meta/MetaQueryPlan.java | 18 +++---- .../java/io/ebean/meta/MetaTimedMetric.java | 51 +++++++++++++++++-- .../java/io/ebean/meta/MetricVisitor.java | 8 +-- .../java/io/ebean/meta/QueryPlanInit.java | 8 +-- .../java/io/ebean/meta/QueryPlanRequest.java | 12 ++--- .../java/io/ebean/meta/ServerMetrics.java | 29 +++++++++-- .../io/ebean/meta/ServerMetricsAsJson.java | 4 +- .../main/java/io/ebean/meta/SortMetric.java | 14 ++--- .../server/core/DefaultQueryPlanListener.java | 4 +- .../server/core/DefaultServer.java | 12 ++--- .../server/core/DumpMetrics.java | 28 +++++----- .../server/core/DumpMetricsData.java | 26 +++++----- .../server/core/DumpMetricsJson.java | 26 +++++----- .../server/deploy/BeanDescriptor.java | 4 +- .../server/profile/DCountMetric.java | 6 +-- .../server/profile/DQueryPlanMetric.java | 32 ++++++------ .../server/profile/DTimeMetricStats.java | 12 ++--- .../server/profile/DTimedMetric.java | 2 +- .../server/profile/DTimedProfileLocation.java | 2 +- .../server/query/CQueryPlanRequest.java | 6 +-- .../server/query/CQueryPlanStats.java | 30 +++++------ .../server/query/DQueryPlanOutput.java | 28 +++++----- .../src/test/java/io/ebean/BaseTestCase.java | 4 +- .../src/test/java/io/ebean/DtoQuery2Test.java | 10 ++-- .../java/io/ebean/DtoQueryFromOrmTest.java | 12 ++--- .../src/test/java/io/ebean/DtoQueryTest.java | 16 +++--- .../test/java/io/ebean/UpdateQueryTest.java | 12 ++--- .../server/deploy/BeanIudMetricsTest.java | 34 ++++++------- .../server/profile/DTimedMetricMapTest.java | 12 ++--- .../server/profile/DTimedMetricTest.java | 26 +++++----- .../server/profile/SortMetricTest.java | 2 +- .../batchinsert/TestBatchInsertFlush.java | 10 ++-- .../org/tests/m2m/TestM2mDeleteObject.java | 2 +- .../query/finder/TestCustomerFinder.java | 16 +++--- .../tests/query/sqlquery/SqlQueryTests.java | 2 +- .../transaction/TestNestedMandatory.java | 2 +- .../TestTransactionalReadOnly.java | 10 ++-- .../org/tests/update/TestSqlUpdateInTxn.java | 4 +- .../src/test/java/io/ebean/BaseTestCase.java | 6 +-- .../main/java/io/ebean/redis/RedisCache.java | 7 ++- 45 files changed, 363 insertions(+), 257 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/meta/AbstractMetricVisitor.java b/ebean-api/src/main/java/io/ebean/meta/AbstractMetricVisitor.java index 323b572ec..51df586d9 100644 --- a/ebean-api/src/main/java/io/ebean/meta/AbstractMetricVisitor.java +++ b/ebean-api/src/main/java/io/ebean/meta/AbstractMetricVisitor.java @@ -18,22 +18,22 @@ public abstract class AbstractMetricVisitor implements MetricVisitor { } @Override - public boolean isReset() { + public boolean reset() { return reset; } @Override - public boolean isCollectTransactionMetrics() { + public boolean collectTransactionMetrics() { return collectTransactionMetrics; } @Override - public boolean isCollectQueryMetrics() { + public boolean collectQueryMetrics() { return collectQueryMetrics; } @Override - public boolean isCollectL2Metrics() { + public boolean collectL2Metrics() { return collectL2Metrics; } diff --git a/ebean-api/src/main/java/io/ebean/meta/BasicMetricVisitor.java b/ebean-api/src/main/java/io/ebean/meta/BasicMetricVisitor.java index c821c63a7..0db953159 100644 --- a/ebean-api/src/main/java/io/ebean/meta/BasicMetricVisitor.java +++ b/ebean-api/src/main/java/io/ebean/meta/BasicMetricVisitor.java @@ -27,17 +27,17 @@ public class BasicMetricVisitor extends AbstractMetricVisitor implements ServerM } @Override - public List getTimedMetrics() { + public List timedMetrics() { return timed; } @Override - public List getQueryMetrics() { + public List queryMetrics() { return query; } @Override - public List getCountMetrics() { + public List countMetrics() { return count; } diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaCountMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaCountMetric.java index 8b6af3594..cdaa2d7fa 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaCountMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaCountMetric.java @@ -8,6 +8,13 @@ public interface MetaCountMetric extends MetaMetric { /** * Return the total count. */ - long getCount(); + long count(); + /** + * Migrate to count() + */ + @Deprecated + default long getCount() { + return count(); + } } diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaMetric.java index 0d716fe23..671dc05c1 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaMetric.java @@ -8,6 +8,13 @@ public interface MetaMetric { /** * Return the metric name. */ - String getName(); + String name(); + /** + * Migrate to name(). + */ + @Deprecated + default String getName() { + return name(); + } } diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java index e3907c69c..f5fee986c 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java @@ -8,21 +8,52 @@ public interface MetaQueryMetric extends MetaTimedMetric { /** * The type of entity or DTO bean. */ - Class getType(); + Class type(); + + /** + * Migrate to type(). + */ + @Deprecated + default Class getType() { + return type(); + } /** * The label for the query (can be null). */ - String getLabel(); + String label(); + + /** + * Migrate to label(). + */ + @Deprecated + default String getLabel() { + return label(); + } /** * The actual SQL of the query. */ - String getSql(); + String sql(); + + /** + * Migrate to sql(). + */ + @Deprecated + default String getSql() { + return sql(); + } /** * Return the hash of the sql. */ - long getSqlHash(); + long sqlHash(); + /** + * Migrate to sqlHash(). + */ + @Deprecated + default long getSqlHash() { + return sqlHash(); + } } diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java b/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java index 4f9667bd0..6cdce69a1 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java @@ -10,45 +10,45 @@ public interface MetaQueryPlan { /** * Return the bean type for the query. */ - Class getBeanType(); + Class beanType(); /** * Return the label of the query. */ - String getLabel(); + String label(); /** * Return the profile location for the query. */ - ProfileLocation getProfileLocation(); + ProfileLocation profileLocation(); /** * Return the sql of the query. */ - String getSql(); + String sql(); /** * Return the hash of the plan. */ - long getHash(); + long sqlHash(); /** * Return a description of the bind values. */ - String getBind(); + String bind(); /** * Return the raw plan. */ - String getPlan(); + String plan(); /** * Return the query execution time associated with the bind values capture. */ - long getQueryTimeMicros(); + long queryTimeMicros(); /** * Return the total count of times bind capture has occurred. */ - long getCaptureCount(); + long captureCount(); } diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java index c6ba13516..f95f3248d 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java @@ -9,27 +9,68 @@ public interface MetaTimedMetric extends MetaMetric { /** * Return the metric location if defined. */ - String getLocation(); + String location(); + + /** + * Migrate to location() + */ + @Deprecated + default String getLocation() { + return location(); + } /** * Return the total count. */ - long getCount(); + long count(); + + /** + * Migrate to count() + */ + @Deprecated + default long getCount() { + return count(); + } /** * Return the total execution time in micros. */ - long getTotal(); + long total(); + + /** + * Migrate to total() + */ + @Deprecated + default long getTotal() { + return total(); + } /** * Return the max execution time in micros. */ - long getMax(); + long max(); + + /** + * Migrate to max() + */ + @Deprecated + default long getMax() { + return max(); + } /** * Return the mean execution time in micros. */ - long getMean(); + long mean(); + + + /** + * Migrate to mean() + */ + @Deprecated + default long getMean() { + return mean(); + } /** * Return true if this is the first metrics collection for this query. diff --git a/ebean-api/src/main/java/io/ebean/meta/MetricVisitor.java b/ebean-api/src/main/java/io/ebean/meta/MetricVisitor.java index 18c7a72dc..fac9f050e 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetricVisitor.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetricVisitor.java @@ -8,22 +8,22 @@ public interface MetricVisitor { /** * Return true if the metrics should be reset. */ - boolean isReset(); + boolean reset(); /** * Return true if we should visit the transaction metrics. */ - boolean isCollectTransactionMetrics(); + boolean collectTransactionMetrics(); /** * Return true if we should visit the ORM and SQL query metrics. */ - boolean isCollectQueryMetrics(); + boolean collectQueryMetrics(); /** * Return true if we should visit the L2 cache metrics. */ - boolean isCollectL2Metrics(); + boolean collectL2Metrics(); /** * Visit has started. diff --git a/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java b/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java index 9b785ec62..7caeabd2f 100644 --- a/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java +++ b/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java @@ -32,7 +32,7 @@ public class QueryPlanInit { * Return the query execution time threshold which must be exceeded to initiate * query plan collection. */ - public long getThresholdMicros() { + public long thresholdMicros() { return thresholdMicros; } @@ -40,7 +40,7 @@ public class QueryPlanInit { * Set the query execution time threshold which must be exceeded to initiate * query plan collection. */ - public void setThresholdMicros(long thresholdMicros) { + public void thresholdMicros(long thresholdMicros) { this.thresholdMicros = thresholdMicros; } @@ -54,14 +54,14 @@ public class QueryPlanInit { /** * Return the specific hashes that we want to collect query plans on. */ - public Set getHashes() { + public Set sqlHashes() { return hashes; } /** * Set the specific hashes that we want to collect query plans on. */ - public void setHashes(Set hashes) { + public void sqlHashes(Set hashes) { this.hashes = hashes; } } diff --git a/ebean-api/src/main/java/io/ebean/meta/QueryPlanRequest.java b/ebean-api/src/main/java/io/ebean/meta/QueryPlanRequest.java index c4a69b1aa..421e0c151 100644 --- a/ebean-api/src/main/java/io/ebean/meta/QueryPlanRequest.java +++ b/ebean-api/src/main/java/io/ebean/meta/QueryPlanRequest.java @@ -18,7 +18,7 @@ public class QueryPlanRequest { * have been around for a while (e.g. 5 mins) and so reasonably represent * bind values that match the slowest execution for this query plan. */ - public long getSince() { + public long since() { return since; } @@ -28,14 +28,14 @@ public class QueryPlanRequest { * * @param since The minimum age of the bind values capture. */ - public void setSince(long since) { + public void since(long since) { this.since = since; } /** * Return the maximum number of plans to capture. */ - public int getMaxCount() { + public int maxCount() { return maxCount; } @@ -45,7 +45,7 @@ public class QueryPlanRequest { * Use this to limit how much query plan capturing is done as query * plan capture is actual database load. */ - public void setMaxCount(int maxCount) { + public void maxCount(int maxCount) { this.maxCount = maxCount; } @@ -54,7 +54,7 @@ public class QueryPlanRequest { *

* Query plan collection will stop once this time is exceeded. */ - public long getMaxTimeMillis() { + public long maxTimeMillis() { return maxTimeMillis; } @@ -65,7 +65,7 @@ public class QueryPlanRequest { * this to ensure the query plan capture does not use excessive amount * of time - put too much load on the database. */ - public void setMaxTimeMillis(long maxTimeMillis) { + public void maxTimeMillis(long maxTimeMillis) { this.maxTimeMillis = maxTimeMillis; } } diff --git a/ebean-api/src/main/java/io/ebean/meta/ServerMetrics.java b/ebean-api/src/main/java/io/ebean/meta/ServerMetrics.java index 8f0488d62..b8a50d85d 100644 --- a/ebean-api/src/main/java/io/ebean/meta/ServerMetrics.java +++ b/ebean-api/src/main/java/io/ebean/meta/ServerMetrics.java @@ -10,16 +10,39 @@ public interface ServerMetrics { /** * Return timed metrics for Transactions, labelled SqlQuery, labelled SqlUpdate. */ - List getTimedMetrics(); + List timedMetrics(); + + /** + * Migrate to timedMetrics(). + */ + @Deprecated + default List getTimedMetrics() { + return timedMetrics(); + } /** * Return the query metrics. */ - List getQueryMetrics(); + List queryMetrics(); + + /** + * Migrate to queryMetrics(). + */ + @Deprecated + default List getQueryMetrics() { + return queryMetrics(); + } /** * Return the Counter metrics. */ - List getCountMetrics(); + List countMetrics(); + /** + * Migrate to countMetrics(). + */ + @Deprecated + default List getCountMetrics() { + return countMetrics(); + } } diff --git a/ebean-api/src/main/java/io/ebean/meta/ServerMetricsAsJson.java b/ebean-api/src/main/java/io/ebean/meta/ServerMetricsAsJson.java index f48ecb5b6..7e42302c8 100644 --- a/ebean-api/src/main/java/io/ebean/meta/ServerMetricsAsJson.java +++ b/ebean-api/src/main/java/io/ebean/meta/ServerMetricsAsJson.java @@ -8,12 +8,12 @@ import java.util.Comparator; public interface ServerMetricsAsJson { /** - * Set to false to exclude profile location and sql. + * Set to false in order to exclude profile location and sql. */ ServerMetricsAsJson withExtraAttributes(boolean withLocation); /** - * Set to false to exclude SQL hash. + * Set to false in order to exclude SQL hash. */ ServerMetricsAsJson withHash(boolean withHash); diff --git a/ebean-api/src/main/java/io/ebean/meta/SortMetric.java b/ebean-api/src/main/java/io/ebean/meta/SortMetric.java index 9df2c704b..30104f1ff 100644 --- a/ebean-api/src/main/java/io/ebean/meta/SortMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/SortMetric.java @@ -32,7 +32,7 @@ public class SortMetric { @Override public int compare(MetaCountMetric o1, MetaCountMetric o2) { - return stringCompare(o1.getName(), o2.getName()); + return stringCompare(o1.name(), o2.name()); } } @@ -43,8 +43,8 @@ public class SortMetric { @Override public int compare(MetaTimedMetric o1, MetaTimedMetric o2) { - int i = stringCompare(o1.getName(), o2.getName()); - return i != 0 ? i : Long.compare(o1.getCount(), o2.getCount()); + int i = stringCompare(o1.name(), o2.name()); + return i != 0 ? i : Long.compare(o1.count(), o2.count()); } } @@ -55,7 +55,7 @@ public class SortMetric { @Override public int compare(MetaTimedMetric o1, MetaTimedMetric o2) { - return Long.compare(o2.getCount(), o1.getCount()); + return Long.compare(o2.count(), o1.count()); } } @@ -66,7 +66,7 @@ public class SortMetric { @Override public int compare(MetaTimedMetric o1, MetaTimedMetric o2) { - return Long.compare(o2.getTotal(), o1.getTotal()); + return Long.compare(o2.total(), o1.total()); } } @@ -77,7 +77,7 @@ public class SortMetric { @Override public int compare(MetaTimedMetric o1, MetaTimedMetric o2) { - return Long.compare(o2.getMean(), o1.getMean()); + return Long.compare(o2.mean(), o1.mean()); } } @@ -88,7 +88,7 @@ public class SortMetric { @Override public int compare(MetaTimedMetric o1, MetaTimedMetric o2) { - return Long.compare(o2.getMax(), o1.getMax()); + return Long.compare(o2.max(), o1.max()); } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultQueryPlanListener.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultQueryPlanListener.java index 051d331ba..20d7ec223 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultQueryPlanListener.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultQueryPlanListener.java @@ -18,8 +18,8 @@ class DefaultQueryPlanListener implements QueryPlanListener { String dbName = capture.getDatabase().getName(); for (MetaQueryPlan plan : capture.getPlans()) { log.info("queryPlan db:{} label:{} queryTimeMicros:{} loc:{} sql:{} bind:{} plan:{}", - dbName, plan.getLabel(), plan.getQueryTimeMicros(), plan.getProfileLocation(), - plan.getSql(), plan.getBind(), plan.getPlan()); + dbName, plan.label(), plan.queryTimeMicros(), plan.profileLocation(), + plan.sql(), plan.bind(), plan.plan()); } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index d21f9967f..2040e3f78 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -416,8 +416,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { private void collectQueryPlans() { QueryPlanRequest request = new QueryPlanRequest(); - request.setMaxCount(config.getQueryPlanCaptureMaxCount()); - request.setMaxTimeMillis(config.getQueryPlanCaptureMaxTimeMillis()); + request.maxCount(config.getQueryPlanCaptureMaxCount()); + request.maxTimeMillis(config.getQueryPlanCaptureMaxTimeMillis()); // obtains query explain plans ... List plans = metaInfoManager.queryPlanCollectNow(request); @@ -2328,13 +2328,13 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { @Override public void visitMetrics(MetricVisitor visitor) { visitor.visitStart(); - if (visitor.isCollectTransactionMetrics()) { + if (visitor.collectTransactionMetrics()) { transactionManager.visitMetrics(visitor); } - if (visitor.isCollectL2Metrics()) { + if (visitor.collectL2Metrics()) { serverCacheManager.visitMetrics(visitor); } - if (visitor.isCollectQueryMetrics()) { + if (visitor.collectQueryMetrics()) { beanDescriptorManager.visitMetrics(visitor); dtoBeanManager.visitMetrics(visitor); relationalQueryEngine.visitMetrics(visitor); @@ -2351,7 +2351,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { List queryPlanInit(QueryPlanInit initRequest) { if (initRequest.isAll()) { - queryPlanManager.setDefaultThreshold(initRequest.getThresholdMicros()); + queryPlanManager.setDefaultThreshold(initRequest.thresholdMicros()); } return beanDescriptorManager.queryPlanInit(initRequest); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java index 4c42c4b11..f31fa849c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java @@ -78,11 +78,11 @@ class DumpMetrics { out("-- Dumping metrics for " + server.getName() + " -- "); ServerMetrics serverMetrics = server.getMetaInfoManager().collectMetrics(); - for (MetaTimedMetric metric : serverMetrics.getTimedMetrics()) { + for (MetaTimedMetric metric : serverMetrics.timedMetrics()) { log(metric); } - List countMetrics = serverMetrics.getCountMetrics(); + List countMetrics = serverMetrics.countMetrics(); if (!countMetrics.isEmpty()) { out("\n-- Counters --"); countMetrics.sort(SortMetric.COUNT_NAME); @@ -91,7 +91,7 @@ class DumpMetrics { } } - List queryMetrics = serverMetrics.getQueryMetrics(); + List queryMetrics = serverMetrics.queryMetrics(); if (!queryMetrics.isEmpty()) { out("\n-- Queries --"); queryMetrics.sort(sortBy); @@ -104,8 +104,8 @@ class DumpMetrics { private void logCount(MetaCountMetric metric) { StringBuilder sb = new StringBuilder(); - sb.append(padNameTimed(metric.getName())).append(" "); - sb.append(" count:").append(pad(metric.getCount())); + sb.append(padNameTimed(metric.name())).append(" "); + sb.append(" count:").append(pad(metric.count())); out(sb.toString()); } @@ -120,38 +120,38 @@ class DumpMetrics { appendQueryName(metric, sb); appendCounters(metric, sb); if (dumpHash) { - sb.append("\n sqlHash:").append(metric.getSqlHash()); + sb.append("\n sqlHash:").append(metric.sqlHash()); } appendProfileAndSql(metric, sb); out(sb.toString()); } private void appendQueryName(MetaQueryMetric metric, StringBuilder sb) { - sb.append("query:").append(padName(metric.getName())).append(" "); + sb.append("query:").append(padName(metric.name())).append(" "); } private void appendProfileAndSql(MetaQueryMetric metric, StringBuilder sb) { - String location = metric.getLocation(); + String location = metric.location(); if (dumpLoc && location != null) { sb.append("\n loc:").append(location); } if (dumpSql) { - sb.append(" \n\n sql:").append(metric.getSql()).append("\n\n"); + sb.append(" \n\n sql:").append(metric.sql()).append("\n\n"); } } private void log(MetaTimedMetric metric) { StringBuilder sb = new StringBuilder(); - sb.append(padNameTimed(metric.getName())).append(" "); + sb.append(padNameTimed(metric.name())).append(" "); appendCounters(metric, sb); out(sb.toString()); } private void appendCounters(MetaTimedMetric timedMetric, StringBuilder sb) { - sb.append(" count:").append(pad(timedMetric.getCount())) - .append(" total:").append(pad(timedMetric.getTotal())) - .append(" mean:").append(pad(timedMetric.getMean())) - .append(" max:").append(pad(timedMetric.getMax())); + sb.append(" count:").append(pad(timedMetric.count())) + .append(" total:").append(pad(timedMetric.total())) + .append(" mean:").append(pad(timedMetric.mean())) + .append(" max:").append(pad(timedMetric.max())); } private String padName(String name) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java index 7458d0468..4ac8859b6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java @@ -31,9 +31,9 @@ class DumpMetricsData { private void collect(ServerMetrics serverMetrics) { - final List timedMetrics = serverMetrics.getTimedMetrics(); - final List countMetrics = serverMetrics.getCountMetrics(); - final List queryMetrics = serverMetrics.getQueryMetrics(); + final List timedMetrics = serverMetrics.timedMetrics(); + final List countMetrics = serverMetrics.countMetrics(); + final List queryMetrics = serverMetrics.queryMetrics(); for (MetaTimedMetric metric : timedMetrics) { add(metric); @@ -47,7 +47,7 @@ class DumpMetricsData { } private MetricData create(MetaMetric metric) { - MetricData data = new MetricData(metric.getName()); + MetricData data = new MetricData(metric.name()); list.add(data); return data; } @@ -55,30 +55,30 @@ class DumpMetricsData { private void add(MetaTimedMetric metric) { final MetricData data = create(metric); appendCounters(data, metric); - data.setLoc(metric.getLocation()); + data.setLoc(metric.location()); } private void addCount(MetaCountMetric metric) { final MetricData data = create(metric); - data.setCount(metric.getCount()); + data.setCount(metric.count()); } private void addQuery(MetaQueryMetric metric) { final MetricData data = create(metric); appendCounters(data, metric); appendLocationAndSql(data, metric); - data.setSqlHash(metric.getSqlHash()); + data.setSqlHash(metric.sqlHash()); } private void appendLocationAndSql(MetricData data, MetaQueryMetric metric) { - data.setLoc(metric.getLocation()); - data.setSql(metric.getSql()); + data.setLoc(metric.location()); + data.setSql(metric.sql()); } private void appendCounters(MetricData data, MetaTimedMetric timedMetric) { - data.setCount(timedMetric.getCount()); - data.setTotal(timedMetric.getTotal()); - data.setMean(timedMetric.getMean()); - data.setMax(timedMetric.getMax()); + data.setCount(timedMetric.count()); + data.setTotal(timedMetric.total()); + data.setMean(timedMetric.mean()); + data.setMax(timedMetric.max()); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java index 6f74dac97..b0644ec9f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java @@ -84,11 +84,11 @@ class DumpMetricsJson implements ServerMetricsAsJson { private void collect(ServerMetrics serverMetrics) { try { start(); - for (MetaTimedMetric metric : serverMetrics.getTimedMetrics()) { + for (MetaTimedMetric metric : serverMetrics.timedMetrics()) { logTimed(metric); } - List countMetrics = serverMetrics.getCountMetrics(); + List countMetrics = serverMetrics.countMetrics(); if (!countMetrics.isEmpty()) { if (sortBy != null) { countMetrics.sort(SortMetric.COUNT_NAME); @@ -98,7 +98,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { } } - List queryMetrics = serverMetrics.getQueryMetrics(); + List queryMetrics = serverMetrics.queryMetrics(); if (!queryMetrics.isEmpty()) { if (sortBy != null) { queryMetrics.sort(sortBy); @@ -170,7 +170,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { } objStart(); key("name"); - val(metric.getName()); + val(metric.name()); } private void metricEnd() throws IOException { @@ -180,7 +180,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { private void logCount(MetaCountMetric metric) throws IOException { metricStart(metric); key("count"); - val(metric.getCount()); + val(metric.count()); metricEnd(); } @@ -188,7 +188,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { metricStart(metric); appendTiming(metric); if (isIncludeDetail(metric)) { - appendExtra("loc", metric.getLocation()); + appendExtra("loc", metric.location()); } metricEnd(); } @@ -197,11 +197,11 @@ class DumpMetricsJson implements ServerMetricsAsJson { metricStart(metric); appendTiming(metric); if (withHash) { - keyVal("sqlHash", metric.getSqlHash()); + keyVal("sqlHash", metric.sqlHash()); } if (isIncludeDetail(metric)) { - appendExtra("loc", metric.getLocation()); - appendExtra("sql", metric.getSql()); + appendExtra("loc", metric.location()); + appendExtra("sql", metric.sql()); } metricEnd(); } @@ -218,10 +218,10 @@ class DumpMetricsJson implements ServerMetricsAsJson { } private void appendTiming(MetaTimedMetric timedMetric) throws IOException { - keyVal("count", timedMetric.getCount()); - keyVal("total", timedMetric.getTotal()); - keyVal("mean", timedMetric.getMean()); - keyVal("max", timedMetric.getMax()); + keyVal("count", timedMetric.count()); + keyVal("total", timedMetric.total()); + keyVal("mean", timedMetric.mean()); + keyVal("max", timedMetric.max()); } private void keyVal(String key, long value) throws IOException { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index e08b37d1d..6a9acd839 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -1559,7 +1559,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { void queryPlanInit(QueryPlanInit request, List list) { for (CQueryPlan queryPlan : queryPlanCache.values()) { if (request.includeHash(queryPlan.getSqlHash())) { - queryPlan.queryPlanInit(request.getThresholdMicros()); + queryPlan.queryPlanInit(request.thresholdMicros()); list.add(queryPlan.createMeta(null, null)); } } @@ -1572,7 +1572,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { iudMetrics.visit(visitor); for (CQueryPlan queryPlan : queryPlanCache.values()) { if (!queryPlan.isEmptyStats()) { - visitor.visitQuery(queryPlan.getSnapshot(visitor.isReset())); + visitor.visitQuery(queryPlan.getSnapshot(visitor.reset())); } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java index 2cf7a25a7..d93e0dbdb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java @@ -49,7 +49,7 @@ class DCountMetric implements CountMetric { @Override public void visit(MetricVisitor visitor) { - long val = visitor.isReset() ? count.sumThenReset() : count.sum(); + long val = visitor.reset() ? count.sumThenReset() : count.sum(); if (val > 0) { visitor.visitCount(new DCountMetricStats(name, val)); } @@ -66,12 +66,12 @@ class DCountMetric implements CountMetric { } @Override - public String getName() { + public String name() { return name; } @Override - public long getCount() { + public long count() { return count; } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java index fda2b62b8..fda1d4d9b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java @@ -19,7 +19,7 @@ class DQueryPlanMetric implements QueryPlanMetric { @Override public void visit(MetricVisitor visitor) { - TimedMetricStats stats = metric.collect(visitor.isReset()); + TimedMetricStats stats = metric.collect(visitor.reset()); if (stats != null) { visitor.visitQuery(new Stats(meta, stats, collected)); collected = true; @@ -45,11 +45,11 @@ class DQueryPlanMetric implements QueryPlanMetric { @Override public String toString() { - return meta + " " + stats + " sql:" + getSql(); + return meta + " " + stats + " sql:" + sql(); } @Override - public Class getType() { + public Class type() { return meta.getType(); } @@ -59,48 +59,48 @@ class DQueryPlanMetric implements QueryPlanMetric { } @Override - public long getSqlHash() { + public long sqlHash() { return meta.getSqlHash(); } @Override - public String getLabel() { + public String label() { return meta.getLabel(); } @Override - public String getSql() { + public String sql() { return meta.getSql(); } @Override - public String getName() { + public String name() { return meta.getName(); } @Override - public String getLocation() { + public String location() { return meta.getLocation(); } @Override - public long getCount() { - return stats.getCount(); + public long count() { + return stats.count(); } @Override - public long getTotal() { - return stats.getTotal(); + public long total() { + return stats.total(); } @Override - public long getMax() { - return stats.getMax(); + public long max() { + return stats.max(); } @Override - public long getMean() { - return stats.getMean(); + public long mean() { + return stats.mean(); } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java index 54146abe9..2207fef3d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java @@ -60,12 +60,12 @@ class DTimeMetricStats implements TimedMetricStats { } @Override - public String getName() { + public String name() { return name; } @Override - public String getLocation() { + public String location() { return location; } @@ -73,7 +73,7 @@ class DTimeMetricStats implements TimedMetricStats { * Return the count of values collected. */ @Override - public long getCount() { + public long count() { return count; } @@ -81,7 +81,7 @@ class DTimeMetricStats implements TimedMetricStats { * Return the total of all the values. */ @Override - public long getTotal() { + public long total() { return total; } @@ -89,7 +89,7 @@ class DTimeMetricStats implements TimedMetricStats { * Return the Max value collected. */ @Override - public long getMax() { + public long max() { return max; } @@ -97,7 +97,7 @@ class DTimeMetricStats implements TimedMetricStats { * Return the mean value rounded up. */ @Override - public long getMean() { + public long mean() { return (count < 1) ? 0L : Math.round((double)(total / count)); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java index 63eb275f6..cc344c3e6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java @@ -71,7 +71,7 @@ class DTimedMetric implements TimedMetric { @Override public void visit(MetricVisitor visitor) { - DTimeMetricStats metric = collect(visitor.isReset()); + DTimeMetricStats metric = collect(visitor.reset()); if (metric != null) { visitor.visitTimed(metric); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java index 7ef4e9084..27537737f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java @@ -48,7 +48,7 @@ class DTimedProfileLocation extends DProfileLocation implements TimedProfileLoca @Override public void visit(MetricVisitor visitor) { - TimedMetricStats collect = timedMetric.collect(visitor.isReset()); + TimedMetricStats collect = timedMetric.collect(visitor.reset()); if (collect != null) { if (overrideMetricName) { collect.setName(fullName); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRequest.java index 86e15f389..315e7a07d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRequest.java @@ -24,10 +24,10 @@ class CQueryPlanRequest { CQueryPlanRequest(Connection connection, QueryPlanRequest req, Iterator iterator) { this.connection = connection; this.iterator = iterator; - this.maxCount = req.getMaxCount(); - long reqSince = req.getSince(); + this.maxCount = req.maxCount(); + long reqSince = req.since(); this.since = (reqSince == 0) ? Long.MAX_VALUE: reqSince; - long maxTimeMillis = req.getMaxTimeMillis(); + long maxTimeMillis = req.maxTimeMillis(); this.maxTime = maxTimeMillis > 0 ? System.currentTimeMillis() + maxTimeMillis : 0; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java index bbcfea2b9..36e070653 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java @@ -83,56 +83,56 @@ public final class CQueryPlanStats { @Override public String toString() { - return "label:" + getLabel() + " location:" + getLocation() + " metrics:" + metrics + " sql:" + getSql(); + return "label:" + label() + " location:" + location() + " metrics:" + metrics + " sql:" + sql(); } @Override - public Class getType() { + public Class type() { return queryPlan.getBeanType(); } @Override - public String getLabel() { + public String label() { return queryPlan.getLabel(); } @Override - public String getName() { + public String name() { return queryPlan.getName(); } @Override - public String getLocation() { + public String location() { return queryPlan.getLocation(); } @Override - public long getCount() { - return metrics.getCount(); + public long count() { + return metrics.count(); } @Override - public long getTotal() { - return metrics.getTotal(); + public long total() { + return metrics.total(); } @Override - public long getMax() { - return metrics.getMax(); + public long max() { + return metrics.max(); } @Override - public long getMean() { - return metrics.getMean(); + public long mean() { + return metrics.mean(); } @Override - public long getSqlHash() { + public long sqlHash() { return queryPlan.getSqlHash(); } @Override - public String getSql() { + public String sql() { return queryPlan.getSql(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java index 3d8c7aaac..3d879362b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java @@ -16,14 +16,14 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { private final String sql; private final String bind; private final String plan; - private final long hash; + private final long sqlHash; private long queryTimeMicros; private long captureCount; - DQueryPlanOutput(Class beanType, String label, long hash, String sql, ProfileLocation profileLocation, String bind, String plan) { + DQueryPlanOutput(Class beanType, String label, long sqlHash, String sql, ProfileLocation profileLocation, String bind, String plan) { this.beanType = beanType; this.label = label; - this.hash = hash; + this.sqlHash = sqlHash; this.sql = sql; this.profileLocation = profileLocation; this.bind = bind; @@ -31,15 +31,15 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { } @Override - public long getHash() { - return hash; + public long sqlHash() { + return sqlHash; } /** * Return the associated bean. */ @Override - public Class getBeanType() { + public Class beanType() { return beanType; } @@ -47,12 +47,12 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { * Return the query label if set. */ @Override - public String getLabel() { + public String label() { return label; } @Override - public ProfileLocation getProfileLocation() { + public ProfileLocation profileLocation() { return profileLocation; } @@ -60,7 +60,7 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { * Return the sql of query. */ @Override - public String getSql() { + public String sql() { return sql; } @@ -68,7 +68,7 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { * Return a description of the bind values used. */ @Override - public String getBind() { + public String bind() { return bind; } @@ -76,7 +76,7 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { * Return the query plan. */ @Override - public String getPlan() { + public String plan() { return plan; } @@ -85,7 +85,7 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { * to build the query plan. */ @Override - public long getQueryTimeMicros() { + public long queryTimeMicros() { return queryTimeMicros; } @@ -93,13 +93,13 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { * Return the total count of times bind capture has occurred. */ @Override - public long getCaptureCount() { + public long captureCount() { return captureCount; } @Override public String toString() { - return " BeanType:" + ((beanType == null) ? "" : beanType.getSimpleName()) + " planHash:" + hash + " label:" + label + " queryTimeMicros:" + queryTimeMicros + " captureCount:" + captureCount + "\n SQL:" + sql + "\nBIND:" + bind + "\nPLAN:" + plan; + return " BeanType:" + ((beanType == null) ? "" : beanType.getSimpleName()) + " planHash:" + sqlHash + " label:" + label + " queryTimeMicros:" + queryTimeMicros + " captureCount:" + captureCount + "\n SQL:" + sql + "\nBIND:" + bind + "\nPLAN:" + plan; } /** diff --git a/ebean-core/src/test/java/io/ebean/BaseTestCase.java b/ebean-core/src/test/java/io/ebean/BaseTestCase.java index 0205d5294..988e73b59 100644 --- a/ebean-core/src/test/java/io/ebean/BaseTestCase.java +++ b/ebean-core/src/test/java/io/ebean/BaseTestCase.java @@ -90,14 +90,14 @@ public abstract class BaseTestCase { } protected List visitTimedMetrics() { - return collectMetrics().getTimedMetrics(); + return collectMetrics().timedMetrics(); } protected List sqlMetrics() { List timedMetrics = visitTimedMetrics(); return timedMetrics.stream() - .filter((it) -> it.getName().startsWith("sql.") || it.getName().startsWith("orm.")) + .filter((it) -> it.name().startsWith("sql.") || it.name().startsWith("orm.")) .collect(Collectors.toList()); } diff --git a/ebean-core/src/test/java/io/ebean/DtoQuery2Test.java b/ebean-core/src/test/java/io/ebean/DtoQuery2Test.java index ba30e9a5c..625cc9ae9 100644 --- a/ebean-core/src/test/java/io/ebean/DtoQuery2Test.java +++ b/ebean-core/src/test/java/io/ebean/DtoQuery2Test.java @@ -191,13 +191,13 @@ public class DtoQuery2Test extends BaseTestCase { BasicMetricVisitor basic = new BasicMetricVisitor(false, true, true, true); server().getMetaInfoManager().visitMetrics(basic); - List stats = basic.getQueryMetrics(); + List stats = basic.queryMetrics(); assertThat(stats).hasSize(1); MetaQueryMetric queryMetric = stats.get(0); - assertThat(queryMetric.getLabel()).isEqualTo("basic"); - assertThat(queryMetric.getCount()).isEqualTo(3); - assertThat(queryMetric.getName()).isEqualTo("dto.DCust_basic"); + assertThat(queryMetric.label()).isEqualTo("basic"); + assertThat(queryMetric.count()).isEqualTo(3); + assertThat(queryMetric.name()).isEqualTo("dto.DCust_basic"); server().findDto(DCust.class, "select c4.id, c4.name from o_customer c4 where lower(c4.name) = :name") @@ -207,7 +207,7 @@ public class DtoQuery2Test extends BaseTestCase { BasicMetricVisitor metric2 = server().getMetaInfoManager().visitBasic(); - stats = metric2.getQueryMetrics(); + stats = metric2.queryMetrics(); assertThat(stats).hasSize(2); log.info("stats " + stats); diff --git a/ebean-core/src/test/java/io/ebean/DtoQueryFromOrmTest.java b/ebean-core/src/test/java/io/ebean/DtoQueryFromOrmTest.java index ee26e9409..28b0bd490 100644 --- a/ebean-core/src/test/java/io/ebean/DtoQueryFromOrmTest.java +++ b/ebean-core/src/test/java/io/ebean/DtoQueryFromOrmTest.java @@ -27,12 +27,12 @@ public class DtoQueryFromOrmTest extends BaseTestCase { @AfterClass public static void reportStats() { ServerMetrics metrics = DB.getDefault().getMetaInfoManager().collectMetrics(); - for (MetaQueryMetric metric : metrics.getQueryMetrics()) { + for (MetaQueryMetric metric : metrics.queryMetrics()) { System.out.println(metric); } System.out.println("-- transaction metrics --"); - for (MetaTimedMetric metric : metrics.getTimedMetrics()) { + for (MetaTimedMetric metric : metrics.timedMetrics()) { System.out.println(metric); } } @@ -59,15 +59,15 @@ public class DtoQueryFromOrmTest extends BaseTestCase { ServerMetrics metrics = collectMetrics(); - List stats = metrics.getQueryMetrics(); + List stats = metrics.queryMetrics(); for (MetaQueryMetric stat : stats) { - long meanMicros = stat.getMean(); + long meanMicros = stat.mean(); assertThat(meanMicros).isLessThan(900_000); - assertThat(stat.getLocation()).isSameAs(loc0.location()); + assertThat(stat.location()).isSameAs(loc0.location()); } assertThat(stats).hasSize(1); - assertThat(stats.get(0).getCount()).isEqualTo(4); + assertThat(stats.get(0).count()).isEqualTo(4); } @ForPlatform(Platform.H2) diff --git a/ebean-core/src/test/java/io/ebean/DtoQueryTest.java b/ebean-core/src/test/java/io/ebean/DtoQueryTest.java index eea1c6da3..0331a8215 100644 --- a/ebean-core/src/test/java/io/ebean/DtoQueryTest.java +++ b/ebean-core/src/test/java/io/ebean/DtoQueryTest.java @@ -42,14 +42,14 @@ public class DtoQueryTest extends BaseTestCase { ServerMetrics metrics = collectMetrics(); - List stats = metrics.getQueryMetrics(); + List stats = metrics.queryMetrics(); for (MetaQueryMetric stat : stats) { - long meanMicros = stat.getMean(); + long meanMicros = stat.mean(); assertThat(meanMicros).isLessThan(900_000); } assertThat(stats).hasSize(1); - assertThat(stats.get(0).getCount()).isEqualTo(1); + assertThat(stats.get(0).count()).isEqualTo(1); } @Test @@ -283,13 +283,13 @@ public class DtoQueryTest extends BaseTestCase { BasicMetricVisitor basic = new BasicMetricVisitor(false, true, true, true); server().getMetaInfoManager().visitMetrics(basic); - List stats = basic.getQueryMetrics(); + List stats = basic.queryMetrics(); assertThat(stats).hasSize(1); MetaQueryMetric queryMetric = stats.get(0); - assertThat(queryMetric.getLabel()).isEqualTo("basic"); - assertThat(queryMetric.getCount()).isEqualTo(3); - assertThat(queryMetric.getName()).isEqualTo("dto.DCust_basic"); + assertThat(queryMetric.label()).isEqualTo("basic"); + assertThat(queryMetric.count()).isEqualTo(3); + assertThat(queryMetric.name()).isEqualTo("dto.DCust_basic"); server().findDto(DCust.class, "select c4.id, c4.name from o_customer c4 where lower(c4.name) = :name") @@ -299,7 +299,7 @@ public class DtoQueryTest extends BaseTestCase { ServerMetrics metric2 = server().getMetaInfoManager().collectMetrics(); - stats = metric2.getQueryMetrics(); + stats = metric2.queryMetrics(); assertThat(stats).hasSize(2); log.info("stats " + stats); diff --git a/ebean-core/src/test/java/io/ebean/UpdateQueryTest.java b/ebean-core/src/test/java/io/ebean/UpdateQueryTest.java index ca2caa4c8..5b9c42991 100644 --- a/ebean-core/src/test/java/io/ebean/UpdateQueryTest.java +++ b/ebean-core/src/test/java/io/ebean/UpdateQueryTest.java @@ -39,10 +39,10 @@ public class UpdateQueryTest extends BaseTestCase { assertSql(query).contains("update o_customer set status=?, updtime=? where status = ? and id > ?"); ServerMetrics metrics = collectMetrics(); - List ormQueryMetrics = metrics.getQueryMetrics(); + List ormQueryMetrics = metrics.queryMetrics(); assertThat(ormQueryMetrics).hasSize(1); - assertThat(ormQueryMetrics.get(0).getType()).isEqualTo(Customer.class); - assertThat(ormQueryMetrics.get(0).getLabel()).isEqualTo("updateActive"); + assertThat(ormQueryMetrics.get(0).type()).isEqualTo(Customer.class); + assertThat(ormQueryMetrics.get(0).label()).isEqualTo("updateActive"); } @Test @@ -69,10 +69,10 @@ public class UpdateQueryTest extends BaseTestCase { assertSql(sql.get(0)).contains("update o_customer set status = status"); ServerMetrics metrics = collectMetrics(); - List ormQueryMetrics = metrics.getQueryMetrics(); + List ormQueryMetrics = metrics.queryMetrics(); assertThat(ormQueryMetrics).hasSize(1); - assertThat(ormQueryMetrics.get(0).getType()).isEqualTo(Customer.class); - assertThat(ormQueryMetrics.get(0).getLabel()).isEqualTo("updateAll"); + assertThat(ormQueryMetrics.get(0).type()).isEqualTo(Customer.class); + assertThat(ormQueryMetrics.get(0).label()).isEqualTo("updateAll"); } @Test diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/deploy/BeanIudMetricsTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/deploy/BeanIudMetricsTest.java index d53f0e973..9f26e978c 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/deploy/BeanIudMetricsTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/deploy/BeanIudMetricsTest.java @@ -23,11 +23,11 @@ public class BeanIudMetricsTest { BasicMetricVisitor basic = new BasicMetricVisitor(); iudMetrics.visit(basic); - List timed = basic.getTimedMetrics(); + List timed = basic.timedMetrics(); assertThat(timed).hasSize(1); - assertThat(timed.get(0).getCount()).isEqualTo(4); - assertThat(timed.get(0).getName()).isEqualTo("iud.one.insertBatch"); + assertThat(timed.get(0).count()).isEqualTo(4); + assertThat(timed.get(0).name()).isEqualTo("iud.one.insertBatch"); iudMetrics.addBatch(PersistRequest.Type.UPDATE, startNanos, 1); iudMetrics.addBatch(PersistRequest.Type.DELETE_SOFT, startNanos, 2); @@ -37,15 +37,15 @@ public class BeanIudMetricsTest { basic = new BasicMetricVisitor(); iudMetrics.visit(basic); - timed = basic.getTimedMetrics(); + timed = basic.timedMetrics(); assertThat(timed).hasSize(3); - assertThat(timed.get(0).getCount()).isEqualTo(16); - assertThat(timed.get(0).getName()).isEqualTo("iud.one.insertBatch"); - assertThat(timed.get(1).getCount()).isEqualTo(3); - assertThat(timed.get(1).getName()).isEqualTo("iud.one.updateBatch"); - assertThat(timed.get(2).getCount()).isEqualTo(12); - assertThat(timed.get(2).getName()).isEqualTo("iud.one.deleteBatch"); + assertThat(timed.get(0).count()).isEqualTo(16); + assertThat(timed.get(0).name()).isEqualTo("iud.one.insertBatch"); + assertThat(timed.get(1).count()).isEqualTo(3); + assertThat(timed.get(1).name()).isEqualTo("iud.one.updateBatch"); + assertThat(timed.get(2).count()).isEqualTo(12); + assertThat(timed.get(2).name()).isEqualTo("iud.one.deleteBatch"); } @Test @@ -63,15 +63,15 @@ public class BeanIudMetricsTest { BasicMetricVisitor basic = new BasicMetricVisitor(); iudMetrics.visit(basic); - List timed = basic.getTimedMetrics(); + List timed = basic.timedMetrics(); assertThat(timed).hasSize(3); - assertThat(timed.get(0).getCount()).isEqualTo(1); - assertThat(timed.get(0).getName()).isEqualTo("iud.one.insert"); - assertThat(timed.get(1).getCount()).isEqualTo(2); - assertThat(timed.get(1).getName()).isEqualTo("iud.one.update"); - assertThat(timed.get(2).getCount()).isEqualTo(2); - assertThat(timed.get(2).getName()).isEqualTo("iud.one.delete"); + assertThat(timed.get(0).count()).isEqualTo(1); + assertThat(timed.get(0).name()).isEqualTo("iud.one.insert"); + assertThat(timed.get(1).count()).isEqualTo(2); + assertThat(timed.get(1).name()).isEqualTo("iud.one.update"); + assertThat(timed.get(2).count()).isEqualTo(2); + assertThat(timed.get(2).name()).isEqualTo("iud.one.delete"); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricMapTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricMapTest.java index 43f0e0426..cb6d4d662 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricMapTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricMapTest.java @@ -21,17 +21,17 @@ public class DTimedMetricMapTest { BasicMetricVisitor visitor = new BasicMetricVisitor(); metricMap.visit(visitor); - MetaTimedMetric timedMetric = visitor.getTimedMetrics().get(0); - assertThat(timedMetric.getCount()).isEqualTo(1); - assertThat(timedMetric.getTotal()).isGreaterThan(10); + MetaTimedMetric timedMetric = visitor.timedMetrics().get(0); + assertThat(timedMetric.count()).isEqualTo(1); + assertThat(timedMetric.total()).isGreaterThan(10); metricMap.addSinceNanos("some", nanos); visitor = new BasicMetricVisitor(); metricMap.visit(visitor); - timedMetric = visitor.getTimedMetrics().get(0); - assertThat(timedMetric.getCount()).isEqualTo(1); - assertThat(timedMetric.getTotal()).isGreaterThan(10); + timedMetric = visitor.timedMetrics().get(0); + assertThat(timedMetric.count()).isEqualTo(1); + assertThat(timedMetric.total()).isGreaterThan(10); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricTest.java index 28e651b88..6dbbb45d3 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/DTimedMetricTest.java @@ -17,16 +17,16 @@ public class DTimedMetricTest { metric.addSinceNanos(start); DTimeMetricStats stats = metric.collect(true); - assertThat(stats.getCount()).isEqualTo(1); - assertThat(stats.getTotal()).isGreaterThan(10); - assertThat(stats.getMax()).isEqualTo(stats.getTotal()); + assertThat(stats.count()).isEqualTo(1); + assertThat(stats.total()).isGreaterThan(10); + assertThat(stats.max()).isEqualTo(stats.total()); metric.addSinceNanos(start); stats = metric.collect(true); - assertThat(stats.getCount()).isEqualTo(1); - assertThat(stats.getTotal()).isGreaterThan(10); - assertThat(stats.getMax()).isEqualTo(stats.getTotal()); + assertThat(stats.count()).isEqualTo(1); + assertThat(stats.total()).isGreaterThan(10); + assertThat(stats.max()).isEqualTo(stats.total()); } @Test @@ -40,16 +40,16 @@ public class DTimedMetricTest { metric.addBatchSince(start, 5); DTimeMetricStats stats = metric.collect(true); - assertThat(stats.getCount()).isEqualTo(5); - assertThat(stats.getTotal()).isGreaterThan(10000); - assertThat(stats.getMax()).isEqualTo(stats.getTotal() / 5); - assertThat(stats.getMax()).isGreaterThan(10000 / 5); + assertThat(stats.count()).isEqualTo(5); + assertThat(stats.total()).isGreaterThan(10000); + assertThat(stats.max()).isEqualTo(stats.total() / 5); + assertThat(stats.max()).isGreaterThan(10000 / 5); metric.addBatchSince(start, 2); stats = metric.collect(true); - assertThat(stats.getCount()).isEqualTo(2); - assertThat(stats.getTotal()).isGreaterThan(10000); - assertThat(stats.getMax()).isEqualTo(stats.getTotal() / 2); + assertThat(stats.count()).isEqualTo(2); + assertThat(stats.total()).isGreaterThan(10000); + assertThat(stats.max()).isEqualTo(stats.total() / 2); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/SortMetricTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/SortMetricTest.java index c67d14b30..29658566c 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/SortMetricTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/SortMetricTest.java @@ -26,7 +26,7 @@ public class SortMetricTest { list.add(create("a")); list.sort(sortMetric); - String names = list.stream().map(DTimeMetricStats::getName).collect(Collectors.joining()); + String names = list.stream().map(DTimeMetricStats::name).collect(Collectors.joining()); assertEquals("nullabcd", names); } diff --git a/ebean-core/src/test/java/org/tests/batchinsert/TestBatchInsertFlush.java b/ebean-core/src/test/java/org/tests/batchinsert/TestBatchInsertFlush.java index 6e956510a..2f9cdf7f1 100644 --- a/ebean-core/src/test/java/org/tests/batchinsert/TestBatchInsertFlush.java +++ b/ebean-core/src/test/java/org/tests/batchinsert/TestBatchInsertFlush.java @@ -80,15 +80,15 @@ public class TestBatchInsertFlush extends BaseTestCase { } ServerMetrics metrics = collectMetrics(); - List txnStats = metrics.getTimedMetrics(); + List txnStats = metrics.timedMetrics(); for (MetaTimedMetric txnMetric : txnStats) { System.out.println(txnMetric); } assertThat(txnStats).hasSize(4); - assertThat(txnStats.get(0).getName()).isEqualTo("txn.main"); - assertThat(txnStats.get(1).getName()).isEqualTo("txn.named.TestBatchInsertFlush.no_cascade"); - assertThat(txnStats.get(2).getName()).isEqualTo("iud.TSDetail.insertBatch"); - assertThat(txnStats.get(3).getName()).isEqualTo("iud.TSMaster.insertBatch"); + assertThat(txnStats.get(0).name()).isEqualTo("txn.main"); + assertThat(txnStats.get(1).name()).isEqualTo("txn.named.TestBatchInsertFlush.no_cascade"); + assertThat(txnStats.get(2).name()).isEqualTo("iud.TSDetail.insertBatch"); + assertThat(txnStats.get(3).name()).isEqualTo("iud.TSMaster.insertBatch"); } @Test diff --git a/ebean-core/src/test/java/org/tests/m2m/TestM2mDeleteObject.java b/ebean-core/src/test/java/org/tests/m2m/TestM2mDeleteObject.java index 3ba05ee68..3ccad9fb8 100644 --- a/ebean-core/src/test/java/org/tests/m2m/TestM2mDeleteObject.java +++ b/ebean-core/src/test/java/org/tests/m2m/TestM2mDeleteObject.java @@ -28,7 +28,7 @@ public class TestM2mDeleteObject extends BaseTestCase { List sqlMetrics = sqlMetrics(); assertThat(sqlMetrics).hasSize(1); - assertThat(sqlMetrics.get(0).getName()).isEqualTo("orm.update.deleteAllPermissions"); + assertThat(sqlMetrics.get(0).name()).isEqualTo("orm.update.deleteAllPermissions"); Tenant t = new Tenant("tenant"); diff --git a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java index b6a40903f..108b4a398 100644 --- a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java +++ b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java @@ -176,7 +176,7 @@ public class TestCustomerFinder extends BaseTestCase { // change default collect query plan threshold to 200 micros QueryPlanInit init0 = new QueryPlanInit(); init0.setAll(true); - init0.setThresholdMicros(2); + init0.thresholdMicros(2); final List plans = server().getMetaInfoManager().queryPlanInit(init0); assertThat(plans.size()).isGreaterThan(1); @@ -186,7 +186,7 @@ public class TestCustomerFinder extends BaseTestCase { // change query plan threshold to 100 micros QueryPlanInit init = new QueryPlanInit(); init.setAll(true); - init.setThresholdMicros(1); + init.thresholdMicros(1); final List appliedToPlans = server().getMetaInfoManager().queryPlanInit(init); assertThat(appliedToPlans.size()).isGreaterThan(4); @@ -195,30 +195,30 @@ public class TestCustomerFinder extends BaseTestCase { ServerMetrics metrics = DB.getDefault().getMetaInfoManager().collectMetrics(); - List planStats = metrics.getQueryMetrics(); + List planStats = metrics.queryMetrics(); assertThat(planStats.size()).isGreaterThan(4); for (MetaQueryMetric planStat : planStats) { System.out.println(planStat); } - for (MetaTimedMetric txnTimed : metrics.getTimedMetrics()) { + for (MetaTimedMetric txnTimed : metrics.timedMetrics()) { System.out.println(txnTimed); } // obtains db query plans ... QueryPlanRequest request = new QueryPlanRequest(); // collect max 1000 plans (use something more like 10) - request.setMaxCount(1_000); + request.maxCount(1_000); // don't collect any more plans if used 10 secs - request.setMaxTimeMillis(10_000); + request.maxTimeMillis(10_000); List plans0 = server().getMetaInfoManager().queryPlanCollectNow(request); assertThat(plans0).isNotEmpty(); for (MetaQueryPlan plan : plans) { logger.info("queryPlan label:{}, queryTimeMicros:{} loc:{} sql:{} bind:{} plan:{}", - plan.getLabel(), plan.getQueryTimeMicros(), plan.getProfileLocation(), - plan.getSql(), plan.getBind(), plan.getPlan()); + plan.label(), plan.queryTimeMicros(), plan.profileLocation(), + plan.sql(), plan.bind(), plan.plan()); System.out.println(plan); } diff --git a/ebean-core/src/test/java/org/tests/query/sqlquery/SqlQueryTests.java b/ebean-core/src/test/java/org/tests/query/sqlquery/SqlQueryTests.java index 996f08bbe..f16828ec5 100644 --- a/ebean-core/src/test/java/org/tests/query/sqlquery/SqlQueryTests.java +++ b/ebean-core/src/test/java/org/tests/query/sqlquery/SqlQueryTests.java @@ -407,7 +407,7 @@ public class SqlQueryTests extends BaseTestCase { List sqlMetrics = sqlMetrics(); assertThat(sqlMetrics).hasSize(1); - assertThat(sqlMetrics.get(0).getName()).isEqualTo("sql.query.findEach-Max10Rows"); + assertThat(sqlMetrics.get(0).name()).isEqualTo("sql.query.findEach-Max10Rows"); } @Test diff --git a/ebean-core/src/test/java/org/tests/transaction/TestNestedMandatory.java b/ebean-core/src/test/java/org/tests/transaction/TestNestedMandatory.java index 91eb4e14f..de3184595 100644 --- a/ebean-core/src/test/java/org/tests/transaction/TestNestedMandatory.java +++ b/ebean-core/src/test/java/org/tests/transaction/TestNestedMandatory.java @@ -33,7 +33,7 @@ public class TestNestedMandatory extends BaseTestCase { } assertThat(txnMetrics).hasSize(2); - assertThat(txnMetrics.get(1).getName()).isEqualTo("txn.named.outer"); + assertThat(txnMetrics.get(1).name()).isEqualTo("txn.named.outer"); } class Outer { diff --git a/ebean-core/src/test/java/org/tests/transaction/TestTransactionalReadOnly.java b/ebean-core/src/test/java/org/tests/transaction/TestTransactionalReadOnly.java index 99f776f14..28e0be699 100644 --- a/ebean-core/src/test/java/org/tests/transaction/TestTransactionalReadOnly.java +++ b/ebean-core/src/test/java/org/tests/transaction/TestTransactionalReadOnly.java @@ -20,9 +20,9 @@ public class TestTransactionalReadOnly extends BaseTestCase { resetAllMetrics(); executeTransactionalUsingReadOnlyDataSource(); - final List timedMetrics = collectMetrics().getTimedMetrics(); + final List timedMetrics = collectMetrics().timedMetrics(); final Optional txnReadOnly = metric(timedMetrics, "txn.readonly"); - assertThat(txnReadOnly.get().getCount()).isEqualTo(1); + assertThat(txnReadOnly.get().count()).isEqualTo(1); assertThat(metric(timedMetrics, "txn")).isEmpty(); } @@ -32,15 +32,15 @@ public class TestTransactionalReadOnly extends BaseTestCase { resetAllMetrics(); executeTransactionalUsingMainDataSource(); - final List timedMetrics = collectMetrics().getTimedMetrics(); + final List timedMetrics = collectMetrics().timedMetrics(); final Optional txnMain = metric(timedMetrics, "txn.main"); - assertThat(txnMain.get().getCount()).isEqualTo(1); + assertThat(txnMain.get().count()).isEqualTo(1); assertThat(metric(timedMetrics, "txn.readonly")).isEmpty(); } private Optional metric(List timedMetrics, String name) { return timedMetrics.stream() - .filter(metaTimedMetric -> metaTimedMetric.getName().equals(name)) + .filter(metaTimedMetric -> metaTimedMetric.name().equals(name)) .findFirst(); } diff --git a/ebean-core/src/test/java/org/tests/update/TestSqlUpdateInTxn.java b/ebean-core/src/test/java/org/tests/update/TestSqlUpdateInTxn.java index 50ca87970..c539beda8 100644 --- a/ebean-core/src/test/java/org/tests/update/TestSqlUpdateInTxn.java +++ b/ebean-core/src/test/java/org/tests/update/TestSqlUpdateInTxn.java @@ -126,8 +126,8 @@ public class TestSqlUpdateInTxn extends BaseTestCase { List sqlMetrics = sqlMetrics(); assertThat(sqlMetrics).hasSize(1); - assertThat(sqlMetrics.get(0).getName()).isEqualTo("sql.update.auditLargeUpdate"); - assertThat(sqlMetrics.get(0).getCount()).isEqualTo(1); + assertThat(sqlMetrics.get(0).name()).isEqualTo("sql.update.auditLargeUpdate"); + assertThat(sqlMetrics.get(0).count()).isEqualTo(1); } @Test diff --git a/ebean-ddl-generator/src/test/java/io/ebean/BaseTestCase.java b/ebean-ddl-generator/src/test/java/io/ebean/BaseTestCase.java index 3abf51366..4c0410ff3 100644 --- a/ebean-ddl-generator/src/test/java/io/ebean/BaseTestCase.java +++ b/ebean-ddl-generator/src/test/java/io/ebean/BaseTestCase.java @@ -8,9 +8,7 @@ import io.ebean.meta.MetaTimedMetric; import io.ebean.meta.ServerMetrics; import io.ebean.util.StringHelper; import io.ebeaninternal.api.SpiEbeanServer; -import io.ebeaninternal.api.SpiQuery; import io.ebeaninternal.api.SpiTransaction; -import io.ebeaninternal.server.core.OrmQueryRequest; import io.ebeaninternal.server.deploy.BeanDescriptor; import io.ebeaninternal.server.expression.platform.DbExpressionHandler; import io.ebeaninternal.server.expression.platform.DbExpressionHandlerFactory; @@ -88,14 +86,14 @@ public abstract class BaseTestCase { } protected List visitTimedMetrics() { - return collectMetrics().getTimedMetrics(); + return collectMetrics().timedMetrics(); } protected List sqlMetrics() { List timedMetrics = visitTimedMetrics(); return timedMetrics.stream() - .filter((it) -> it.getName().startsWith("sql.") || it.getName().startsWith("orm.")) + .filter((it) -> it.name().startsWith("sql.") || it.name().startsWith("orm.")) .collect(Collectors.toList()); } diff --git a/ebean-redis/src/main/java/io/ebean/redis/RedisCache.java b/ebean-redis/src/main/java/io/ebean/redis/RedisCache.java index 39e670a7f..a69fb6766 100644 --- a/ebean-redis/src/main/java/io/ebean/redis/RedisCache.java +++ b/ebean-redis/src/main/java/io/ebean/redis/RedisCache.java @@ -255,14 +255,13 @@ class RedisCache implements ServerCache { @Override public ServerCacheStatistics getStatistics(boolean reset) { - ServerCacheStatistics cacheStats = new ServerCacheStatistics(); cacheStats.setCacheName(cacheKey); cacheStats.setHitCount(hitCount.get(reset)); cacheStats.setMissCount(missCount.get(reset)); - cacheStats.setPutCount(metricPut.collect(reset).getCount()); - cacheStats.setRemoveCount(metricRemove.collect(reset).getCount()); - cacheStats.setClearCount(metricClear.collect(reset).getCount()); + cacheStats.setPutCount(metricPut.collect(reset).count()); + cacheStats.setRemoveCount(metricRemove.collect(reset).count()); + cacheStats.setClearCount(metricClear.collect(reset).count()); return cacheStats; } } From fea7de42d5507f5c207dd05889a07f39f4018148 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 6 Aug 2021 14:48:42 +1200 Subject: [PATCH 052/120] #2290 - Add MetaTimedMetric locationHash() which is a crc32 checksum of package + type + method (excludes line number) --- .../main/java/io/ebean/ProfileLocation.java | 8 +++++ .../java/io/ebean/meta/MetaTimedMetric.java | 8 +++++ .../main/java/io/ebean/meta/MetricData.java | 9 ++++++ .../io/ebean/metric/TimedMetricStats.java | 5 ++++ .../server/core/DumpMetrics.java | 1 + .../server/core/DumpMetricsData.java | 2 ++ .../server/core/DumpMetricsJson.java | 2 ++ .../server/profile/BasicProfileLocation.java | 7 +++++ .../server/profile/DProfileLocation.java | 11 ++++--- .../server/profile/DQueryPlanMeta.java | 4 +++ .../server/profile/DQueryPlanMetric.java | 5 ++++ .../server/profile/DTimeMetricStats.java | 22 +++++++++----- .../server/profile/UtilLocation.java | 15 +++++++++- .../server/query/CQueryPlan.java | 30 ++++++------------- .../server/query/CQueryPlanStats.java | 5 ++++ .../server/profile/UtilLocationTest.java | 8 ++++- .../model/basic/finder/CustomerFinder.java | 2 -- .../tests/profile/ProfileLocationTest.java | 20 +++++++++---- .../query/finder/TestCustomerFinder.java | 3 +- 19 files changed, 124 insertions(+), 43 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/ProfileLocation.java b/ebean-api/src/main/java/io/ebean/ProfileLocation.java index 33584a0b3..605de580a 100644 --- a/ebean-api/src/main/java/io/ebean/ProfileLocation.java +++ b/ebean-api/src/main/java/io/ebean/ProfileLocation.java @@ -45,6 +45,14 @@ public interface ProfileLocation { */ String label(); + /** + * Return a hash of the location that intentionally excludes the line number. + *

+ * The hash is expected to be stable regardless of line number in the source file + * so that is identifies the class and method location over a long time. + */ + long hash(); + /** * Return the full location. */ diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java index f95f3248d..dbd0f0a0e 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java @@ -6,6 +6,14 @@ package io.ebean.meta; */ public interface MetaTimedMetric extends MetaMetric { + /** + * Return the metric location hash if defined. + *

+ * This hash excludes line number with the intention of being stable over time + * as code changes move the source line (but the method is the same). + */ + long locationHash(); + /** * Return the metric location if defined. */ diff --git a/ebean-api/src/main/java/io/ebean/meta/MetricData.java b/ebean-api/src/main/java/io/ebean/meta/MetricData.java index d8f80a0a9..7f2eb38b6 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetricData.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetricData.java @@ -14,6 +14,7 @@ public class MetricData { private Long mean; private Long max; private Long total; + private long locHash; public MetricData(String name) { this.name = name; @@ -38,6 +39,14 @@ public class MetricData { this.sqlHash = sqlHash; } + public void setLocHash(long locHash) { + this.locHash = locHash; + } + + public long getLocHash() { + return locHash; + } + public String getLoc() { return loc; } diff --git a/ebean-api/src/main/java/io/ebean/metric/TimedMetricStats.java b/ebean-api/src/main/java/io/ebean/metric/TimedMetricStats.java index 3012e9e9f..8c88d839e 100644 --- a/ebean-api/src/main/java/io/ebean/metric/TimedMetricStats.java +++ b/ebean-api/src/main/java/io/ebean/metric/TimedMetricStats.java @@ -12,6 +12,11 @@ public interface TimedMetricStats extends MetaTimedMetric { */ void setLocation(String location); + /** + * Additionally set the location hash. + */ + void setLocationHash(long locationHash); + /** * Override the name based on profile location. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java index f31fa849c..968e96a98 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java @@ -134,6 +134,7 @@ class DumpMetrics { String location = metric.location(); if (dumpLoc && location != null) { sb.append("\n loc:").append(location); + sb.append("\n locHash:").append(metric.locationHash()); } if (dumpSql) { sb.append(" \n\n sql:").append(metric.sql()).append("\n\n"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java index 4ac8859b6..07980228f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java @@ -56,6 +56,7 @@ class DumpMetricsData { final MetricData data = create(metric); appendCounters(data, metric); data.setLoc(metric.location()); + data.setLocHash(metric.locationHash()); } private void addCount(MetaCountMetric metric) { @@ -71,6 +72,7 @@ class DumpMetricsData { } private void appendLocationAndSql(MetricData data, MetaQueryMetric metric) { + data.setLocHash(metric.locationHash()); data.setLoc(metric.location()); data.setSql(metric.sql()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java index b0644ec9f..c116ebd26 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java @@ -188,6 +188,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { metricStart(metric); appendTiming(metric); if (isIncludeDetail(metric)) { + keyVal("locHash", metric.locationHash()); appendExtra("loc", metric.location()); } metricEnd(); @@ -198,6 +199,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { appendTiming(metric); if (withHash) { keyVal("sqlHash", metric.sqlHash()); + keyVal("locHash", metric.locationHash()); } if (isIncludeDetail(metric)) { appendExtra("loc", metric.location()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/BasicProfileLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/BasicProfileLocation.java index 507938a96..8e8a5ffc0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/BasicProfileLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/BasicProfileLocation.java @@ -10,9 +10,11 @@ final class BasicProfileLocation implements ProfileLocation { private final String fullLocation; private final String location; private final String label; + private final long hash; BasicProfileLocation(String fullLocation) { this.fullLocation = fullLocation; + this.hash = UtilLocation.hash(fullLocation); this.location = shortDesc(fullLocation); this.label = UtilLocation.label(location); } @@ -42,6 +44,11 @@ final class BasicProfileLocation implements ProfileLocation { return location; } + @Override + public long hash() { + return hash; + } + @Override public String fullLocation() { return fullLocation; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java index c5ff7d3ac..9c6340ad4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java @@ -8,17 +8,14 @@ import io.ebean.ProfileLocation; class DProfileLocation implements ProfileLocation { private static final String IO_EBEAN = "io.ebean"; - private static final String UNKNOWN = "unknown"; private String fullLocation; - private String location; - private String label; + private long hash; private final int lineNumber; - private int traceCount; DProfileLocation() { @@ -53,6 +50,7 @@ class DProfileLocation implements ProfileLocation { label = UtilLocation.label(shortDesc); location = shortDesc; fullLocation = loc; + hash = UtilLocation.hash(loc); initWith(label); return true; } @@ -71,6 +69,11 @@ class DProfileLocation implements ProfileLocation { return location; } + @Override + public long hash() { + return hash; + } + @Override public String fullLocation() { return fullLocation; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java index 5359d96ed..0354bbd0a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java @@ -49,6 +49,10 @@ class DQueryPlanMeta { return (profileLocation == null) ? null : profileLocation.location(); } + public long getLocationHash() { + return (profileLocation == null) ? 0 : profileLocation.hash(); + } + public String getSql() { return sql; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java index fda1d4d9b..41a0658f4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java @@ -83,6 +83,11 @@ class DQueryPlanMetric implements QueryPlanMetric { return meta.getLocation(); } + @Override + public long locationHash() { + return meta.getLocationHash(); + } + @Override public long count() { return stats.count(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java index 2207fef3d..82731dfd3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java @@ -7,18 +7,15 @@ import io.ebean.metric.TimedMetricStats; */ class DTimeMetricStats implements TimedMetricStats { - private String name; - private final boolean collected; - - private String location; - private final long count; - private final long total; - private final long max; + private String name; + private String location; + private long locationHash; + DTimeMetricStats(String name, boolean collected, long count, long total, long max) { this.name = name; this.collected = collected; @@ -40,6 +37,7 @@ class DTimeMetricStats implements TimedMetricStats { .append(" max:").append(max); if (location != null) { sb.append(" loc:").append(location); + sb.append(" locHash:").append(locationHash); } return sb.toString(); } @@ -49,6 +47,11 @@ class DTimeMetricStats implements TimedMetricStats { this.location = location; } + @Override + public void setLocationHash(long locationHash) { + this.locationHash = locationHash; + } + @Override public boolean initialCollection() { return !collected; @@ -69,6 +72,11 @@ class DTimeMetricStats implements TimedMetricStats { return location; } + @Override + public long locationHash() { + return locationHash; + } + /** * Return the count of values collected. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/UtilLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/UtilLocation.java index 7b70dfcb7..00b388bbd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/UtilLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/UtilLocation.java @@ -1,7 +1,21 @@ package io.ebeaninternal.server.profile; +import io.ebeaninternal.server.util.Checksum; + final class UtilLocation { + /** + * Return a hash of the full description excluding the source line number. + */ + static long hash(String full) { + final int pos = full.lastIndexOf('('); + if (pos > -1) { + return Checksum.checksum(full.substring(0, pos)); + } else { + return Checksum.checksum(full); + } + } + static String label(String shortDescription) { int pos = shortDescription.indexOf("("); if (pos == -1) { @@ -21,5 +35,4 @@ final class UtilLocation { } return desc; } - } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java index 796290808..770ac522d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java @@ -54,46 +54,32 @@ public class CQueryPlan implements SpiQueryPlan { static final String RESULT_SET_BASED_RAW_SQL = "--ResultSetBasedRawSql"; private final SpiEbeanServer server; - private final ProfileLocation profileLocation; - private final String location; - + private final long locationHash; private final String label; - private final String name; - private final CQueryPlanKey planKey; - private final boolean rawSql; - private final String sql; private final long sqlHash; - private final String logWhereSql; - private final SqlTree sqlTree; /** * Encrypted properties required additional binding. */ private final STreeProperty[] encryptedProps; - private final CQueryPlanStats stats; - private final Class beanType; - final DataTimeZone dataTimeZone; - private final int asOfTableCount; /** * Key used to identify the query plan in audit logging. */ private volatile String auditQueryHash; - private final Set dependentTables; - private final SpiQueryBindCapture bindCapture; /** @@ -106,9 +92,10 @@ public class CQueryPlan implements SpiQueryPlan { this.planKey = request.getQueryPlanKey(); SpiQuery query = request.getQuery(); this.profileLocation = query.getProfileLocation(); + this.location = (profileLocation == null) ? null : profileLocation.location(); + this.locationHash = (profileLocation == null) ? 0 : profileLocation.hash(); this.label = query.getPlanLabel(); this.name = deriveName(label, query.getType(), request.getBeanDescriptor().getSimpleName()); - this.location = location(); this.asOfTableCount = query.getAsOfTableCount(); this.sql = sqlRes.getSql(); this.sqlTree = sqlTree; @@ -130,9 +117,10 @@ public class CQueryPlan implements SpiQueryPlan { this.beanType = request.getBeanDescriptor().getBeanType(); SpiQuery query = request.getQuery(); this.profileLocation = query.getProfileLocation(); + this.location = (profileLocation == null) ? null : profileLocation.location(); + this.locationHash = (profileLocation == null) ? 0 : profileLocation.hash(); this.label = query.getPlanLabel(); this.name = deriveName(label, query.getType(), request.getBeanDescriptor().getSimpleName()); - this.location = location(); this.planKey = buildPlanKey(sql, logWhereSql); this.asOfTableCount = 0; this.sql = sql; @@ -169,10 +157,6 @@ public class CQueryPlan implements SpiQueryPlan { return sql.equals(RESULT_SET_BASED_RAW_SQL) || query.getType().isUpdate() ? SpiQueryBindCapture.NOOP : server.createQueryBindCapture(this); } - private String location() { - return (profileLocation == null) ? null : profileLocation.location(); - } - private CQueryPlanKey buildPlanKey(String sql, String logWhereSql) { return new RawSqlQueryPlanKey(sql, false, logWhereSql); } @@ -219,6 +203,10 @@ public class CQueryPlan implements SpiQueryPlan { return location; } + public long getLocationHash() { + return locationHash; + } + @Override public void queryPlanInit(long thresholdMicros) { bindCapture.queryPlanInit(thresholdMicros); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java index 36e070653..ab7dc0b63 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java @@ -106,6 +106,11 @@ public final class CQueryPlanStats { return queryPlan.getLocation(); } + @Override + public long locationHash() { + return queryPlan.getLocationHash(); + } + @Override public long count() { return metrics.count(); diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/UtilLocationTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/UtilLocationTest.java index 1bdbcd2f7..5fcbe90a4 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/UtilLocationTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/UtilLocationTest.java @@ -8,8 +8,14 @@ public class UtilLocationTest { @Test public void label() { - assertThat(UtilLocation.label("foo")).isEqualTo("foo"); assertThat(UtilLocation.label("ProfileLocationTest$Other.(ProfileLocationTest.java:47)")).isEqualTo("ProfileLocationTest$Other.init"); } + + @Test + public void hash() { + assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:12)")).isEqualTo(396279222L); + assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:13)")).isEqualTo(396279222L); + assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:945)")).isEqualTo(396279222L); + } } diff --git a/ebean-core/src/test/java/org/tests/model/basic/finder/CustomerFinder.java b/ebean-core/src/test/java/org/tests/model/basic/finder/CustomerFinder.java index c76728fca..79db60023 100644 --- a/ebean-core/src/test/java/org/tests/model/basic/finder/CustomerFinder.java +++ b/ebean-core/src/test/java/org/tests/model/basic/finder/CustomerFinder.java @@ -37,7 +37,6 @@ public class CustomerFinder extends Finder { } public List byNameStatus(String nameStartsWith, Customer.Status status) { - return query("where status = :status and name istartsWith :name order by name") .setParameter("status", status) .setParameter("name", nameStartsWith) @@ -45,7 +44,6 @@ public class CustomerFinder extends Finder { } public List namesStartingWith(String name) { - return nativeSql("select name from o_customer where name like ? order by name") .setParameter(name + "%") .findSingleAttributeList(); diff --git a/ebean-core/src/test/java/org/tests/profile/ProfileLocationTest.java b/ebean-core/src/test/java/org/tests/profile/ProfileLocationTest.java index d93b5c75f..d452b7463 100644 --- a/ebean-core/src/test/java/org/tests/profile/ProfileLocationTest.java +++ b/ebean-core/src/test/java/org/tests/profile/ProfileLocationTest.java @@ -7,20 +7,28 @@ import static org.assertj.core.api.Assertions.assertThat; public class ProfileLocationTest { - private static ProfileLocation loc = ProfileLocation.create(12, "foo"); - - private static ProfileLocation loc2 = ProfileLocation.create(); + private static final ProfileLocation loc = ProfileLocation.create(12, "foo"); + private static final ProfileLocation locB = ProfileLocation.create(); + private static final ProfileLocation loc2 = ProfileLocation.create(); private boolean doIt() { + locB.obtain(); // simulate a location moving by line number only return loc.obtain(); } @Test public void test_obtain() { assertThat(doIt()).isTrue(); - assertThat(loc.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:15)"); - assertThat(loc.location()).isEqualTo("ProfileLocationTest.doIt(ProfileLocationTest.java:15)"); + assertThat(loc.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:16)"); + assertThat(loc.location()).isEqualTo("ProfileLocationTest.doIt(ProfileLocationTest.java:16)"); assertThat(loc.label()).isEqualTo("ProfileLocationTest.doIt"); + assertThat(loc.hash()).isEqualTo(1867926812L); + + // same hash even when the line number has changed + assertThat(locB.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:15)"); + assertThat(locB.location()).isEqualTo("ProfileLocationTest.doIt(ProfileLocationTest.java:15)"); + assertThat(locB.label()).isEqualTo("ProfileLocationTest.doIt"); + assertThat(locB.hash()).isEqualTo(1867926812L); } @Test @@ -35,7 +43,7 @@ public class ProfileLocationTest { other.hashCode(); assertThat(loc2.label()).isEqualTo("ProfileLocationTest$Other.init"); - assertThat(loc2.location()).isEqualTo("ProfileLocationTest$Other.(ProfileLocationTest.java:44)"); + assertThat(loc2.location()).isEqualTo("ProfileLocationTest$Other.(ProfileLocationTest.java:52)"); } static class Other { diff --git a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java index 108b4a398..6dfd99422 100644 --- a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java +++ b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java @@ -242,7 +242,8 @@ public class TestCustomerFinder extends BaseTestCase { assertThat(metricsJson).contains("\"name\":\"txn.main\""); assertThat(metricsJson).contains("\"name\":\"orm.Customer.findList\""); - assertThat(metricsJson).contains("\"loc\":\"CustomerFinder.byNameStatus(CustomerFinder.java:44)\""); + assertThat(metricsJson).contains("\"locHash\":3254522637"); + assertThat(metricsJson).contains("\"loc\":\"CustomerFinder.byNameStatus(CustomerFinder.java:43)\""); if (isH2() || isPostgres()) { assertThat(metricsJson).contains("\"sqlHash\":3634991469"); assertThat(metricsJson).contains("\"sql\":\"select t0.id, t0.status,"); From ee615836bafe925fc6e29cc23a9dc68132633c4b Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 6 Aug 2021 14:56:09 +1200 Subject: [PATCH 053/120] [maven-release-plugin] prepare release ebean-parent-12.11.0 --- ebean-api/pom.xml | 2 +- ebean-autotune/pom.xml | 6 +++--- ebean-bom/pom.xml | 30 +++++++++++++++--------------- ebean-core-type/pom.xml | 4 ++-- ebean-core/pom.xml | 10 +++++----- ebean-ddl-generator/pom.xml | 6 +++--- ebean-externalmapping-api/pom.xml | 2 +- ebean-externalmapping-xml/pom.xml | 10 +++++----- ebean-postgis/pom.xml | 6 +++--- ebean-querybean/pom.xml | 10 +++++----- ebean-redis/pom.xml | 12 ++++++------ ebean-test/pom.xml | 6 +++--- ebean/pom.xml | 8 ++++---- kotlin-querybean-generator/pom.xml | 11 +++++------ pom.xml | 4 ++-- querybean-generator/pom.xml | 2 +- 16 files changed, 64 insertions(+), 65 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 9afbb6446..645581876 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean api diff --git a/ebean-autotune/pom.xml b/ebean-autotune/pom.xml index 0b0355981..e4a105be8 100644 --- a/ebean-autotune/pom.xml +++ b/ebean-autotune/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.8.0 + ebean-parent-12.11.0 ebean autotune @@ -26,7 +26,7 @@ io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 provided diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index 35ed6d6a0..220dc3e72 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean bom @@ -81,88 +81,88 @@ io.ebean ebean - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-api - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-core-type - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-ddl-generator - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-externalmapping-api - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-externalmapping-xml - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-autotune - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-querybean - 12.11.0-SNAPSHOT + 12.11.0 io.ebean querybean-generator - 12.11.0-SNAPSHOT + 12.11.0 provided io.ebean kotlin-querybean-generator - 12.11.0-SNAPSHOT + 12.11.0 provided io.ebean ebean-test - 12.11.0-SNAPSHOT + 12.11.0 test io.ebean ebean-postgis - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-redis - 12.11.0-SNAPSHOT + 12.11.0 diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml index 35a29a677..7911ebaff 100644 --- a/ebean-core-type/pom.xml +++ b/ebean-core-type/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean-core-type @@ -16,7 +16,7 @@ io.ebean ebean-api - 12.11.0-SNAPSHOT + 12.11.0 diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index 3426582d3..43d628258 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -3,7 +3,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean-core @@ -15,7 +15,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.8.0 + ebean-parent-12.11.0 @@ -87,19 +87,19 @@ io.ebean ebean-api - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-core-type - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-externalmapping-api - 12.11.0-SNAPSHOT + 12.11.0 diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index 4035af5f2..5db1fd673 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean ddl generation @@ -28,14 +28,14 @@ io.ebean ebean-core-type - 12.11.0-SNAPSHOT + 12.11.0 provided io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 provided diff --git a/ebean-externalmapping-api/pom.xml b/ebean-externalmapping-api/pom.xml index a9b9968b9..29cccfacc 100644 --- a/ebean-externalmapping-api/pom.xml +++ b/ebean-externalmapping-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean external mapping api diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index 3f0b71546..0997c343a 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.8.0 + ebean-parent-12.11.0 ebean external mapping xml @@ -33,7 +33,7 @@ io.ebean ebean-externalmapping-api - 12.11.0-SNAPSHOT + 12.11.0 @@ -59,14 +59,14 @@ io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 test io.ebean ebean-ddl-generator - 12.11.0-SNAPSHOT + 12.11.0 test diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml index a6bfe2ed0..0c69fd30b 100644 --- a/ebean-postgis/pom.xml +++ b/ebean-postgis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean postgis @@ -23,7 +23,7 @@ io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 provided @@ -74,7 +74,7 @@ io.ebean ebean-test - 12.11.0-SNAPSHOT + 12.11.0 test diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml index b3ffadfc0..cfd9f569e 100644 --- a/ebean-querybean/pom.xml +++ b/ebean-querybean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean querybean @@ -17,7 +17,7 @@ io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 provided @@ -57,21 +57,21 @@ io.ebean ebean-ddl-generator - 12.11.0-SNAPSHOT + 12.11.0 test io.ebean querybean-generator - 12.11.0-SNAPSHOT + 12.11.0 test io.ebean ebean-test - 12.11.0-SNAPSHOT + 12.11.0 test diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index d0d5f8ee2..a3e5bbf91 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean-redis @@ -22,35 +22,35 @@ io.ebean ebean-api - 12.11.0-SNAPSHOT + 12.11.0 provided io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 provided io.ebean ebean-querybean - 12.11.0-SNAPSHOT + 12.11.0 test io.ebean querybean-generator - 12.11.0-SNAPSHOT + 12.11.0 test io.ebean ebean-test - 12.11.0-SNAPSHOT + 12.11.0 test diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 43b5ee6f3..97ae36c87 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean test @@ -29,14 +29,14 @@ io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 provided io.ebean ebean-ddl-generator - 12.11.0-SNAPSHOT + 12.11.0 diff --git a/ebean/pom.xml b/ebean/pom.xml index 819328290..e283dc067 100644 --- a/ebean/pom.xml +++ b/ebean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 ebean composite @@ -22,20 +22,20 @@ io.ebean ebean-api - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 io.ebean ebean-querybean - 12.11.0-SNAPSHOT + 12.11.0 diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml index 8f3cafa8a..80cdb4f26 100644 --- a/kotlin-querybean-generator/pom.xml +++ b/kotlin-querybean-generator/pom.xml @@ -1,11 +1,10 @@ - + 4.0.0 ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 kotlin querybean generator @@ -30,7 +29,7 @@ io.ebean ebean-querybean - 12.11.0-SNAPSHOT + 12.11.0 test @@ -44,7 +43,7 @@ io.ebean ebean-core - 12.11.0-SNAPSHOT + 12.11.0 test @@ -65,7 +64,7 @@ io.ebean ebean-ddl-generator - 12.11.0-SNAPSHOT + 12.11.0 test diff --git a/pom.xml b/pom.xml index b86928387..d104f7afe 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.ebean ebean-parent - 12.11.0-SNAPSHOT + 12.11.0 pom ebean parent @@ -18,7 +18,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.8.0 + ebean-parent-12.11.0 diff --git a/querybean-generator/pom.xml b/querybean-generator/pom.xml index 956e39cb5..6d0b1af1b 100644 --- a/querybean-generator/pom.xml +++ b/querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0-SNAPSHOT + 12.11.0 querybean generator From c4484c758ec2729d0796fc50573ada0920eb16f9 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 6 Aug 2021 14:56:15 +1200 Subject: [PATCH 054/120] [maven-release-plugin] prepare for next development iteration --- ebean-api/pom.xml | 2 +- ebean-autotune/pom.xml | 6 +++--- ebean-bom/pom.xml | 30 +++++++++++++++--------------- ebean-core-type/pom.xml | 4 ++-- ebean-core/pom.xml | 10 +++++----- ebean-ddl-generator/pom.xml | 6 +++--- ebean-externalmapping-api/pom.xml | 2 +- ebean-externalmapping-xml/pom.xml | 10 +++++----- ebean-postgis/pom.xml | 6 +++--- ebean-querybean/pom.xml | 10 +++++----- ebean-redis/pom.xml | 12 ++++++------ ebean-test/pom.xml | 6 +++--- ebean/pom.xml | 8 ++++---- kotlin-querybean-generator/pom.xml | 8 ++++---- pom.xml | 4 ++-- querybean-generator/pom.xml | 2 +- 16 files changed, 63 insertions(+), 63 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 645581876..72fbfe3ae 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean api diff --git a/ebean-autotune/pom.xml b/ebean-autotune/pom.xml index e4a105be8..c47f7fe08 100644 --- a/ebean-autotune/pom.xml +++ b/ebean-autotune/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.11.0 + ebean-parent-12.8.0 ebean autotune @@ -26,7 +26,7 @@ io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT provided diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index 220dc3e72..fff064c90 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean bom @@ -81,88 +81,88 @@ io.ebean ebean - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-api - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-core-type - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-ddl-generator - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-externalmapping-api - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-externalmapping-xml - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-autotune - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-querybean - 12.11.0 + 12.11.1-SNAPSHOT io.ebean querybean-generator - 12.11.0 + 12.11.1-SNAPSHOT provided io.ebean kotlin-querybean-generator - 12.11.0 + 12.11.1-SNAPSHOT provided io.ebean ebean-test - 12.11.0 + 12.11.1-SNAPSHOT test io.ebean ebean-postgis - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-redis - 12.11.0 + 12.11.1-SNAPSHOT diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml index 7911ebaff..d8eab3e25 100644 --- a/ebean-core-type/pom.xml +++ b/ebean-core-type/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean-core-type @@ -16,7 +16,7 @@ io.ebean ebean-api - 12.11.0 + 12.11.1-SNAPSHOT diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index 43d628258..11aac552a 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -3,7 +3,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean-core @@ -15,7 +15,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.11.0 + ebean-parent-12.8.0 @@ -87,19 +87,19 @@ io.ebean ebean-api - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-core-type - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-externalmapping-api - 12.11.0 + 12.11.1-SNAPSHOT diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index 5db1fd673..f83a8b02e 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean ddl generation @@ -28,14 +28,14 @@ io.ebean ebean-core-type - 12.11.0 + 12.11.1-SNAPSHOT provided io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT provided diff --git a/ebean-externalmapping-api/pom.xml b/ebean-externalmapping-api/pom.xml index 29cccfacc..e506a6841 100644 --- a/ebean-externalmapping-api/pom.xml +++ b/ebean-externalmapping-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean external mapping api diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index 0997c343a..d0226a553 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.11.0 + ebean-parent-12.8.0 ebean external mapping xml @@ -33,7 +33,7 @@ io.ebean ebean-externalmapping-api - 12.11.0 + 12.11.1-SNAPSHOT @@ -59,14 +59,14 @@ io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT test io.ebean ebean-ddl-generator - 12.11.0 + 12.11.1-SNAPSHOT test diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml index 0c69fd30b..98b44522d 100644 --- a/ebean-postgis/pom.xml +++ b/ebean-postgis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean postgis @@ -23,7 +23,7 @@ io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT provided @@ -74,7 +74,7 @@ io.ebean ebean-test - 12.11.0 + 12.11.1-SNAPSHOT test diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml index cfd9f569e..059976afa 100644 --- a/ebean-querybean/pom.xml +++ b/ebean-querybean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean querybean @@ -17,7 +17,7 @@ io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT provided @@ -57,21 +57,21 @@ io.ebean ebean-ddl-generator - 12.11.0 + 12.11.1-SNAPSHOT test io.ebean querybean-generator - 12.11.0 + 12.11.1-SNAPSHOT test io.ebean ebean-test - 12.11.0 + 12.11.1-SNAPSHOT test diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index a3e5bbf91..943ab6985 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean-redis @@ -22,35 +22,35 @@ io.ebean ebean-api - 12.11.0 + 12.11.1-SNAPSHOT provided io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT provided io.ebean ebean-querybean - 12.11.0 + 12.11.1-SNAPSHOT test io.ebean querybean-generator - 12.11.0 + 12.11.1-SNAPSHOT test io.ebean ebean-test - 12.11.0 + 12.11.1-SNAPSHOT test diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 97ae36c87..4b9b05272 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean test @@ -29,14 +29,14 @@ io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT provided io.ebean ebean-ddl-generator - 12.11.0 + 12.11.1-SNAPSHOT diff --git a/ebean/pom.xml b/ebean/pom.xml index e283dc067..db01d91a1 100644 --- a/ebean/pom.xml +++ b/ebean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT ebean composite @@ -22,20 +22,20 @@ io.ebean ebean-api - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT io.ebean ebean-querybean - 12.11.0 + 12.11.1-SNAPSHOT diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml index 80cdb4f26..1b3f9d848 100644 --- a/kotlin-querybean-generator/pom.xml +++ b/kotlin-querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT kotlin querybean generator @@ -29,7 +29,7 @@ io.ebean ebean-querybean - 12.11.0 + 12.11.1-SNAPSHOT test @@ -43,7 +43,7 @@ io.ebean ebean-core - 12.11.0 + 12.11.1-SNAPSHOT test @@ -64,7 +64,7 @@ io.ebean ebean-ddl-generator - 12.11.0 + 12.11.1-SNAPSHOT test diff --git a/pom.xml b/pom.xml index d104f7afe..dc3426809 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.ebean ebean-parent - 12.11.0 + 12.11.1-SNAPSHOT pom ebean parent @@ -18,7 +18,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.11.0 + ebean-parent-12.8.0 diff --git a/querybean-generator/pom.xml b/querybean-generator/pom.xml index 6d0b1af1b..a240e3b8b 100644 --- a/querybean-generator/pom.xml +++ b/querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.0 + 12.11.1-SNAPSHOT querybean generator From c610f95b2d2da07ae15d8993b5fbdbd6dbfc25e4 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 9 Aug 2021 14:05:10 +1200 Subject: [PATCH 055/120] #2293 - Metric hash back to MD5 of sql + name + loc (minus location file and line source) ~= Revert of #2288 --- .../main/java/io/ebean/ProfileLocation.java | 8 --- .../java/io/ebean/meta/MetaQueryMetric.java | 11 +--- .../java/io/ebean/meta/MetaQueryPlan.java | 2 +- .../java/io/ebean/meta/MetaTimedMetric.java | 8 --- .../main/java/io/ebean/meta/MetricData.java | 19 ++----- .../java/io/ebean/meta/QueryPlanInit.java | 10 ++-- .../io/ebean/metric/TimedMetricStats.java | 5 -- .../io/ebeaninternal/api/SpiQueryPlan.java | 2 +- .../server/core/DumpMetrics.java | 3 +- .../server/core/DumpMetricsData.java | 4 +- .../server/core/DumpMetricsJson.java | 22 ++++---- .../server/deploy/BeanDescriptor.java | 2 +- .../server/profile/BasicProfileLocation.java | 20 +------ .../server/profile/DProfileLocation.java | 31 ++--------- .../server/profile/DQueryPlanMeta.java | 15 +++--- .../server/profile/DQueryPlanMetric.java | 9 +--- .../server/profile/DTimeMetricStats.java | 12 ----- .../server/profile/UtilLocation.java | 29 +++++----- .../server/query/CQueryPlan.java | 23 +++----- .../server/query/CQueryPlanStats.java | 9 +--- .../server/query/DQueryPlanOutput.java | 12 ++--- .../io/ebeaninternal/server/util/Md5.java | 36 +++++++++++++ .../profile/BasicProfileLocationTest.java | 6 +-- .../server/profile/UtilLocationTest.java | 9 ++-- .../io/ebeaninternal/server/util/Md5Test.java | 53 +++++++++++++++++++ .../tests/profile/ProfileLocationTest.java | 8 ++- .../query/finder/TestCustomerFinder.java | 5 +- 27 files changed, 172 insertions(+), 201 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java create mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/util/Md5Test.java diff --git a/ebean-api/src/main/java/io/ebean/ProfileLocation.java b/ebean-api/src/main/java/io/ebean/ProfileLocation.java index 605de580a..33584a0b3 100644 --- a/ebean-api/src/main/java/io/ebean/ProfileLocation.java +++ b/ebean-api/src/main/java/io/ebean/ProfileLocation.java @@ -45,14 +45,6 @@ public interface ProfileLocation { */ String label(); - /** - * Return a hash of the location that intentionally excludes the line number. - *

- * The hash is expected to be stable regardless of line number in the source file - * so that is identifies the class and method location over a long time. - */ - long hash(); - /** * Return the full location. */ diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java index f5fee986c..1c9b5fe12 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaQueryMetric.java @@ -45,15 +45,8 @@ public interface MetaQueryMetric extends MetaTimedMetric { } /** - * Return the hash of the sql. + * Return the hash of the plan. */ - long sqlHash(); + String hash(); - /** - * Migrate to sqlHash(). - */ - @Deprecated - default long getSqlHash() { - return sqlHash(); - } } diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java b/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java index 6cdce69a1..c1ae44a82 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaQueryPlan.java @@ -30,7 +30,7 @@ public interface MetaQueryPlan { /** * Return the hash of the plan. */ - long sqlHash(); + String hash(); /** * Return a description of the bind values. diff --git a/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java b/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java index dbd0f0a0e..f95f3248d 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetaTimedMetric.java @@ -6,14 +6,6 @@ package io.ebean.meta; */ public interface MetaTimedMetric extends MetaMetric { - /** - * Return the metric location hash if defined. - *

- * This hash excludes line number with the intention of being stable over time - * as code changes move the source line (but the method is the same). - */ - long locationHash(); - /** * Return the metric location if defined. */ diff --git a/ebean-api/src/main/java/io/ebean/meta/MetricData.java b/ebean-api/src/main/java/io/ebean/meta/MetricData.java index 7f2eb38b6..b4606b1d7 100644 --- a/ebean-api/src/main/java/io/ebean/meta/MetricData.java +++ b/ebean-api/src/main/java/io/ebean/meta/MetricData.java @@ -6,7 +6,7 @@ package io.ebean.meta; public class MetricData { private String name; - private long sqlHash; + private String hash; private String loc; private String sql; @@ -14,7 +14,6 @@ public class MetricData { private Long mean; private Long max; private Long total; - private long locHash; public MetricData(String name) { this.name = name; @@ -31,20 +30,12 @@ public class MetricData { this.name = name; } - public long getSqlHash() { - return sqlHash; + public String getHash() { + return hash; } - public void setSqlHash(long sqlHash) { - this.sqlHash = sqlHash; - } - - public void setLocHash(long locHash) { - this.locHash = locHash; - } - - public long getLocHash() { - return locHash; + public void setHash(String hash) { + this.hash = hash; } public String getLoc() { diff --git a/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java b/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java index 7caeabd2f..5cce68994 100644 --- a/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java +++ b/ebean-api/src/main/java/io/ebean/meta/QueryPlanInit.java @@ -10,7 +10,7 @@ public class QueryPlanInit { private boolean all; - private Set hashes = new HashSet<>(); + private Set hashes = new HashSet<>(); private long thresholdMicros; @@ -47,21 +47,21 @@ public class QueryPlanInit { /** * Return true if the query plan should be initiated based on it's hash. */ - public boolean includeHash(long sqlHash) { - return all || hashes.contains(sqlHash); + public boolean includeHash(String hash) { + return all || hashes.contains(hash); } /** * Return the specific hashes that we want to collect query plans on. */ - public Set sqlHashes() { + public Set hashes() { return hashes; } /** * Set the specific hashes that we want to collect query plans on. */ - public void sqlHashes(Set hashes) { + public void hashes(Set hashes) { this.hashes = hashes; } } diff --git a/ebean-api/src/main/java/io/ebean/metric/TimedMetricStats.java b/ebean-api/src/main/java/io/ebean/metric/TimedMetricStats.java index 8c88d839e..3012e9e9f 100644 --- a/ebean-api/src/main/java/io/ebean/metric/TimedMetricStats.java +++ b/ebean-api/src/main/java/io/ebean/metric/TimedMetricStats.java @@ -12,11 +12,6 @@ public interface TimedMetricStats extends MetaTimedMetric { */ void setLocation(String location); - /** - * Additionally set the location hash. - */ - void setLocationHash(long locationHash); - /** * Override the name based on profile location. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java index 878dcc716..0b4c3ea0a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQueryPlan.java @@ -20,7 +20,7 @@ public interface SpiQueryPlan { /** * The hash of the sql. */ - long getSqlHash(); + String getHash(); /** * The SQL for the query plan. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java index 968e96a98..5274b4ced 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java @@ -120,7 +120,7 @@ class DumpMetrics { appendQueryName(metric, sb); appendCounters(metric, sb); if (dumpHash) { - sb.append("\n sqlHash:").append(metric.sqlHash()); + sb.append("\n hash:").append(metric.hash()); } appendProfileAndSql(metric, sb); out(sb.toString()); @@ -134,7 +134,6 @@ class DumpMetrics { String location = metric.location(); if (dumpLoc && location != null) { sb.append("\n loc:").append(location); - sb.append("\n locHash:").append(metric.locationHash()); } if (dumpSql) { sb.append(" \n\n sql:").append(metric.sql()).append("\n\n"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java index 07980228f..4bc1e5035 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java @@ -56,7 +56,6 @@ class DumpMetricsData { final MetricData data = create(metric); appendCounters(data, metric); data.setLoc(metric.location()); - data.setLocHash(metric.locationHash()); } private void addCount(MetaCountMetric metric) { @@ -68,11 +67,10 @@ class DumpMetricsData { final MetricData data = create(metric); appendCounters(data, metric); appendLocationAndSql(data, metric); - data.setSqlHash(metric.sqlHash()); + data.setHash(metric.hash()); } private void appendLocationAndSql(MetricData data, MetaQueryMetric metric) { - data.setLocHash(metric.locationHash()); data.setLoc(metric.location()); data.setSql(metric.sql()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java index c116ebd26..90200f79b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java @@ -188,8 +188,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { metricStart(metric); appendTiming(metric); if (isIncludeDetail(metric)) { - keyVal("locHash", metric.locationHash()); - appendExtra("loc", metric.location()); + append("loc", metric.location()); } metricEnd(); } @@ -198,12 +197,11 @@ class DumpMetricsJson implements ServerMetricsAsJson { metricStart(metric); appendTiming(metric); if (withHash) { - keyVal("sqlHash", metric.sqlHash()); - keyVal("locHash", metric.locationHash()); + append("hash", metric.hash()); } if (isIncludeDetail(metric)) { - appendExtra("loc", metric.location()); - appendExtra("sql", metric.sql()); + append("loc", metric.location()); + append("sql", metric.sql()); } metricEnd(); } @@ -212,7 +210,7 @@ class DumpMetricsJson implements ServerMetricsAsJson { return includeExtraAttributes == 2 || includeExtraAttributes == 1 && metric.initialCollection(); } - private void appendExtra(String key, String val) throws IOException { + private void append(String key, String val) throws IOException { if (val != null) { key(key); val(val); @@ -220,13 +218,13 @@ class DumpMetricsJson implements ServerMetricsAsJson { } private void appendTiming(MetaTimedMetric timedMetric) throws IOException { - keyVal("count", timedMetric.count()); - keyVal("total", timedMetric.total()); - keyVal("mean", timedMetric.mean()); - keyVal("max", timedMetric.max()); + append("count", timedMetric.count()); + append("total", timedMetric.total()); + append("mean", timedMetric.mean()); + append("max", timedMetric.max()); } - private void keyVal(String key, long value) throws IOException { + private void append(String key, long value) throws IOException { key(key); val(value); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 6a9acd839..8e8b02b6f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -1558,7 +1558,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { void queryPlanInit(QueryPlanInit request, List list) { for (CQueryPlan queryPlan : queryPlanCache.values()) { - if (request.includeHash(queryPlan.getSqlHash())) { + if (request.includeHash(queryPlan.getHash())) { queryPlan.queryPlanInit(request.thresholdMicros()); list.add(queryPlan.createMeta(null, null)); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/BasicProfileLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/BasicProfileLocation.java index 8e8a5ffc0..d7d5b0fd2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/BasicProfileLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/BasicProfileLocation.java @@ -10,12 +10,10 @@ final class BasicProfileLocation implements ProfileLocation { private final String fullLocation; private final String location; private final String label; - private final long hash; BasicProfileLocation(String fullLocation) { this.fullLocation = fullLocation; - this.hash = UtilLocation.hash(fullLocation); - this.location = shortDesc(fullLocation); + this.location = UtilLocation.loc(fullLocation); this.label = UtilLocation.label(location); } @@ -44,11 +42,6 @@ final class BasicProfileLocation implements ProfileLocation { return location; } - @Override - public long hash() { - return hash; - } - @Override public String fullLocation() { return fullLocation; @@ -64,15 +57,4 @@ final class BasicProfileLocation implements ProfileLocation { // do nothing } - private String shortDesc(String location) { - int lastPer = location.lastIndexOf('.'); - if (lastPer > -1) { - lastPer = location.lastIndexOf('.', lastPer - 1); - if (lastPer > -1) { - return location.substring(lastPer + 1); - } - } - return location; - } - } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java index 9c6340ad4..63fa0e11a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java @@ -13,7 +13,6 @@ class DProfileLocation implements ProfileLocation { private String fullLocation; private String location; private String label; - private long hash; private final int lineNumber; private int traceCount; @@ -46,11 +45,10 @@ class DProfileLocation implements ProfileLocation { return false; } final String loc = create(); - final String shortDesc = shortDesc(loc); - label = UtilLocation.label(shortDesc); - location = shortDesc; - fullLocation = loc; - hash = UtilLocation.hash(loc); + final String location = UtilLocation.loc(loc); + this.label = UtilLocation.label(location); + this.location = location; + this.fullLocation = loc; initWith(label); return true; } @@ -69,11 +67,6 @@ class DProfileLocation implements ProfileLocation { return location; } - @Override - public long hash() { - return hash; - } - @Override public String fullLocation() { return fullLocation; @@ -116,20 +109,4 @@ class DProfileLocation implements ProfileLocation { return traceLine.substring(0, traceLine.length() - 1) + ":" + lineNumber + ")"; } } - - private String shortDesc(String location) { - int pos = location.lastIndexOf('('); - if (pos == -1) { - pos = location.length(); - } - - pos = location.lastIndexOf('.', pos); - if (pos > -1) { - pos = location.lastIndexOf('.', pos - 1); - if (pos > -1) { - return location.substring(pos + 1); - } - } - return location; - } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java index 0354bbd0a..67f724051 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.profile; import io.ebean.ProfileLocation; -import io.ebeaninternal.server.util.Checksum; +import io.ebeaninternal.server.util.Md5; class DQueryPlanMeta { @@ -10,7 +10,7 @@ class DQueryPlanMeta { private final ProfileLocation profileLocation; private final String name; private final String sql; - private final long sqlHash; + private final String hash; DQueryPlanMeta(Class type, String label, ProfileLocation profileLocation, String sql) { this.type = type; @@ -22,15 +22,16 @@ class DQueryPlanMeta { name += "_" + label; } this.name = name; - this.sqlHash = Checksum.checksum(sql); + String loc = profileLocation == null ? null : profileLocation.location(); + this.hash = Md5.hash(sql, name, loc); } public Class getType() { return type; } - public long getSqlHash() { - return sqlHash; + public String getHash() { + return hash; } public String getName() { @@ -49,10 +50,6 @@ class DQueryPlanMeta { return (profileLocation == null) ? null : profileLocation.location(); } - public long getLocationHash() { - return (profileLocation == null) ? 0 : profileLocation.hash(); - } - public String getSql() { return sql; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java index 41a0658f4..e24da73c7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java @@ -59,8 +59,8 @@ class DQueryPlanMetric implements QueryPlanMetric { } @Override - public long sqlHash() { - return meta.getSqlHash(); + public String hash() { + return meta.getHash(); } @Override @@ -83,11 +83,6 @@ class DQueryPlanMetric implements QueryPlanMetric { return meta.getLocation(); } - @Override - public long locationHash() { - return meta.getLocationHash(); - } - @Override public long count() { return stats.count(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java index 82731dfd3..a4243e31a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java @@ -14,7 +14,6 @@ class DTimeMetricStats implements TimedMetricStats { private String name; private String location; - private long locationHash; DTimeMetricStats(String name, boolean collected, long count, long total, long max) { this.name = name; @@ -37,7 +36,6 @@ class DTimeMetricStats implements TimedMetricStats { .append(" max:").append(max); if (location != null) { sb.append(" loc:").append(location); - sb.append(" locHash:").append(locationHash); } return sb.toString(); } @@ -47,11 +45,6 @@ class DTimeMetricStats implements TimedMetricStats { this.location = location; } - @Override - public void setLocationHash(long locationHash) { - this.locationHash = locationHash; - } - @Override public boolean initialCollection() { return !collected; @@ -72,11 +65,6 @@ class DTimeMetricStats implements TimedMetricStats { return location; } - @Override - public long locationHash() { - return locationHash; - } - /** * Return the count of values collected. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/UtilLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/UtilLocation.java index 00b388bbd..65ab1ce4d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/UtilLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/UtilLocation.java @@ -1,28 +1,29 @@ package io.ebeaninternal.server.profile; -import io.ebeaninternal.server.util.Checksum; - final class UtilLocation { - /** - * Return a hash of the full description excluding the source line number. - */ - static long hash(String full) { + static String loc(String full) { final int pos = full.lastIndexOf('('); if (pos > -1) { - return Checksum.checksum(full.substring(0, pos)); + return full.substring(0, pos); } else { - return Checksum.checksum(full); + return full; } } - static String label(String shortDescription) { - int pos = shortDescription.indexOf("("); - if (pos == -1) { - return shortDescription; - } else { - return trimInit(shortDescription.substring(0, pos)); + static String label(String location) { + return trimInit(shortDesc(location)); + } + + private static String shortDesc(String location) { + int pos = location.lastIndexOf('.'); + if (pos > -1) { + pos = location.lastIndexOf('.', pos - 1); + if (pos > -1) { + return location.substring(pos + 1); + } } + return location; } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java index 770ac522d..de365f253 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java @@ -13,7 +13,7 @@ import io.ebeaninternal.api.SpiQueryBindCapture; import io.ebeaninternal.api.SpiQueryPlan; import io.ebeaninternal.server.core.OrmQueryRequest; import io.ebeaninternal.server.core.timezone.DataTimeZone; -import io.ebeaninternal.server.util.Checksum; +import io.ebeaninternal.server.util.Md5; import io.ebeaninternal.server.util.Str; import io.ebeaninternal.server.query.CQueryPlanStats.Snapshot; import io.ebeaninternal.server.type.DataBind; @@ -56,13 +56,12 @@ public class CQueryPlan implements SpiQueryPlan { private final SpiEbeanServer server; private final ProfileLocation profileLocation; private final String location; - private final long locationHash; private final String label; private final String name; private final CQueryPlanKey planKey; private final boolean rawSql; private final String sql; - private final long sqlHash; + private final String hash; private final String logWhereSql; private final SqlTree sqlTree; @@ -93,7 +92,6 @@ public class CQueryPlan implements SpiQueryPlan { SpiQuery query = request.getQuery(); this.profileLocation = query.getProfileLocation(); this.location = (profileLocation == null) ? null : profileLocation.location(); - this.locationHash = (profileLocation == null) ? 0 : profileLocation.hash(); this.label = query.getPlanLabel(); this.name = deriveName(label, query.getType(), request.getBeanDescriptor().getSimpleName()); this.asOfTableCount = query.getAsOfTableCount(); @@ -105,7 +103,7 @@ public class CQueryPlan implements SpiQueryPlan { this.stats = new CQueryPlanStats(this); this.dependentTables = sqlTree.dependentTables(); this.bindCapture = initBindCapture(query); - this.sqlHash = Checksum.checksum(sql); + this.hash = Md5.hash(sql, name, location); } /** @@ -118,7 +116,6 @@ public class CQueryPlan implements SpiQueryPlan { SpiQuery query = request.getQuery(); this.profileLocation = query.getProfileLocation(); this.location = (profileLocation == null) ? null : profileLocation.location(); - this.locationHash = (profileLocation == null) ? 0 : profileLocation.hash(); this.label = query.getPlanLabel(); this.name = deriveName(label, query.getType(), request.getBeanDescriptor().getSimpleName()); this.planKey = buildPlanKey(sql, logWhereSql); @@ -131,7 +128,7 @@ public class CQueryPlan implements SpiQueryPlan { this.stats = new CQueryPlanStats(this); this.dependentTables = sqlTree.dependentTables(); this.bindCapture = initBindCaptureRaw(sql, query); - this.sqlHash = Checksum.checksum(sql); + this.hash = Md5.hash(sql, name, location); } private String deriveName(String label, SpiQuery.Type type, String simpleName) { @@ -177,8 +174,8 @@ public class CQueryPlan implements SpiQueryPlan { } @Override - public long getSqlHash() { - return sqlHash; + public String getHash() { + return hash; } @Override @@ -203,10 +200,6 @@ public class CQueryPlan implements SpiQueryPlan { return location; } - public long getLocationHash() { - return locationHash; - } - @Override public void queryPlanInit(long thresholdMicros) { bindCapture.queryPlanInit(thresholdMicros); @@ -214,7 +207,7 @@ public class CQueryPlan implements SpiQueryPlan { @Override public DQueryPlanOutput createMeta(String bind, String planString) { - return new DQueryPlanOutput(getBeanType(), name, sqlHash, sql, profileLocation, bind, planString); + return new DQueryPlanOutput(getBeanType(), name, hash, sql, profileLocation, bind, planString); } public DataReader createDataReader(ResultSet rset) { @@ -261,7 +254,7 @@ public class CQueryPlan implements SpiQueryPlan { private String calcAuditQueryKey() { // rawSql needs to include the MD5 hash of the sql - return rawSql ? planKey.getPartialKey() + "_" + sqlHash : planKey.getPartialKey(); + return rawSql ? planKey.getPartialKey() + "_" + hash : planKey.getPartialKey(); } SqlTree getSqlTree() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java index ab7dc0b63..ffc749eb9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java @@ -106,11 +106,6 @@ public final class CQueryPlanStats { return queryPlan.getLocation(); } - @Override - public long locationHash() { - return queryPlan.getLocationHash(); - } - @Override public long count() { return metrics.count(); @@ -132,8 +127,8 @@ public final class CQueryPlanStats { } @Override - public long sqlHash() { - return queryPlan.getSqlHash(); + public String hash() { + return queryPlan.getHash(); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java index 3d879362b..1c1a41d07 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java @@ -16,14 +16,14 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { private final String sql; private final String bind; private final String plan; - private final long sqlHash; + private final String hash; private long queryTimeMicros; private long captureCount; - DQueryPlanOutput(Class beanType, String label, long sqlHash, String sql, ProfileLocation profileLocation, String bind, String plan) { + DQueryPlanOutput(Class beanType, String label, String hash, String sql, ProfileLocation profileLocation, String bind, String plan) { this.beanType = beanType; this.label = label; - this.sqlHash = sqlHash; + this.hash = hash; this.sql = sql; this.profileLocation = profileLocation; this.bind = bind; @@ -31,8 +31,8 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { } @Override - public long sqlHash() { - return sqlHash; + public String hash() { + return hash; } /** @@ -99,7 +99,7 @@ class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { @Override public String toString() { - return " BeanType:" + ((beanType == null) ? "" : beanType.getSimpleName()) + " planHash:" + sqlHash + " label:" + label + " queryTimeMicros:" + queryTimeMicros + " captureCount:" + captureCount + "\n SQL:" + sql + "\nBIND:" + bind + "\nPLAN:" + plan; + return " BeanType:" + ((beanType == null) ? "" : beanType.getSimpleName()) + " planHash:" + hash + " label:" + label + " queryTimeMicros:" + queryTimeMicros + " captureCount:" + captureCount + "\n SQL:" + sql + "\nBIND:" + bind + "\nPLAN:" + plan; } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java new file mode 100644 index 000000000..45df901f0 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/Md5.java @@ -0,0 +1,36 @@ +package io.ebeaninternal.server.util; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; + +public final class Md5 { + + /** + * Return the MD5 hash of the underlying sql. + */ + public static String hash(String... values) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + for (String val : values) { + if (val != null) { + md.update(val.getBytes(StandardCharsets.UTF_8)); + } + } + return digestToHex(md.digest()); + } catch (Exception e) { + throw new RuntimeException("MD5 hashing failed", e); + } + } + + /** + * Convert the digest into a hex value. + */ + private static String digestToHex(byte[] digest) { + StringBuilder sb = new StringBuilder(32); + for (byte aDigest : digest) { + sb.append(Integer.toString((aDigest & 0xff) + 0x100, 16).substring(1)); + } + return sb.toString(); + } + +} diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java index 6dfdad9f6..84a53442a 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java @@ -14,7 +14,7 @@ public class BasicProfileLocationTest { assertThat(loc.obtain()).isTrue(); assertThat(loc.fullLocation()).endsWith(":12)"); - assertThat(loc.location()).isEqualTo("NativeMethodAccessorImpl.invoke0(Native Method:12)"); + assertThat(loc.location()).isEqualTo("java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0"); assertThat(loc.label()).isEqualTo("NativeMethodAccessorImpl.invoke0"); } @@ -24,7 +24,7 @@ public class BasicProfileLocationTest { BasicProfileLocation loc = new BasicProfileLocation("com.foo.Bar.all"); assertThat(loc.obtain()).isFalse(); assertThat(loc.fullLocation()).isEqualTo("com.foo.Bar.all"); - assertThat(loc.location()).isEqualTo("Bar.all"); + assertThat(loc.location()).isEqualTo("com.foo.Bar.all"); assertThat(loc.label()).isEqualTo("Bar.all"); } @@ -34,7 +34,7 @@ public class BasicProfileLocationTest { BasicProfileLocation loc = new BasicProfileLocation("foo.Bar.all"); assertThat(loc.obtain()).isFalse(); assertThat(loc.fullLocation()).isEqualTo("foo.Bar.all"); - assertThat(loc.location()).isEqualTo("Bar.all"); + assertThat(loc.location()).isEqualTo("foo.Bar.all"); assertThat(loc.label()).isEqualTo("Bar.all"); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/UtilLocationTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/UtilLocationTest.java index 5fcbe90a4..0b26078ff 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/UtilLocationTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/UtilLocationTest.java @@ -9,13 +9,12 @@ public class UtilLocationTest { @Test public void label() { assertThat(UtilLocation.label("foo")).isEqualTo("foo"); - assertThat(UtilLocation.label("ProfileLocationTest$Other.(ProfileLocationTest.java:47)")).isEqualTo("ProfileLocationTest$Other.init"); + assertThat(UtilLocation.label("ProfileLocationTest$Other.")).isEqualTo("ProfileLocationTest$Other.init"); } @Test - public void hash() { - assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:12)")).isEqualTo(396279222L); - assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:13)")).isEqualTo(396279222L); - assertThat(UtilLocation.hash("org.foo.MyFoo.doIt(MyFoo.java:945)")).isEqualTo(396279222L); + public void loc() { + assertThat(UtilLocation.loc("org.foo.MyFoo.doIt(MyFoo.java:12)")).isEqualTo("org.foo.MyFoo.doIt"); + assertThat(UtilLocation.label("org.foo.MyFoo.doIt")).isEqualTo("MyFoo.doIt"); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/util/Md5Test.java b/ebean-core/src/test/java/io/ebeaninternal/server/util/Md5Test.java new file mode 100644 index 000000000..9f0106cae --- /dev/null +++ b/ebean-core/src/test/java/io/ebeaninternal/server/util/Md5Test.java @@ -0,0 +1,53 @@ +package io.ebeaninternal.server.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +public class Md5Test { + + @Test + public void hash() throws Exception { + String content = "some random content we wish to hash"; + String hash1 = Md5.hash(content); + String hash2 = Md5.hash(content); + assertEquals(hash1, hash2); + assertEquals(hash1, "62c20bf679ff56cb746452ab5c88e3ed"); + } + + @Test + public void hashDifferent() throws Exception { + String hash1 = Md5.hash("one"); + String hash2 = Md5.hash("two"); + String hash3 = Md5.hash("onetwo"); + + assertNotEquals(hash1, hash2); + assertNotEquals(hash2, hash3); + assertEquals(hash1, "f97c5d29941bfb1b2fdab0874906ab82"); + } + + @Test + public void hashMulti() { + String hash1 = Md5.hash("one", "two"); + String hash2 = Md5.hash("onetwo"); + + assertEquals(hash1, hash2); + assertEquals(hash1, "5b9164ad6f496d9dee12ec7634ce253f"); + } + + @Test + public void hashMulti_when_null() { + String hash1 = Md5.hash("one", null); + String hash2 = Md5.hash("one"); + + assertEquals(hash1, hash2); + assertEquals(hash1, "f97c5d29941bfb1b2fdab0874906ab82"); + } + + @Test + public void when_null() { + String hash1 = Md5.hash(null, null); + assertEquals(hash1, "d41d8cd98f00b204e9800998ecf8427e"); + } +} diff --git a/ebean-core/src/test/java/org/tests/profile/ProfileLocationTest.java b/ebean-core/src/test/java/org/tests/profile/ProfileLocationTest.java index d452b7463..c7b0edfe9 100644 --- a/ebean-core/src/test/java/org/tests/profile/ProfileLocationTest.java +++ b/ebean-core/src/test/java/org/tests/profile/ProfileLocationTest.java @@ -20,15 +20,13 @@ public class ProfileLocationTest { public void test_obtain() { assertThat(doIt()).isTrue(); assertThat(loc.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:16)"); - assertThat(loc.location()).isEqualTo("ProfileLocationTest.doIt(ProfileLocationTest.java:16)"); + assertThat(loc.location()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt"); assertThat(loc.label()).isEqualTo("ProfileLocationTest.doIt"); - assertThat(loc.hash()).isEqualTo(1867926812L); // same hash even when the line number has changed assertThat(locB.fullLocation()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt(ProfileLocationTest.java:15)"); - assertThat(locB.location()).isEqualTo("ProfileLocationTest.doIt(ProfileLocationTest.java:15)"); + assertThat(locB.location()).isEqualTo("org.tests.profile.ProfileLocationTest.doIt"); assertThat(locB.label()).isEqualTo("ProfileLocationTest.doIt"); - assertThat(locB.hash()).isEqualTo(1867926812L); } @Test @@ -43,7 +41,7 @@ public class ProfileLocationTest { other.hashCode(); assertThat(loc2.label()).isEqualTo("ProfileLocationTest$Other.init"); - assertThat(loc2.location()).isEqualTo("ProfileLocationTest$Other.(ProfileLocationTest.java:52)"); + assertThat(loc2.location()).isEqualTo("org.tests.profile.ProfileLocationTest$Other."); } static class Other { diff --git a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java index 6dfd99422..d36e36b51 100644 --- a/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java +++ b/ebean-core/src/test/java/org/tests/query/finder/TestCustomerFinder.java @@ -242,10 +242,9 @@ public class TestCustomerFinder extends BaseTestCase { assertThat(metricsJson).contains("\"name\":\"txn.main\""); assertThat(metricsJson).contains("\"name\":\"orm.Customer.findList\""); - assertThat(metricsJson).contains("\"locHash\":3254522637"); - assertThat(metricsJson).contains("\"loc\":\"CustomerFinder.byNameStatus(CustomerFinder.java:43)\""); + assertThat(metricsJson).contains("\"loc\":\"org.tests.model.basic.finder.CustomerFinder.byNameStatus\""); if (isH2() || isPostgres()) { - assertThat(metricsJson).contains("\"sqlHash\":3634991469"); + assertThat(metricsJson).contains("\"hash\":\"de3affa5b4bff07e19c1c012590dcde6\""); assertThat(metricsJson).contains("\"sql\":\"select t0.id, t0.status,"); } } From 43213ead058f8a648f6ce1a7d2edf54c28a54d47 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 9 Aug 2021 15:10:59 +1200 Subject: [PATCH 056/120] #2291 - ENH: Explicit option for fast-failing or not fast-failing (skipDataSourceCheck config option) --- .../java/io/ebean/config/DatabaseConfig.java | 17 +++++++++++++++++ .../server/core/DefaultContainer.java | 3 +++ .../io/ebean/config/DatabaseConfigTest.java | 5 +++++ 3 files changed, 25 insertions(+) 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 d1f0346b5..873304c3a 100644 --- a/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java +++ b/ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java @@ -319,6 +319,8 @@ public class DatabaseConfig { */ private ExternalTransactionManager externalTransactionManager; + private boolean skipDataSourceCheck; + /** * The data source (if programmatically provided). */ @@ -1651,6 +1653,20 @@ public class DatabaseConfig { this.autoTuneConfig = autoTuneConfig; } + /** + * Return true if the startup DataSource check should be skipped. + */ + public boolean skipDataSourceCheck() { + return skipDataSourceCheck; + } + + /** + * Set to true to skip the startup DataSource check. + */ + public void setSkipDataSourceCheck(boolean skipDataSourceCheck) { + this.skipDataSourceCheck = skipDataSourceCheck; + } + /** * Return the DataSource. */ @@ -2932,6 +2948,7 @@ public class DatabaseConfig { jsonDate = p.getEnum(JsonConfig.Date.class, "jsonDate", jsonDate); jsonMutationDetection = p.getEnum(MutationDetection.class, "jsonMutationDetection", jsonMutationDetection); + skipDataSourceCheck = p.getBoolean("skipDataSourceCheck", skipDataSourceCheck); runMigration = p.getBoolean("migration.run", runMigration); ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate); ddlRun = p.getBoolean("ddl.run", ddlRun); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java index cdefcc294..2c8bbfecc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java @@ -255,6 +255,9 @@ public class DefaultContainer implements SpiContainer { } throw new RuntimeException("DataSource not set?"); } + if (config.skipDataSourceCheck()) { + return true; + } try (Connection connection = config.getDataSource().getConnection()) { if (connection.getAutoCommit()) { logger.warn("DataSource [{}] has autoCommit defaulting to true!", config.getName()); diff --git a/ebean-core/src/test/java/io/ebean/config/DatabaseConfigTest.java b/ebean-core/src/test/java/io/ebean/config/DatabaseConfigTest.java index dd132a8e3..368bc9a8f 100644 --- a/ebean-core/src/test/java/io/ebean/config/DatabaseConfigTest.java +++ b/ebean-core/src/test/java/io/ebean/config/DatabaseConfigTest.java @@ -76,6 +76,7 @@ public class DatabaseConfigTest { props.setProperty("loadModuleInfo", "true"); props.setProperty("forUpdateNoKey", "true"); props.setProperty("defaultServer", "false"); + props.setProperty("skipDataSourceCheck", "true"); props.setProperty("queryPlan.enable", "true"); props.setProperty("queryPlan.thresholdMicros", "10000"); @@ -92,6 +93,7 @@ public class DatabaseConfigTest { assertTrue(config.isDbOffline()); assertTrue(config.isAutoReadOnlyDataSource()); assertTrue(config.isAutoLoadModuleInfo()); + assertTrue(config.skipDataSourceCheck()); assertTrue(config.isIdGeneratorAutomatic()); assertFalse(config.getPlatformConfig().isCaseSensitiveCollation()); @@ -155,6 +157,7 @@ public class DatabaseConfigTest { assertTrue(config.isIdGeneratorAutomatic()); assertTrue(config.isDefaultServer()); assertFalse(config.isAutoPersistUpdates()); + assertFalse(config.skipDataSourceCheck()); config.setIdGeneratorAutomatic(false); assertFalse(config.isIdGeneratorAutomatic()); @@ -175,6 +178,8 @@ public class DatabaseConfigTest { assertFalse(config.isAutoLoadModuleInfo()); config.setAutoPersistUpdates(true); assertTrue(config.isAutoPersistUpdates()); + config.setSkipDataSourceCheck(true); + assertTrue(config.skipDataSourceCheck()); } @Test From 8c101fd0a460df5ed5252601483b8f89ac4f783e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 9 Aug 2021 16:48:59 +1200 Subject: [PATCH 057/120] #2268 - Feature request/question: Query execution time for debugging --- .../server/core/AbstractSqlQueryRequest.java | 14 +--- .../server/core/DtoQueryRequest.java | 3 - .../server/core/RelationalQueryRequest.java | 3 - .../io/ebeaninternal/server/query/CQuery.java | 6 +- .../server/query/CQueryEngine.java | 66 ++----------------- .../query/CQueryFetchSingleAttribute.java | 38 ++--------- .../server/query/CQueryRowCount.java | 38 ++--------- .../server/query/CQueryUpdate.java | 32 ++------- 8 files changed, 29 insertions(+), 171 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/AbstractSqlQueryRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/AbstractSqlQueryRequest.java index 67844c631..a88f1bbe9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/AbstractSqlQueryRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/AbstractSqlQueryRequest.java @@ -23,25 +23,16 @@ import javax.persistence.PersistenceException; public abstract class AbstractSqlQueryRequest implements CancelableQuery { protected final SpiSqlBinding query; - protected final SpiEbeanServer server; - protected SpiTransaction transaction; - private boolean createdTransaction; - protected String sql; - protected ResultSet resultSet; - protected String bindLog = ""; - protected PreparedStatement pstmt; - protected long startNano; - private final ReentrantLock lock = new ReentrantLock(); - + /** * Create the BeanFindRequest. */ @@ -161,7 +152,8 @@ public abstract class AbstractSqlQueryRequest implements CancelableQuery { this.bindLog = binder.bind(bindParams, pstmt, conn); } if (isLogSql()) { - transaction.logSql(Str.add(TrimLogSql.trim(sql), "; --bind(", bindLog, ")")); + long micros = (System.nanoTime() - startNano) / 1000L; + transaction.logSql(Str.add(TrimLogSql.trim(sql), "; --bind(", bindLog, ") --micros(", micros + ")")); } } finally { lock.unlock(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DtoQueryRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DtoQueryRequest.java index 2b1a55f6e..c023f2d0d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DtoQueryRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DtoQueryRequest.java @@ -28,11 +28,8 @@ public final class DtoQueryRequest extends AbstractSqlQueryRequest { private static final String ENC_PREFIX_UPPER = EncryptAlias.PREFIX.toUpperCase(); private final SpiDtoQuery query; - private final DtoQueryEngine queryEngine; - private DtoQueryPlan plan; - private DataReader dataReader; DtoQueryRequest(SpiEbeanServer server, DtoQueryEngine engine, SpiDtoQuery query) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/RelationalQueryRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/RelationalQueryRequest.java index a5130ef22..ef3874008 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/RelationalQueryRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/RelationalQueryRequest.java @@ -18,11 +18,8 @@ import java.util.function.Predicate; public final class RelationalQueryRequest extends AbstractSqlQueryRequest { private final RelationalQueryEngine queryEngine; - private String[] propertyNames; - private int estimateCapacity; - private int rows; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java index e7674a31c..7fc636af0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java @@ -541,9 +541,13 @@ public class CQuery implements DbReadContext, CancelableQuery, SpiProfileTran updateStatistics(); } + long micros() { + return (System.nanoTime() - startNano) / 1000L; + } + private void updateStatistics() { try { - executionTimeMicros = (System.nanoTime() - startNano) / 1000L; + executionTimeMicros = micros(); if (autoTuneProfiling) { profilingListener.collectQueryInfo(objectGraphNode, loadedBeanCount, executionTimeMicros); } 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 a1a211c0a..03074b43f 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 @@ -79,15 +79,10 @@ public class CQueryEngine { private int executeUpdate(OrmQueryRequest request, CQueryUpdate query) { try { int rows = query.execute(); - if (request.isLogSql()) { - String logSql = query.getGeneratedSql(); - logSql = Str.add(logSql, "; --bind(", query.getBindLog(), ") rows:", String.valueOf(rows)); - request.logSql(logSql); + request.logSql(Str.add(query.getGeneratedSql(), "; --bind(", query.getBindLog(), ") --micros(", query.micros() + ") --rows(", rows + ")")); } - return rows; - } catch (SQLException e) { throw translate(request, query.getBindLog(), query.getGeneratedSql(), e); } @@ -97,7 +92,6 @@ public class CQueryEngine { * Build and execute the findSingleAttributeList query. */ public List findSingleAttributeList(OrmQueryRequest request) { - CQueryFetchSingleAttribute rcQuery = queryBuilder.buildFetchAttributeQuery(request); request.setCancelableQuery(rcQuery); return findAttributeList(request, rcQuery); @@ -108,14 +102,13 @@ public class CQueryEngine { try { List list = (List) rcQuery.findList(); if (request.isLogSql()) { - logGeneratedSql(request, rcQuery.getGeneratedSql(), rcQuery.getBindLog()); + logGeneratedSql(request, rcQuery.getGeneratedSql(), rcQuery.getBindLog(), rcQuery.micros()); } if (request.isLogSummary()) { request.getTransaction().logSummary(rcQuery.getSummary()); } if (request.isQueryCachePut()) { request.addDependentTables(rcQuery.getDependentTables()); - list = Collections.unmodifiableList(list); request.putToQueryCache(list); if (Boolean.FALSE.equals(request.getQuery().isReadOnly())) { @@ -123,7 +116,6 @@ public class CQueryEngine { } } return list; - } catch (SQLException e) { throw translate(request, rcQuery.getBindLog(), rcQuery.getGeneratedSql(), e); } @@ -139,10 +131,8 @@ public class CQueryEngine { String msg = "ERROR executing query, bindLog[" + bindLog + "] error[" + StringHelper.removeNewLines(e.getMessage()) + "]"; t.logSummary(msg); } - // ensure 'rollback' is logged if queryOnly transaction t.getConnection(); - // build a decent error message for the exception String m = "Query threw SQLException:" + e.getMessage() + " Bind values:[" + bindLog + "] Query was:" + sql; return dbPlatform.translate(m, e); @@ -152,46 +142,37 @@ public class CQueryEngine { * Build and execute the find Id's query. */ public List findIds(OrmQueryRequest request) { - CQueryFetchSingleAttribute rcQuery = queryBuilder.buildFetchIdsQuery(request); request.setCancelableQuery(rcQuery); return findAttributeList(request, rcQuery); } - private void logGeneratedSql(OrmQueryRequest request, String sql, String bindLog) { - request.logSql(Str.add(sql, "; --bind(", bindLog, ")")); + private void logGeneratedSql(OrmQueryRequest request, String sql, String bindLog, long micros) { + request.logSql(Str.add(sql, "; --bind(", bindLog, ") --micros(", micros + ")")); } /** * Build and execute the row count query. */ public int findCount(OrmQueryRequest request) { - CQueryRowCount rcQuery = queryBuilder.buildRowCountQuery(request); request.setCancelableQuery(rcQuery); try { - int count = rcQuery.findCount(); - if (request.isLogSql()) { - logGeneratedSql(request, rcQuery.getGeneratedSql(), rcQuery.getBindLog()); + logGeneratedSql(request, rcQuery.getGeneratedSql(), rcQuery.getBindLog(), rcQuery.micros()); } - if (request.isLogSummary()) { request.getTransaction().logSummary(rcQuery.getSummary()); } - if (request.getQuery().isFutureFetch()) { request.getTransaction().end(); } - if (request.isQueryCachePut()) { request.addDependentTables(rcQuery.getDependentTables()); request.putToQueryCache(count); } - return count; - } catch (SQLException e) { throw translate(request, rcQuery.getBindLog(), rcQuery.getGeneratedSql(), e); } @@ -254,9 +235,7 @@ public class CQueryEngine { * Execute the find versions query returning version beans. */ public List> findVersions(OrmQueryRequest request) { - SpiQuery query = request.getQuery(); - String sysPeriodLower = getSysPeriodLower(query); if (query.isVersionsBetween() && !historySupport.isStandardsBased()) { query.where().lt(sysPeriodLower, query.getVersionEnd()); @@ -272,26 +251,21 @@ public class CQueryEngine { if (request.isLogSql()) { logSql(cquery); } - List> versions = cquery.readVersions(); // just order in memory rather than use NULLS LAST as that // is not universally supported, not expect huge list here versions.sort(OrderVersionDesc.INSTANCE); deriveVersionDiffs(versions, request); - if (request.isLogSummary()) { logFindManySummary(cquery); } - if (request.isAuditReads()) { cquery.auditFindMany(); } - return versions; } catch (SQLException e) { throw cquery.createPersistenceException(e); - } finally { if (cquery != null) { cquery.close(); @@ -300,9 +274,7 @@ public class CQueryEngine { } private void deriveVersionDiffs(List> versions, OrmQueryRequest request) { - BeanDescriptor descriptor = request.getBeanDescriptor(); - if (!versions.isEmpty()) { Version current = versions.get(0); if (versions.size() > 1) { @@ -367,10 +339,8 @@ public class CQueryEngine { * Find a list/map/set of beans. */ BeanCollection findMany(OrmQueryRequest request) { - CQuery cquery = queryBuilder.buildQuery(request); request.setCancelableQuery(cquery); - try { if (defaultFetchSizeFindList > 0) { request.setDefaultFetchBuffer(defaultFetchSizeFindList); @@ -380,30 +350,24 @@ public class CQueryEngine { logger.trace("Future fetch already cancelled"); return null; } - if (request.isLogSql()) { logSql(cquery); } - BeanCollection beanCollection = cquery.readCollection(); if (request.isLogSummary()) { logFindManySummary(cquery); } - if (request.isAuditReads()) { cquery.auditFindMany(); } - request.executeSecondaryQueries(false); if (request.isQueryCachePut()) { request.addDependentTables(cquery.getDependentTables()); } - return beanCollection; } catch (SQLException e) { throw cquery.createPersistenceException(e); - } finally { if (cquery != null) { cquery.close(); @@ -416,38 +380,27 @@ public class CQueryEngine { */ @SuppressWarnings("unchecked") public T find(OrmQueryRequest request) { - EntityBean bean = null; - CQuery cquery = queryBuilder.buildQuery(request); request.setCancelableQuery(cquery); - try { cquery.prepareBindExecuteQuery(); - if (request.isLogSql()) { logSql(cquery); } - if (cquery.readBean()) { bean = cquery.next(); } - if (request.isLogSummary()) { logFindBeanSummary(cquery); } - if (request.isAuditReads()) { cquery.auditFind(bean); } - request.executeSecondaryQueries(false); - return (T) bean; - } catch (SQLException e) { throw cquery.createPersistenceException(e); - } finally { cquery.close(); } @@ -457,17 +410,13 @@ public class CQueryEngine { * Log the generated SQL to the transaction log. */ private void logSql(CQuery query) { - - String sql = query.getGeneratedSql(); - sql = Str.add(sql, "; --bind(", query.getBindLog(), ")"); - query.getTransaction().logSql(sql); + query.getTransaction().logSql(Str.add(query.getGeneratedSql(), "; --bind(", query.getBindLog(), ") --micros(", query.micros() + ")")); } /** * Log the FindById summary to the transaction log. */ private void logFindBeanSummary(CQuery q) { - SpiQuery query = q.getQueryRequest().getQuery(); String loadMode = query.getLoadMode(); String loadDesc = query.getLoadDescription(); @@ -504,7 +453,6 @@ public class CQueryEngine { msg.append("exeMicros[").append(q.getQueryExecutionTimeMicros()); msg.append("] rows[").append(q.getLoadedRowDetail()); msg.append("] bind[").append(q.getBindLog()).append("]"); - q.getTransaction().logSummary(msg.toString()); } @@ -512,7 +460,6 @@ public class CQueryEngine { * Log the FindMany to the transaction log. */ private void logFindManySummary(CQuery q) { - SpiQuery query = q.getQueryRequest().getQuery(); String loadMode = query.getLoadMode(); String loadDesc = query.getLoadDescription(); @@ -551,7 +498,6 @@ public class CQueryEngine { msg.append("] rows[").append(q.getLoadedRowDetail()); msg.append("] predicates[").append(q.getLogWhereSql()); msg.append("] bind[").append(q.getBindLog()).append("]"); - q.getTransaction().logSummary(msg.toString()); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java index b68813bd4..a89cd28fa 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java @@ -29,45 +29,19 @@ class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent, Cancelab private static final Logger logger = LoggerFactory.getLogger(CQueryFetchSingleAttribute.class); private final CQueryPlan queryPlan; - - /** - * The overall find request wrapper object. - */ private final OrmQueryRequest request; - private final BeanDescriptor desc; - private final SpiQuery query; - - /** - * Where clause predicates. - */ private final CQueryPredicates predicates; - - /** - * The final sql that is generated. - */ private final String sql; - private RsetDataReader dataReader; - - /** - * The statement used to create the resultSet. - */ private PreparedStatement pstmt; - private String bindLog; - private long executionTimeMicros; - private int rowCount; - private final ScalarDataReader reader; - private final boolean containsCounts; - private long profileOffset; - private final ReentrantLock lock = new ReentrantLock(); /** @@ -95,19 +69,20 @@ class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent, Cancelab .append("] type[").append(desc.getName()) .append("] predicates[").append(predicates.getLogWhereSql()) .append("] bind[").append(bindLog).append("]"); - return sb.toString(); } + long micros() { + return executionTimeMicros; + } + /** * Execute the query returning the row count. */ List findList() throws SQLException { - long startNano = System.nanoTime(); try { prepareExecute(); - List result = new ArrayList<>(); while (dataReader.next()) { Object value = reader.read(dataReader); @@ -117,16 +92,13 @@ class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent, Cancelab result.add(value); rowCount++; } - executionTimeMicros = (System.nanoTime() - startNano) / 1000L; request.slowQueryCheck(executionTimeMicros, rowCount); if (queryPlan.executionTime(executionTimeMicros)) { queryPlan.captureBindForQueryPlan(predicates, executionTimeMicros); } getTransaction().profileEvent(this); - return result; - } finally { close(); } @@ -158,14 +130,12 @@ class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent, Cancelab profileOffset = t.profileOffset(); Connection conn = t.getInternalConnection(); pstmt = conn.prepareStatement(sql); - if (query.getBufferFetchSizeHint() > 0) { pstmt.setFetchSize(query.getBufferFetchSizeHint()); } if (query.getTimeout() > 0) { pstmt.setQueryTimeout(query.getTimeout()); } - bindLog = predicates.bind(pstmt, conn); } finally { lock.unlock(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java index 248fa9058..0c1df9483 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java @@ -22,44 +22,17 @@ import java.util.concurrent.locks.ReentrantLock; class CQueryRowCount implements SpiProfileTransactionEvent, CancelableQuery { private final CQueryPlan queryPlan; - - /** - * The overall find request wrapper object. - */ private final OrmQueryRequest request; - private final BeanDescriptor desc; - private final SpiQuery query; - - /** - * Where clause predicates. - */ private final CQueryPredicates predicates; - - /** - * The final sql that is generated. - */ private final String sql; - - /** - * The resultSet that is read and converted to objects. - */ private ResultSet rset; - - /** - * The statement used to create the resultSet. - */ private PreparedStatement pstmt; - private String bindLog; - private long executionTimeMicros; - private int rowCount; - private long profileOffset; - private final ReentrantLock lock = new ReentrantLock(); /** @@ -104,11 +77,14 @@ class CQueryRowCount implements SpiProfileTransactionEvent, CancelableQuery { return sql; } + long micros() { + return executionTimeMicros; + } + /** * Execute the query returning the row count. */ public int findCount() throws SQLException { - long startNano = System.nanoTime(); try { SpiTransaction t = getTransaction(); @@ -118,24 +94,19 @@ class CQueryRowCount implements SpiProfileTransactionEvent, CancelableQuery { try { query.checkCancelled(); pstmt = conn.prepareStatement(sql); - if (query.getTimeout() > 0) { pstmt.setQueryTimeout(query.getTimeout()); } - bindLog = predicates.bind(pstmt, conn); } finally { lock.unlock(); } rset = pstmt.executeQuery(); query.checkCancelled(); - if (!rset.next()) { throw new PersistenceException("Expecting 1 row but got none?"); } - rowCount = rset.getInt(1); - executionTimeMicros = (System.nanoTime() - startNano) / 1000L; request.slowQueryCheck(executionTimeMicros, rowCount); if (queryPlan.executionTime(executionTimeMicros)) { @@ -143,7 +114,6 @@ class CQueryRowCount implements SpiProfileTransactionEvent, CancelableQuery { } t.profileEvent(this); return rowCount; - } finally { close(); } 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 eec5d2e6f..302b1bcf0 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 @@ -19,36 +19,18 @@ import java.util.concurrent.locks.ReentrantLock; class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery { private final CQueryPlan queryPlan; - private final OrmQueryRequest request; - private final BeanDescriptor desc; - private final SpiQuery query; - - /** - * Where clause predicates. - */ private final CQueryPredicates predicates; - - /** - * The final sql that is generated. - */ private final String sql; - - /** - * The statement used to create the resultSet. - */ private PreparedStatement pstmt; - private String bindLog; - private int rowCount; - private long profileOffset; - + private long executionTimeMicros; private final ReentrantLock lock = new ReentrantLock(); - + /** * Create the Sql select based on the request. */ @@ -80,7 +62,6 @@ class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery { * Execute the update or delete statement returning the row count. */ public int execute() throws SQLException { - long startNano = System.nanoTime(); try { SpiTransaction t = getTransaction(); @@ -90,19 +71,16 @@ class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery { try { query.checkCancelled(); pstmt = conn.prepareStatement(sql); - if (query.getTimeout() > 0) { pstmt.setQueryTimeout(query.getTimeout()); } - bindLog = predicates.bind(pstmt, conn); } finally { lock.unlock(); } rowCount = pstmt.executeUpdate(); query.checkCancelled(); - - long executionTimeMicros = (System.nanoTime() - startNano) / 1000L; + executionTimeMicros = (System.nanoTime() - startNano) / 1000L; request.slowQueryCheck(executionTimeMicros, rowCount); if (queryPlan.executionTime(executionTimeMicros)) { queryPlan.captureBindForQueryPlan(predicates, executionTimeMicros); @@ -115,6 +93,10 @@ class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery { } } + long micros() { + return executionTimeMicros; + } + private SpiTransaction getTransaction() { return request.getTransaction(); } From 7ed2de917828ea69a6ab5136cc86a80c383f2e5b Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 9 Aug 2021 16:57:43 +1200 Subject: [PATCH 058/120] Update github issue template --- .github/ISSUE_TEMPLATE.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 8575f4580..357f8aefb 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,9 +1,3 @@ - -GITHUB ISSUES ARE STRICTLY CONTROLLED FOR THIS PROJECT. - -Refer to http://ebean-orm.github.io/support for the policies controlling the use of github issues. -Please post issues to the Ebean group https://groups.google.com/forum/#!forum/ebean first. - ## Expected behavior ## Actual behavior From 181dc73d39f5285fb7d02ffbc923d01ff794c4d9 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Mon, 9 Aug 2021 09:19:53 +0200 Subject: [PATCH 059/120] Use MD5 for QueryBindHash --- .../java/io/ebeaninternal/api/BindHash.java | 37 +++++ .../java/io/ebeaninternal/api/BindParams.java | 11 +- .../java/io/ebeaninternal/api/HashQuery.java | 8 +- .../io/ebeaninternal/api/SpiExpression.java | 2 +- .../java/io/ebeaninternal/api/SpiQuery.java | 2 +- .../expression/AbstractTextExpression.java | 7 +- .../expression/AllEqualsExpression.java | 8 +- .../expression/ArrayContainsExpression.java | 10 +- .../expression/ArrayIsEmptyExpression.java | 5 +- .../server/expression/BetweenExpression.java | 7 +- .../expression/BetweenPropertyExpression.java | 5 +- .../server/expression/BitwiseExpression.java | 5 +- .../CaseInsensitiveEqualExpression.java | 5 +- .../expression/DefaultExampleExpression.java | 8 +- .../expression/DefaultExpressionList.java | 8 +- .../expression/ExistsQueryExpression.java | 5 +- .../server/expression/IdExpression.java | 5 +- .../server/expression/IdInExpression.java | 8 +- .../server/expression/InExpression.java | 8 +- .../server/expression/InPairsExpression.java | 8 +- .../server/expression/InQueryExpression.java | 5 +- .../server/expression/InRangeExpression.java | 7 +- .../server/expression/IsEmptyExpression.java | 5 +- .../server/expression/JsonPathExpression.java | 7 +- .../server/expression/JunctionExpression.java | 6 +- .../server/expression/LikeExpression.java | 5 +- .../server/expression/LogicExpression.java | 7 +- .../expression/NativeILikeExpression.java | 5 +- .../NestedPathWrapperExpression.java | 5 +- .../server/expression/NoopExpression.java | 4 +- .../server/expression/NotExpression.java | 5 +- .../server/expression/NullExpression.java | 5 +- .../server/expression/RawExpression.java | 8 +- .../server/expression/SimpleExpression.java | 5 +- .../server/querydefn/DefaultOrmQuery.java | 26 ++-- .../server/querydefn/HashCodeBindHash.java | 56 +++++++ .../server/querydefn/MdBindHash.java | 138 ++++++++++++++++++ .../server/expression/RawExpressionTest.java | 12 +- .../server/querydefn/DefaultOrmQueryTest.java | 14 +- .../java/org/tests/cache/TestQueryCache.java | 86 +++++++---- 40 files changed, 436 insertions(+), 137 deletions(-) create mode 100644 ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/querydefn/MdBindHash.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java new file mode 100644 index 000000000..d70c5f09d --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java @@ -0,0 +1,37 @@ +package io.ebeaninternal.api; + +/** + * BindHash implementation. + * + * @author Roland Praml, FOCONIS AG + * + */ +public interface BindHash { + + /** + * Update with boolean value. + */ + BindHash update(boolean boolValue); + + /** + * Update with int value. + */ + BindHash update(int intValue); + + /** + * Update with long value. + */ + BindHash update(long longValue); + + /** + * Update with object value. + */ + BindHash update(Object value); + + /** + * finishes the hash. May be used to compute internal state. After finish, no + * update method must be called + */ + void finish(); + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java index afb1e44b8..2817c4ba1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java @@ -54,12 +54,11 @@ public class BindParams implements Serializable { positionedParameters.clear(); } - public int queryBindHash() { - int hc = namedParameters.hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(positionedParameters.size()); for (Param positionedParameter : positionedParameters) { - hc = hc * 92821 + positionedParameter.hashCode(); + positionedParameter.queryBindHash(hash); } - return hc; } /** @@ -422,6 +421,10 @@ public class BindParams implements Serializable { return hc; } + void queryBindHash(BindHash hash) { + hash.update(isInParam).update(isOutParam).update(type).update(inValue); + } + @Override public boolean equals(Object o) { return o != null && (o == this || (o instanceof Param) && hashCode() == o.hashCode()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/HashQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/HashQuery.java index c14cb88d7..87241aedc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/HashQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/HashQuery.java @@ -7,12 +7,12 @@ public class HashQuery { private final CQueryPlanKey planHash; - private final int bindHash; + private final BindHash bindHash; /** * Create the HashQuery. */ - public HashQuery(CQueryPlanKey planHash, int bindHash) { + public HashQuery(CQueryPlanKey planHash, BindHash bindHash) { this.planHash = planHash; this.bindHash = bindHash; } @@ -25,7 +25,7 @@ public class HashQuery { @Override public int hashCode() { int hc = 92821 * planHash.hashCode(); - hc = 92821 * hc + bindHash; + hc = 92821 * hc + bindHash.hashCode(); return hc; } @@ -39,6 +39,6 @@ public class HashQuery { } HashQuery e = (HashQuery) obj; - return e.bindHash == bindHash && e.planHash.equals(planHash); + return e.bindHash.equals(bindHash) && e.planHash.equals(planHash); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java index 007e9f29f..32c3a3518 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java @@ -56,7 +56,7 @@ public interface SpiExpression extends Expression { /** * Return the hash value for the values that will be bound. */ - int queryBindHash(); + void queryBindHash(BindHash hash); /** * Return true if the expression is the same with respect to bind values. diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java index 12942e7d6..d8bae7503 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -635,7 +635,7 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod * query). *

*/ - int queryBindHash(); + void queryBindHash(BindHash hash); /** * Identifies queries that are exactly the same including bind variables. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java index d30649149..d377e48dd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -37,9 +38,9 @@ public abstract class AbstractTextExpression extends AbstractExpression { } @Override - public int queryBindHash() { - return 0; - } + public void queryBindHash(BindHash hash) { + // do nothing, only execute against document store + }; @Override public boolean isSameByBind(SpiExpression other) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java index 5a931ec5a..df9e6095b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -122,14 +123,13 @@ class AllEqualsExpression extends NonPrepareExpression { } @Override - public int queryBindHash() { + public void queryBindHash(BindHash hash) { - int hc = 92821; + hash.update(propMap.size()); for (Object value : propMap.values()) { - hc = hc * 92821 + (value == null ? 0 : value.hashCode()); + hash.update(value); } - return hc; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java index 8c12bec60..ac6d27d0e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -49,12 +50,11 @@ public class ArrayContainsExpression extends AbstractExpression { } @Override - public int queryBindHash() { - int hc = values[0].hashCode(); - for (int i = 1; i < values.length; i++) { - hc = hc * 92821 + values[i].hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(values.length); + for (int i = 0; i < values.length; i++) { + hash.update(values[i]); } - return hc; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java index 815223dfe..0249acabb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -33,8 +34,8 @@ public class ArrayIsEmptyExpression extends AbstractExpression { } @Override - public int queryBindHash() { - return empty ? 0 : 92821; + public void queryBindHash(BindHash hash) { + hash.update(empty); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java index bfdfa1d52..37a3aab8f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -49,10 +50,8 @@ class BetweenExpression extends AbstractExpression { } @Override - public int queryBindHash() { - int hc = low().hashCode(); - hc = hc * 92821 + high().hashCode(); - return hc; + public void queryBindHash(BindHash hash) { + hash.update(low()).update(high()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java index a50ec888f..440dd5f1f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.util.SplitName; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -95,8 +96,8 @@ class BetweenPropertyExpression extends NonPrepareExpression { } @Override - public int queryBindHash() { - return val().hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(val()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java index 073ee51df..db1fa686d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -39,8 +40,8 @@ class BitwiseExpression extends AbstractExpression { } @Override - public int queryBindHash() { - return Long.hashCode(flags); + public void queryBindHash(BindHash hash) { + hash.update(flags).update(match); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java index 52e39fbfa..485d1b04f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.server.el.ElPropertyValue; @@ -69,8 +70,8 @@ class CaseInsensitiveEqualExpression extends AbstractValueExpression { } @Override - public int queryBindHash() { - return val().hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(val()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java index aade99f5a..9149923e0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java @@ -5,6 +5,7 @@ import io.ebean.LikeType; import io.ebean.bean.EntityBean; import io.ebean.event.BeanQueryRequest; import io.ebean.util.SplitName; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -241,12 +242,11 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio * Return a hash for the actual bind values used. */ @Override - public int queryBindHash() { - int hc = DefaultExampleExpression.class.getName().hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(list.size()); for (SpiExpression aList : list) { - hc = hc * 92821 + aList.queryBindHash(); + aList.queryBindHash(hash); } - return hc; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index ab80ae9e5..b5f9c6ec1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -26,6 +26,7 @@ import io.ebean.search.MultiMatch; import io.ebean.search.TextCommonTerms; import io.ebean.search.TextQueryString; import io.ebean.search.TextSimple; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -678,12 +679,11 @@ public class DefaultExpressionList implements SpiExpressionList { * Calculate a hash based on the expressions. */ @Override - public int queryBindHash() { - int hash = DefaultExpressionList.class.getName().hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(list.size()); for (SpiExpression aList : list) { - hash = hash * 92821 + aList.queryBindHash(); + aList.queryBindHash(hash); } - return hash; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java index 32ae2bccc..b3fcf8ce0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiEbeanServer; @@ -91,8 +92,8 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress } @Override - public int queryBindHash() { - return subQuery.queryBindHash(); + public void queryBindHash(BindHash hash) { + subQuery.queryBindHash(hash); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java index b5280b868..904fbe9be 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -77,8 +78,8 @@ class IdExpression extends NonPrepareExpression implements SpiExpression { } @Override - public int queryBindHash() { - return value.hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(value); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java index 4c08b24d2..390d0bebb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -133,8 +134,11 @@ public class IdInExpression extends NonPrepareExpression { } @Override - public int queryBindHash() { - return idCollection.hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(idCollection.size()); + for (Object elem : idCollection) { + hash.update(elem); + } } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java index 7009a8b44..a5719f71a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java @@ -2,6 +2,7 @@ package io.ebeaninternal.server.expression; import io.ebean.bean.EntityBean; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -176,12 +177,11 @@ class InExpression extends AbstractExpression { } @Override - public int queryBindHash() { - int hc = 92821; + public void queryBindHash(BindHash hash) { + hash.update(bindValues.size()); for (Object bindValue : bindValues) { - hc = 92821 * hc + bindValue.hashCode(); + hash.update(bindValue); } - return hc; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java index 96cc7c182..a7079ae55 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java @@ -3,6 +3,7 @@ package io.ebeaninternal.server.expression; import io.ebean.Pairs; import io.ebean.Pairs.Entry; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -124,12 +125,11 @@ class InPairsExpression extends AbstractExpression { } @Override - public int queryBindHash() { - int hc = 92821; + public void queryBindHash(BindHash hash) { + hash.update(entries.size()); for (Pairs.Entry entry : entries) { - hc = 92821 * hc + entry.hashCode(); + hash.update(entry.getA()).update(entry.getB()); } - return hc; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java index 83507af4b..619f7b715 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiEbeanServer; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -72,8 +73,8 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor } @Override - public int queryBindHash() { - return subQuery.queryBindHash(); + public void queryBindHash(BindHash hash) { + subQuery.queryBindHash(hash); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java index e1d170b43..abe0b7338 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -47,10 +48,8 @@ class InRangeExpression extends AbstractExpression { } @Override - public int queryBindHash() { - int hc = low().hashCode(); - hc = hc * 92821 + high().hashCode(); - return hc; + public void queryBindHash(BindHash hash) { + hash.update(low()).update(high()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java index d3a3a1da6..bb65962b3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -103,8 +104,8 @@ class IsEmptyExpression extends AbstractExpression { } @Override - public int queryBindHash() { - return 1; + public void queryBindHash(BindHash hash) { + // no bind values } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java index f60b125cb..18e0aa924 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -83,10 +84,8 @@ class JsonPathExpression extends AbstractExpression { } @Override - public int queryBindHash() { - int hc = (value == null) ? 0 : value.hashCode(); - hc = (upperValue == null) ? hc : hc * 92821 + upperValue.hashCode(); - return hc; + public void queryBindHash(BindHash hash) { + hash.update(value).update(upperValue); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 0aae30886..51eba8f39 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -25,6 +25,7 @@ import io.ebean.search.MultiMatch; import io.ebean.search.TextCommonTerms; import io.ebean.search.TextQueryString; import io.ebean.search.TextSimple; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -225,13 +226,12 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression } @Override - public int queryBindHash() { + public void queryBindHash(BindHash hash) { int hc = JunctionExpression.class.getName().hashCode(); List list = exprList.internalList(); for (SpiExpression aList : list) { - hc = hc * 92821 + aList.queryBindHash(); + aList.queryBindHash(hash); } - return hc; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java index 6886203c4..587e6064c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.LikeType; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.server.el.ElPropertyValue; @@ -70,8 +71,8 @@ class LikeExpression extends AbstractValueExpression { } @Override - public int queryBindHash() { - return strValue().hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(strValue()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java index 482aac6e8..cbd487b3e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java @@ -3,6 +3,7 @@ package io.ebeaninternal.server.expression; import io.ebean.Expression; import io.ebean.Junction; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -168,10 +169,8 @@ abstract class LogicExpression implements SpiExpression { } @Override - public int queryBindHash() { - int hc = expOne.queryBindHash(); - hc = hc * 92821 + expTwo.queryBindHash(); - return hc; + public void queryBindHash(BindHash hash) { + hash.update(expOne).update(expTwo); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java index c3376f656..8c51d2f5d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.LikeType; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.server.el.ElPropertyValue; @@ -54,8 +55,8 @@ class NativeILikeExpression extends AbstractExpression { } @Override - public int queryBindHash() { - return val.hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(val); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java index 77f46828b..f3ed1badd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -79,8 +80,8 @@ class NestedPathWrapperExpression implements SpiExpression { } @Override - public int queryBindHash() { - return delegate.queryBindHash(); + public void queryBindHash(BindHash hash) { + delegate.queryBindHash(hash); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java index 28c9e3c78..92180cea1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -74,9 +75,8 @@ class NoopExpression implements SpiExpression { } @Override - public int queryBindHash() { + public void queryBindHash(BindHash hash) { // no bind values - return 0; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java index 60ade47b0..e9df6d856 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java @@ -2,6 +2,7 @@ package io.ebeaninternal.server.expression; import io.ebean.Expression; import io.ebean.event.BeanQueryRequest; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -99,8 +100,8 @@ final class NotExpression implements SpiExpression { } @Override - public int queryBindHash() { - return exp.queryBindHash(); + public void queryBindHash(BindHash hash) { + exp.queryBindHash(hash); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java index 90894dbde..daded43cb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java @@ -1,6 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.util.SplitName; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -94,7 +95,7 @@ class NullExpression extends AbstractExpression { } @Override - public int queryBindHash() { - return (notNull ? 1 : 0); + public void queryBindHash(BindHash hash) { + hash.update(notNull); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java index 295ddc75b..721d69b25 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java @@ -1,5 +1,6 @@ package io.ebeaninternal.server.expression; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -73,12 +74,11 @@ class RawExpression extends NonPrepareExpression { } @Override - public int queryBindHash() { - int hc = sql.hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(values.length); for (Object value : values) { - hc = hc * 92821 + value.hashCode(); + hash.update(value); } - return hc; } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java index 0f8de90ec..e50d9856c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java @@ -5,6 +5,7 @@ import io.ebean.plugin.ExpressionPath; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.server.el.ElPropertyValue; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.NaturalKeyQueryData; import java.io.IOException; @@ -121,8 +122,8 @@ public class SimpleExpression extends AbstractValueExpression { } @Override - public int queryBindHash() { - return value().hashCode(); + public void queryBindHash(BindHash hash) { + hash.update(value()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index 96a923637..6f3334ede 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -32,6 +32,8 @@ import io.ebean.bean.PersistenceContext; import io.ebean.event.BeanQueryRequest; import io.ebean.event.readaudit.ReadEvent; import io.ebean.plugin.BeanType; +import io.ebean.plugin.LoadErrorHandler; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.BindParams; import io.ebeaninternal.api.CQueryPlanKey; import io.ebeaninternal.api.CacheIdLookup; @@ -283,6 +285,8 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { private boolean orderById; + private final String bindHashAlgorithm; + private ProfileLocation profileLocation; public DefaultOrmQuery(BeanDescriptor desc, SpiEbeanServer server, ExpressionFactory expressionFactory) { @@ -291,6 +295,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { this.beanType = desc.getBeanType(); this.server = server; this.orderById = server.getServerConfig().isDefaultOrderById(); + this.bindHashAlgorithm = "MD5"; // TODO: server.getServerConfig().isUseMd5BindHash(); this.disableLazyLoading = server.getServerConfig().isDisableLazyLoading(); this.expressionFactory = expressionFactory; this.detail = new OrmQueryDetail(); @@ -1276,15 +1281,12 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { *

*/ @Override - public int queryBindHash() { - int hc = (id == null ? 0 : id.hashCode()); - hc = hc * 92821 + (whereExpressions == null ? 0 : whereExpressions.queryBindHash()); - hc = hc * 92821 + (havingExpressions == null ? 0 : havingExpressions.queryBindHash()); - hc = hc * 92821 + (bindParams == null ? 0 : bindParams.queryBindHash()); - hc = hc * 92821 + (asOf == null ? 0 : asOf.hashCode()); - hc = hc * 92821 + (versionsStart == null ? 0 : versionsStart.hashCode()); - hc = hc * 92821 + (versionsEnd == null ? 0 : versionsEnd.hashCode()); - return hc; + public void queryBindHash(BindHash hash) { + hash.update(id); + if (whereExpressions != null) whereExpressions.queryBindHash(hash); + if (havingExpressions != null) havingExpressions.queryBindHash(hash); + if (bindParams != null) bindParams.queryBindHash(hash); + hash.update(asOf).update(versionsStart).update(versionsEnd); } /** @@ -1298,8 +1300,10 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { public HashQuery queryHash() { // calculateQueryPlanHash is called just after potential AutoTune tuning // so queryPlanHash is calculated well before this method is called - int hc = queryBindHash(); - return new HashQuery(queryPlanKey, hc); + BindHash hash = bindHashAlgorithm == null ? new HashCodeBindHash() : new MdBindHash(bindHashAlgorithm); + queryBindHash(hash); + hash.finish(); + return new HashQuery(queryPlanKey, hash); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java new file mode 100644 index 000000000..cc6cd5f13 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java @@ -0,0 +1,56 @@ +package io.ebeaninternal.server.querydefn; + +import java.util.Objects; + +import io.ebeaninternal.api.BindHash; + +/** + * HashCode builder that uses Object.hashCode for computing bind-hashes. + * This is a fast and lightweight implementation, but may produce collisions. + * + * @author Roland Praml, FOCONIS AG + */ +public class HashCodeBindHash implements BindHash { + + int hashCode; + + @Override + public BindHash update(int intValue) { + hashCode = hashCode * 92821 + intValue; + return this; + } + + @Override + public BindHash update(long longValue) { + hashCode = hashCode * 92821 + Long.hashCode(longValue); + return this; + } + + @Override + public BindHash update(boolean boolValue) { + hashCode = hashCode * 92821 + Boolean.hashCode(boolValue); + return this; + } + + @Override + public BindHash update(Object value) { + hashCode = hashCode * 92821 + Objects.hashCode(value); + return this; + } + + @Override + public void finish() { + // nothing to do + } + + @Override + public boolean equals(Object obj) { + return obj instanceof HashCodeBindHash && ((HashCodeBindHash) obj).hashCode == hashCode; + } + + @Override + public int hashCode() { + return hashCode; + } + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/MdBindHash.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/MdBindHash.java new file mode 100644 index 000000000..4791a9c07 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/MdBindHash.java @@ -0,0 +1,138 @@ +/* + * Licensed Materials - Property of FOCONIS AG + * (C) Copyright FOCONIS AG. + */ + +package io.ebeaninternal.server.querydefn; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Arrays; +import java.util.Date; +import java.util.UUID; + +import io.ebeaninternal.api.BindHash; + +/** + * Bind hash that uses a MessageDigest to compute a collision resistent hash. + * + * @author Roland Praml, FOCONIS AG + * + */ +public class MdBindHash implements BindHash { + private MessageDigest md; + private byte[] buffer; + private int hashCode; + + public MdBindHash(String algorithm) { + try { + md = MessageDigest.getInstance(algorithm); + } catch (NoSuchAlgorithmException nsae) { + throw new InternalError(algorithm + " not supported", nsae); + } + } + + @Override + public BindHash update(int v) { + md.update((byte) (v >>> 24)); + md.update((byte) (v >>> 16)); + md.update((byte) (v >>> 8)); + md.update((byte) (v >>> 0)); + return this; + } + + @Override + public BindHash update(long v) { + md.update((byte) (v >>> 56)); + md.update((byte) (v >>> 48)); + md.update((byte) (v >>> 40)); + md.update((byte) (v >>> 32)); + md.update((byte) (v >>> 24)); + md.update((byte) (v >>> 16)); + md.update((byte) (v >>> 8)); + md.update((byte) (v >>> 0)); + return this; + } + + @Override + public BindHash update(boolean boolValue) { + md.update(boolValue ? (byte) 1 : (byte) 0); + return this; + } + + @Override + public BindHash update(Object value) { + if (value == null) { + md.update((byte) 0); + + // do some special handling for known object types + } else if (value instanceof String) { + md.update(((String) value).getBytes()); + + } else if (value instanceof Long) { + update(((Long) value).longValue()); + + } else if (value instanceof Double) { + double d = ((Double) value).doubleValue(); + update(Double.doubleToLongBits(d)); + + } else if (value instanceof UUID) { + UUID uuid = (UUID) value; + update(uuid.getLeastSignificantBits()); + update(uuid.getMostSignificantBits()); + + } else if (value instanceof Date) { + update(((Date) value).getTime()); + + } else if (value instanceof Instant) { + update(((Instant) value).getEpochSecond()); + update(((Instant) value).getNano()); + + } else if (value instanceof LocalDate) { + update(((LocalDate) value).toEpochDay()); + + } else if (value instanceof LocalTime) { + update(((LocalTime) value).toSecondOfDay()); + update(((LocalTime) value).toNanoOfDay()); + + } else if (value instanceof LocalDateTime) { + update(((LocalDateTime) value).toLocalDate().toEpochDay()); + update(((LocalDateTime) value).toLocalTime().toSecondOfDay()); + update(((LocalDateTime) value).toLocalTime().toNanoOfDay()); + + } else { + // Fall back to hashCode for all other types + updateOther(value); + } + return this; + } + + /** + * Update all other object. May be overridden to handle joda dates. + */ + protected void updateOther(Object value) { + // Fall back to hashCode for all other types + update(value.hashCode()); + } + + @Override + public void finish() { + buffer = md.digest(); + hashCode = Arrays.hashCode(buffer); + md = null; // clear memory + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MdBindHash && Arrays.equals(buffer, ((MdBindHash) obj).buffer); + } + + @Override + public int hashCode() { + return hashCode; + } +} diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java index 1953f2959..6c608472f 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java @@ -3,6 +3,8 @@ package io.ebeaninternal.server.expression; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; +import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.server.querydefn.HashCodeBindHash; public class RawExpressionTest extends BaseExpressionTest { @@ -61,11 +63,17 @@ public class RawExpressionTest extends BaseExpressionTest { } public void assert_queryBindHash_isDifferent(RawExpression exp0, RawExpression exp1) { - assertThat(exp0.queryBindHash()).isNotEqualTo(exp1.queryBindHash()); + assertThat(getHash(exp0)).isNotEqualTo(getHash(exp1)); } public void assert_queryBindHash_isSame(RawExpression exp0, RawExpression exp1) { - assertThat(exp0.queryBindHash()).isEqualTo(exp1.queryBindHash()); + assertThat(getHash(exp0)).isEqualTo(getHash(exp1)); } + private int getHash(RawExpression query) { + BindHash hash = new HashCodeBindHash(); + query.queryBindHash(hash); + hash.finish(); + return hash.hashCode(); + } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java index d9e621221..cb1738ba8 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java @@ -4,6 +4,7 @@ package io.ebeaninternal.server.querydefn; import io.ebean.BaseTestCase; import io.ebean.CacheMode; import io.ebean.Ebean; +import io.ebeaninternal.api.BindHash; import io.ebeaninternal.api.SpiQuery; import io.ebeaninternal.server.core.OrmQueryRequest; import org.junit.Test; @@ -62,7 +63,7 @@ public class DefaultOrmQueryTest extends BaseTestCase { prepare(q1, q2); assertThat(q1.createQueryPlanKey()).isNotEqualTo(q2.createQueryPlanKey()); - assertThat(q1.queryBindHash()).isNotEqualTo(q2.queryBindHash()); + assertThat(getHash(q1)).isNotEqualTo(getHash(q2)); } @Test @@ -73,7 +74,7 @@ public class DefaultOrmQueryTest extends BaseTestCase { prepare(q1, q2); assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey()); - assertThat(q1.queryBindHash()).isNotEqualTo(q2.queryBindHash()); + assertThat(getHash(q1)).isNotEqualTo(getHash(q2)); } @Test @@ -84,7 +85,7 @@ public class DefaultOrmQueryTest extends BaseTestCase { prepare(q1, q2); assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey()); - assertThat(q1.queryBindHash()).isEqualTo(q2.queryBindHash()); + assertThat(getHash(q1)).isEqualTo(getHash(q2)); } @Test @@ -110,4 +111,11 @@ public class DefaultOrmQueryTest extends BaseTestCase { OrmQueryRequest r2 = createQueryRequest(SpiQuery.Type.LIST, q2, null); q2.prepare(r2); } + + private int getHash(DefaultOrmQuery query) { + BindHash hash = new HashCodeBindHash(); + query.queryBindHash(hash); + hash.finish(); + return hash.hashCode(); + } } diff --git a/ebean-core/src/test/java/org/tests/cache/TestQueryCache.java b/ebean-core/src/test/java/org/tests/cache/TestQueryCache.java index f9e732220..4c4d56109 100644 --- a/ebean-core/src/test/java/org/tests/cache/TestQueryCache.java +++ b/ebean-core/src/test/java/org/tests/cache/TestQueryCache.java @@ -3,7 +3,7 @@ package org.tests.cache; import io.ebean.BaseTestCase; import io.ebean.CacheMode; import io.ebean.DB; -import io.ebean.Ebean; +import io.ebean.ExpressionList; import io.ebean.bean.BeanCollection; import io.ebean.cache.ServerCache; import org.ebeantest.LoggedSqlCollector; @@ -14,6 +14,7 @@ import org.tests.model.basic.ResetBasicData; import org.tests.model.cache.EColAB; import java.util.List; +import java.util.function.Consumer; import static org.assertj.core.api.Assertions.assertThat; @@ -26,8 +27,7 @@ public class TestQueryCache extends BaseTestCase { new EColAB("02", "10").save(); List list1 = - Ebean.getServer(null) - .find(EColAB.class) + DB.find(EColAB.class) .setUseQueryCache(true) .where() .eq("columnA", "01") @@ -35,8 +35,7 @@ public class TestQueryCache extends BaseTestCase { .findList(); List list2 = - Ebean.getServer(null) - .find(EColAB.class) + DB.find(EColAB.class) .setUseQueryCache(true) .where() .eq("columnA", "02") @@ -57,7 +56,7 @@ public class TestQueryCache extends BaseTestCase { new EColAB("03", "SingleAttribute").save(); new EColAB("03", "SingleAttribute").save(); - List colA_first = Ebean.getServer(null) + List colA_first = DB .find(EColAB.class) .setUseQueryCache(true) .setDistinct(true) @@ -66,7 +65,7 @@ public class TestQueryCache extends BaseTestCase { .eq("columnB", "SingleAttribute") .findSingleAttributeList(); - List colA_Second = Ebean.getServer(null) + List colA_Second = DB .find(EColAB.class) .setUseQueryCache(true) .setDistinct(true) @@ -77,7 +76,7 @@ public class TestQueryCache extends BaseTestCase { assertThat(colA_Second).isSameAs(colA_first); - List colA_NotDistinct = Ebean.getServer(null) + List colA_NotDistinct = DB .find(EColAB.class) .setUseQueryCache(true) .select("columnA") @@ -89,7 +88,7 @@ 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 = Ebean.getServer(null) + int count = DB .find(EColAB.class) .setUseQueryCache(true) .select("columnA") @@ -107,13 +106,13 @@ public class TestQueryCache extends BaseTestCase { LoggedSqlCollector.start(); - int count0 = Ebean.find(EColAB.class) + int count0 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.ON) .where() .eq("columnB", "count") .findCount(); - int count1 = Ebean.find(EColAB.class) + int count1 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.ON) .where() .eq("columnB", "count") @@ -126,7 +125,7 @@ public class TestQueryCache extends BaseTestCase { // and now, ensure that we hit the database LoggedSqlCollector.start(); - int count2 = Ebean.find(EColAB.class) + int count2 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.OFF) .where() .eq("columnB", "count") @@ -142,13 +141,13 @@ public class TestQueryCache extends BaseTestCase { LoggedSqlCollector.start(); - int count0 = Ebean.find(EColAB.class) + int count0 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.ON) .where() .eq("columnB", "abc") .findCount(); - int count1 = Ebean.find(EColAB.class) + int count1 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.ON) .where() .eq("columnB", "def") @@ -167,13 +166,13 @@ public class TestQueryCache extends BaseTestCase { LoggedSqlCollector.start(); - int count0 = Ebean.find(EColAB.class) + int count0 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.ON) .where() .eq("columnB", "uvw") .findCount(); - int count1 = Ebean.find(EColAB.class) + int count1 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.PUT) .where() .eq("columnB", "uvw") @@ -193,13 +192,13 @@ public class TestQueryCache extends BaseTestCase { LoggedSqlCollector.start(); - int count0 = Ebean.find(EColAB.class) + int count0 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.PUT) .where() .eq("columnB", "xyz") .findCount(); - int count1 = Ebean.find(EColAB.class) + int count1 = DB.find(EColAB.class) .setUseQueryCache(CacheMode.ON) .where() .eq("columnB", "xyz") @@ -214,26 +213,26 @@ public class TestQueryCache extends BaseTestCase { @Test @SuppressWarnings("unchecked") - public void test() { + public void testReadOnlyFind() { ResetBasicData.reset(); - ServerCache customerCache = Ebean.getServerCacheManager().getQueryCache(Customer.class); + ServerCache customerCache = DB.getServerCacheManager().getQueryCache(Customer.class); customerCache.clear(); - List list = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where() + List list = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where() .ilike("name", "Rob").findList(); BeanCollection bc = (BeanCollection) list; Assert.assertTrue(bc.isReadOnly()); Assert.assertFalse(bc.isEmpty()); Assert.assertTrue(!list.isEmpty()); - Assert.assertTrue(Ebean.getBeanState(list.get(0)).isReadOnly()); + Assert.assertTrue(DB.getBeanState(list.get(0)).isReadOnly()); - List list2 = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where() + List list2 = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(true).where() .ilike("name", "Rob").findList(); - List list2B = Ebean.find(Customer.class).setUseQueryCache(true) + List list2B = DB.find(Customer.class).setUseQueryCache(true) // .setReadOnly(true) .where().ilike("name", "Rob").findList(); @@ -245,7 +244,7 @@ public class TestQueryCache extends BaseTestCase { - List list3 = Ebean.find(Customer.class).setUseQueryCache(true).setReadOnly(false).where() + List list3 = DB.find(Customer.class).setUseQueryCache(true).setReadOnly(false).where() .ilike("name", "Rob").findList(); Assert.assertNotSame(list, list3); @@ -269,13 +268,13 @@ public class TestQueryCache extends BaseTestCase { LoggedSqlCollector.start(); - List colA_first = Ebean.find(EColAB.class) + List colA_first = DB.find(EColAB.class) .setUseQueryCache(CacheMode.ON) .where() .eq("columnB", "someId") .findIds(); - List colA_second = Ebean.find(EColAB.class) + List colA_second = DB.find(EColAB.class) .setUseQueryCache(CacheMode.ON) .where() .eq("columnB", "someId") @@ -289,7 +288,7 @@ public class TestQueryCache extends BaseTestCase { // and now, ensure that we hit the database LoggedSqlCollector.start(); - colA_second = Ebean.find(EColAB.class) + colA_second = DB.find(EColAB.class) .setUseQueryCache(CacheMode.PUT) .where() .eq("columnB", "someId") @@ -299,4 +298,35 @@ public class TestQueryCache extends BaseTestCase { assertThat(sql).hasSize(1); } + @Test + public void findCountDifferentQueriesBit() { + DB.getDefault().getPluginApi().getServerCacheManager().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.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",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)); + + } + + void differentFindCount(Consumer> q0, Consumer> q1) { + LoggedSqlCollector.start(); + + ExpressionList el0 = DB.find(EColAB.class).setUseQueryCache(CacheMode.ON).where(); + q0.accept(el0); + el0.findCount(); + + ExpressionList el1 = DB.find(EColAB.class).setUseQueryCache(CacheMode.ON).where(); + q1.accept(el1); + el1.findCount(); + + List sql = LoggedSqlCollector.stop(); + + assertThat(sql).hasSize(2); // different queries + } + } From e18c190905fa8a2a2051e6bba3447ad1a942408d Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Mon, 9 Aug 2021 09:46:49 +0200 Subject: [PATCH 060/120] Fix the test to run with java 8 --- .../server/profile/BasicProfileLocationTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java index 84a53442a..9d99b17ce 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/profile/BasicProfileLocationTest.java @@ -14,7 +14,11 @@ public class BasicProfileLocationTest { assertThat(loc.obtain()).isTrue(); assertThat(loc.fullLocation()).endsWith(":12)"); - assertThat(loc.location()).isEqualTo("java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0"); + if (System.getProperty("java.version").startsWith("1.8")) { + assertThat(loc.location()).isEqualTo("sun.reflect.NativeMethodAccessorImpl.invoke0"); + } else { + assertThat(loc.location()).isEqualTo("java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0"); + } assertThat(loc.label()).isEqualTo("NativeMethodAccessorImpl.invoke0"); } From c8ae3c5ef65da0ad043f9a0c302720abd298fda9 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 10 Aug 2021 09:30:25 +0200 Subject: [PATCH 061/120] FIX: Changelog-oldValue did not work for Json mutable properties --- .../io/ebean/bean/EntityBeanIntercept.java | 13 ++++++--- .../org/tests/changelog/TestChangeLog.java | 27 +++++++++++++++++++ .../tests/model/basic/EBasicChangeLog.java | 19 ++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java index 78d8e5f8c..527860200 100644 --- a/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java +++ b/ebean-api/src/main/java/io/ebean/bean/EntityBeanIntercept.java @@ -395,6 +395,15 @@ public final class EntityBeanIntercept implements Serializable { this.owner._ebean_setEmbeddedLoaded(); this.lazyLoadProperty = -1; this.origValues = null; + // after save, transfer the mutable next values back to mutable info + if (mutableNext != null) { + for (int i = 0; i < mutableNext.length; i++) { + MutableValueNext next = mutableNext[i]; + if (next != null) { + mutableInfo(i, next.info()); + } + } + } this.mutableNext = null; for (int i = 0; i < flags.length; i++) { flags[i] &= ~(FLAG_CHANGED_PROP | FLAG_ORIG_VALUE_SET); @@ -1223,9 +1232,7 @@ public final class EntityBeanIntercept implements Serializable { if (mutableNext == null) { return null; } - final MutableValueNext next = mutableNext[propertyIndex]; - mutableInfo(propertyIndex, next.info()); - return next.content(); + return mutableNext[propertyIndex].content(); } } diff --git a/ebean-core/src/test/java/org/tests/changelog/TestChangeLog.java b/ebean-core/src/test/java/org/tests/changelog/TestChangeLog.java index 2adbbfc4b..a10a41276 100644 --- a/ebean-core/src/test/java/org/tests/changelog/TestChangeLog.java +++ b/ebean-core/src/test/java/org/tests/changelog/TestChangeLog.java @@ -16,10 +16,13 @@ import io.ebean.event.changelog.ChangeLogRegister; import io.ebean.event.changelog.ChangeSet; import io.ebean.event.changelog.ChangeType; import io.ebean.event.changelog.TxnState; +import io.ebeantest.LoggedSql; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.tests.model.basic.EBasicChangeLog; +import org.tests.model.json.PlainBean; import java.util.ArrayList; import java.util.List; @@ -130,7 +133,31 @@ public class TestChangeLog extends BaseTestCase { assertThat(change.getEvent()).isEqualTo(ChangeType.DELETE); assertThat(change.getData()).isNull(); } + + @Test + public void testWithJsonMutationDetection() { + EBasicChangeLog bean = new EBasicChangeLog(); + bean.setName(null); + bean.setShortDescription("hello"); + PlainBean jsonBean = new PlainBean(); + bean.setPlainBean(jsonBean); + jsonBean.setName("A"); + server.save(bean); + + BeanChange change = firstChange(); + assertThat(change.getEvent()).isEqualTo(ChangeType.INSERT); + + jsonBean.setName("B"); + LoggedSql.start(); + server.save(bean); + assertThat(LoggedSql.stop()).isNotEmpty(); + + change = firstChange(); + assertThat(change.getEvent()).isEqualTo(ChangeType.UPDATE); + assertThat(change.getData()).contains("\"plainBean\":{\"name\":\"B\""); + assertThat(change.getOldData()).contains("\"plainBean\":{\"name\":\"A\""); + } private Database createServer() { DatabaseConfig config = new DatabaseConfig(); diff --git a/ebean-core/src/test/java/org/tests/model/basic/EBasicChangeLog.java b/ebean-core/src/test/java/org/tests/model/basic/EBasicChangeLog.java index 88e3e4f10..0ac02e749 100644 --- a/ebean-core/src/test/java/org/tests/model/basic/EBasicChangeLog.java +++ b/ebean-core/src/test/java/org/tests/model/basic/EBasicChangeLog.java @@ -2,6 +2,7 @@ package org.tests.model.basic; import io.ebean.annotation.Cache; import io.ebean.annotation.ChangeLog; +import io.ebean.annotation.DbJson; import io.ebean.annotation.ReadAudit; import io.ebean.annotation.WhenCreated; import io.ebean.annotation.WhenModified; @@ -12,11 +13,16 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Version; import javax.validation.constraints.Size; + +import org.tests.model.json.PlainBean; + +import static io.ebean.annotation.MutationDetection.SOURCE; + import java.sql.Timestamp; @Cache(enableQueryCache = true) @ReadAudit -@ChangeLog(updatesThatInclude = {"name", "shortDescription"}) +@ChangeLog(updatesThatInclude = {"name", "shortDescription", "plainBean"}) @Entity public class EBasicChangeLog { @@ -46,6 +52,9 @@ public class EBasicChangeLog { @Version Long version; + + @DbJson(length = 500, mutationDetection = SOURCE) // such that we can rebuild old values + PlainBean plainBean; public Long getId() { return id; @@ -118,4 +127,12 @@ public class EBasicChangeLog { public void setVersion(Long version) { this.version = version; } + + public PlainBean getPlainBean() { + return plainBean; + } + + public void setPlainBean(PlainBean plainBean) { + this.plainBean = plainBean; + } } From 3e8f76cd6d054cbc9bb88392c4e3048d8857841b Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 10 Aug 2021 21:49:31 +1200 Subject: [PATCH 062/120] Update HashCodeBindHash to use values for equals() --- .../server/querydefn/DefaultOrmQuery.java | 3 ++- .../server/querydefn/HashCodeBindHash.java | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index 6f3334ede..f29889a88 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -1300,7 +1300,8 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { public HashQuery queryHash() { // calculateQueryPlanHash is called just after potential AutoTune tuning // so queryPlanHash is calculated well before this method is called - BindHash hash = bindHashAlgorithm == null ? new HashCodeBindHash() : new MdBindHash(bindHashAlgorithm); + //BindHash hash = bindHashAlgorithm == null ? new HashCodeBindHash() : new MdBindHash(bindHashAlgorithm); + BindHash hash = new HashCodeBindHash();// : new MdBindHash(bindHashAlgorithm); queryBindHash(hash); hash.finish(); return new HashQuery(queryPlanKey, hash); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java index cc6cd5f13..9bc9c60fc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java @@ -1,5 +1,7 @@ package io.ebeaninternal.server.querydefn; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import io.ebeaninternal.api.BindHash; @@ -12,28 +14,33 @@ import io.ebeaninternal.api.BindHash; */ public class HashCodeBindHash implements BindHash { - int hashCode; + private final List values = new ArrayList<>(); + private int hashCode; @Override public BindHash update(int intValue) { + values.add(intValue); hashCode = hashCode * 92821 + intValue; return this; } @Override public BindHash update(long longValue) { + values.add(longValue); hashCode = hashCode * 92821 + Long.hashCode(longValue); return this; } @Override public BindHash update(boolean boolValue) { + values.add(boolValue); hashCode = hashCode * 92821 + Boolean.hashCode(boolValue); return this; } @Override public BindHash update(Object value) { + values.add(value); hashCode = hashCode * 92821 + Objects.hashCode(value); return this; } @@ -45,7 +52,7 @@ public class HashCodeBindHash implements BindHash { @Override public boolean equals(Object obj) { - return obj instanceof HashCodeBindHash && ((HashCodeBindHash) obj).hashCode == hashCode; + return obj instanceof HashCodeBindHash && ((HashCodeBindHash) obj).values.equals(values); } @Override From ede1ad0a4c0d067bfa2823d0ec24530c7e88254e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 10 Aug 2021 21:58:41 +1200 Subject: [PATCH 063/120] Fix BindParams equals() and hashCode() --- .../java/io/ebeaninternal/api/BindParams.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java index 2817c4ba1..3a81f2f0a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java @@ -4,11 +4,7 @@ import io.ebeaninternal.server.persist.MultiValueWrapper; import io.ebeaninternal.server.querydefn.NaturalKeyBindParam; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; /** @@ -414,6 +410,7 @@ public class BindParams implements Serializable { @Override public int hashCode() { int hc = getClass().hashCode(); + hc = hc * 92821 + (encryptionKey ? 0 : 1); hc = hc * 92821 + (isInParam ? 0 : 1); hc = hc * 92821 + (isOutParam ? 0 : 1); hc = hc * 92821 + (type); @@ -421,13 +418,17 @@ public class BindParams implements Serializable { return hc; } - void queryBindHash(BindHash hash) { - hash.update(isInParam).update(isOutParam).update(type).update(inValue); - } - @Override public boolean equals(Object o) { - return o != null && (o == this || (o instanceof Param) && hashCode() == o.hashCode()); + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Param param = (Param) o; + return encryptionKey == param.encryptionKey && isInParam == param.isInParam && isOutParam == param.isOutParam + && type == param.type && Objects.equals(inValue, param.inValue); + } + + void queryBindHash(BindHash hash) { + hash.update(isInParam).update(isOutParam).update(type).update(inValue); } /** From 2dc48cf08d4519e66bc8bc81b9f31a791407e47d Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 10 Aug 2021 22:00:46 +1200 Subject: [PATCH 064/120] ArrayContainsExpression equals() to use enhanced for loop --- .../server/expression/ArrayContainsExpression.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java index ac6d27d0e..3c200c046 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java @@ -52,8 +52,8 @@ public class ArrayContainsExpression extends AbstractExpression { @Override public void queryBindHash(BindHash hash) { hash.update(values.length); - for (int i = 0; i < values.length; i++) { - hash.update(values[i]); + for (Object value : values) { + hash.update(value); } } From ac3edbedf41ef627f5d99f77507dbfac4fc51dd5 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 10 Aug 2021 22:07:48 +1200 Subject: [PATCH 065/120] Remove MdBindHash, tidy DefaultOrmQuery --- .../server/querydefn/DefaultOrmQuery.java | 67 +-------- .../server/querydefn/MdBindHash.java | 138 ------------------ 2 files changed, 5 insertions(+), 200 deletions(-) delete mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/querydefn/MdBindHash.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index f29889a88..e4735e32b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -1,30 +1,7 @@ package io.ebeaninternal.server.querydefn; -import io.ebean.CacheMode; -import io.ebean.CountDistinctOrder; -import io.ebean.Database; -import io.ebean.DtoQuery; -import io.ebean.Expression; -import io.ebean.ExpressionFactory; -import io.ebean.ExpressionList; -import io.ebean.FetchConfig; -import io.ebean.FetchGroup; -import io.ebean.FetchPath; -import io.ebean.FutureIds; -import io.ebean.FutureList; -import io.ebean.FutureRowCount; -import io.ebean.OrderBy; +import io.ebean.*; import io.ebean.OrderBy.Property; -import io.ebean.PagedList; -import io.ebean.PersistenceContextScope; -import io.ebean.ProfileLocation; -import io.ebean.Query; -import io.ebean.QueryIterator; -import io.ebean.QueryType; -import io.ebean.RawSql; -import io.ebean.Transaction; -import io.ebean.UpdateQuery; -import io.ebean.Version; import io.ebean.bean.CallOrigin; import io.ebean.bean.ObjectGraphNode; import io.ebean.bean.ObjectGraphOrigin; @@ -32,31 +9,10 @@ import io.ebean.bean.PersistenceContext; import io.ebean.event.BeanQueryRequest; import io.ebean.event.readaudit.ReadEvent; import io.ebean.plugin.BeanType; -import io.ebean.plugin.LoadErrorHandler; -import io.ebeaninternal.api.BindHash; -import io.ebeaninternal.api.BindParams; -import io.ebeaninternal.api.CQueryPlanKey; -import io.ebeaninternal.api.CacheIdLookup; -import io.ebeaninternal.api.CacheIdLookupMany; -import io.ebeaninternal.api.CacheIdLookupSingle; -import io.ebeaninternal.api.HashQuery; -import io.ebeaninternal.api.ManyWhereJoins; -import io.ebeaninternal.api.NaturalKeyQueryData; -import io.ebeaninternal.api.SpiEbeanServer; -import io.ebeaninternal.api.SpiExpression; -import io.ebeaninternal.api.SpiExpressionList; -import io.ebeaninternal.api.SpiExpressionValidation; -import io.ebeaninternal.api.SpiNamedParam; -import io.ebeaninternal.api.SpiQuery; -import io.ebeaninternal.api.SpiQuerySecondary; -import io.ebeaninternal.api.SpiTransaction; +import io.ebeaninternal.api.*; import io.ebeaninternal.server.autotune.ProfilingListener; import io.ebeaninternal.server.core.SpiOrmQueryRequest; -import io.ebeaninternal.server.deploy.BeanDescriptor; -import io.ebeaninternal.server.deploy.BeanNaturalKey; -import io.ebeaninternal.server.deploy.BeanPropertyAssocMany; -import io.ebeaninternal.server.deploy.InheritInfo; -import io.ebeaninternal.server.deploy.TableJoin; +import io.ebeaninternal.server.deploy.*; import io.ebeaninternal.server.el.ElPropertyDeploy; import io.ebeaninternal.server.expression.DefaultExpressionList; import io.ebeaninternal.server.expression.IdInExpression; @@ -68,14 +24,7 @@ import io.ebeaninternal.server.transaction.ExternalJdbcTransaction; import javax.persistence.PersistenceException; import java.sql.Connection; import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; +import java.util.*; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Stream; @@ -93,8 +42,6 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { private static final FetchConfig FETCH_LAZY = FetchConfig.ofLazy(); - private final ReentrantLock lock = new ReentrantLock(); - private final Class beanType; private final ExpressionFactory expressionFactory; @@ -285,8 +232,6 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { private boolean orderById; - private final String bindHashAlgorithm; - private ProfileLocation profileLocation; public DefaultOrmQuery(BeanDescriptor desc, SpiEbeanServer server, ExpressionFactory expressionFactory) { @@ -295,7 +240,6 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { this.beanType = desc.getBeanType(); this.server = server; this.orderById = server.getServerConfig().isDefaultOrderById(); - this.bindHashAlgorithm = "MD5"; // TODO: server.getServerConfig().isUseMd5BindHash(); this.disableLazyLoading = server.getServerConfig().isDisableLazyLoading(); this.expressionFactory = expressionFactory; this.detail = new OrmQueryDetail(); @@ -1300,8 +1244,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { public HashQuery queryHash() { // calculateQueryPlanHash is called just after potential AutoTune tuning // so queryPlanHash is calculated well before this method is called - //BindHash hash = bindHashAlgorithm == null ? new HashCodeBindHash() : new MdBindHash(bindHashAlgorithm); - BindHash hash = new HashCodeBindHash();// : new MdBindHash(bindHashAlgorithm); + BindHash hash = new HashCodeBindHash(); queryBindHash(hash); hash.finish(); return new HashQuery(queryPlanKey, hash); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/MdBindHash.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/MdBindHash.java deleted file mode 100644 index 4791a9c07..000000000 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/MdBindHash.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed Materials - Property of FOCONIS AG - * (C) Copyright FOCONIS AG. - */ - -package io.ebeaninternal.server.querydefn; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.Arrays; -import java.util.Date; -import java.util.UUID; - -import io.ebeaninternal.api.BindHash; - -/** - * Bind hash that uses a MessageDigest to compute a collision resistent hash. - * - * @author Roland Praml, FOCONIS AG - * - */ -public class MdBindHash implements BindHash { - private MessageDigest md; - private byte[] buffer; - private int hashCode; - - public MdBindHash(String algorithm) { - try { - md = MessageDigest.getInstance(algorithm); - } catch (NoSuchAlgorithmException nsae) { - throw new InternalError(algorithm + " not supported", nsae); - } - } - - @Override - public BindHash update(int v) { - md.update((byte) (v >>> 24)); - md.update((byte) (v >>> 16)); - md.update((byte) (v >>> 8)); - md.update((byte) (v >>> 0)); - return this; - } - - @Override - public BindHash update(long v) { - md.update((byte) (v >>> 56)); - md.update((byte) (v >>> 48)); - md.update((byte) (v >>> 40)); - md.update((byte) (v >>> 32)); - md.update((byte) (v >>> 24)); - md.update((byte) (v >>> 16)); - md.update((byte) (v >>> 8)); - md.update((byte) (v >>> 0)); - return this; - } - - @Override - public BindHash update(boolean boolValue) { - md.update(boolValue ? (byte) 1 : (byte) 0); - return this; - } - - @Override - public BindHash update(Object value) { - if (value == null) { - md.update((byte) 0); - - // do some special handling for known object types - } else if (value instanceof String) { - md.update(((String) value).getBytes()); - - } else if (value instanceof Long) { - update(((Long) value).longValue()); - - } else if (value instanceof Double) { - double d = ((Double) value).doubleValue(); - update(Double.doubleToLongBits(d)); - - } else if (value instanceof UUID) { - UUID uuid = (UUID) value; - update(uuid.getLeastSignificantBits()); - update(uuid.getMostSignificantBits()); - - } else if (value instanceof Date) { - update(((Date) value).getTime()); - - } else if (value instanceof Instant) { - update(((Instant) value).getEpochSecond()); - update(((Instant) value).getNano()); - - } else if (value instanceof LocalDate) { - update(((LocalDate) value).toEpochDay()); - - } else if (value instanceof LocalTime) { - update(((LocalTime) value).toSecondOfDay()); - update(((LocalTime) value).toNanoOfDay()); - - } else if (value instanceof LocalDateTime) { - update(((LocalDateTime) value).toLocalDate().toEpochDay()); - update(((LocalDateTime) value).toLocalTime().toSecondOfDay()); - update(((LocalDateTime) value).toLocalTime().toNanoOfDay()); - - } else { - // Fall back to hashCode for all other types - updateOther(value); - } - return this; - } - - /** - * Update all other object. May be overridden to handle joda dates. - */ - protected void updateOther(Object value) { - // Fall back to hashCode for all other types - update(value.hashCode()); - } - - @Override - public void finish() { - buffer = md.digest(); - hashCode = Arrays.hashCode(buffer); - md = null; // clear memory - } - - @Override - public boolean equals(Object obj) { - return obj instanceof MdBindHash && Arrays.equals(buffer, ((MdBindHash) obj).buffer); - } - - @Override - public int hashCode() { - return hashCode; - } -} From e1ad210bb088aa7da3a6ee15fe6775742becf784 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 10 Aug 2021 22:18:33 +1200 Subject: [PATCH 066/120] Tidy JunctionExpression --- .../server/expression/JunctionExpression.java | 38 ++++++------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 51eba8f39..88614873d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -114,9 +114,8 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression @Override public void writeDocQuery(DocQueryContext context) throws IOException { context.startBool(type); - List list = exprList.internalList(); - for (SpiExpression aList : list) { - aList.writeDocQuery(context); + for (SpiExpression expr : exprList.internalList()) { + expr.writeDocQuery(context); } context.endBool(); } @@ -124,9 +123,8 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression @Override public void writeDocQueryJunction(DocQueryContext context) throws IOException { context.startBoolGroupList(type); - List list = exprList.internalList(); - for (SpiExpression aList : list) { - aList.writeDocQuery(context); + for (SpiExpression expr : exprList.internalList()) { + expr.writeDocQuery(context); } context.endBoolGroupList(); } @@ -139,18 +137,15 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression @Override public void containsMany(BeanDescriptor desc, ManyWhereJoins manyWhereJoin) { - List list = exprList.internalList(); - // get the current state for 'require outer joins' boolean parentOuterJoins = manyWhereJoin.isRequireOuterJoins(); if (type == Type.OR) { // turn on outer joins required for disjunction expressions manyWhereJoin.setRequireOuterJoins(true); } - - for (SpiExpression aList : list) { - aList.containsMany(desc, manyWhereJoin); + for (SpiExpression expr : list) { + expr.containsMany(desc, manyWhereJoin); } if (type == Type.OR && !parentOuterJoins) { // restore state to not forcing outer joins @@ -177,18 +172,14 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression @Override public void addBindValues(SpiExpressionRequest request) { - - List list = exprList.internalList(); - for (SpiExpression aList : list) { - aList.addBindValues(request); + for (SpiExpression expr : exprList.internalList()) { + expr.addBindValues(request); } } @Override public void addSql(SpiExpressionRequest request) { - List list = exprList.internalList(); - if (!list.isEmpty()) { request.append(type.prefix()); request.append("("); @@ -205,9 +196,8 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression @Override public void prepareExpression(BeanQueryRequest request) { - List list = exprList.internalList(); - for (SpiExpression aList : list) { - aList.prepareExpression(request); + for (SpiExpression expr : exprList.internalList()) { + expr.prepareExpression(request); } } @@ -227,10 +217,8 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression @Override public void queryBindHash(BindHash hash) { - int hc = JunctionExpression.class.getName().hashCode(); - List list = exprList.internalList(); - for (SpiExpression aList : list) { - aList.queryBindHash(hash); + for (SpiExpression expr : exprList.internalList()) { + expr.queryBindHash(hash); } } @@ -275,7 +263,6 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression return exprList.textCommonTerms(search, options); } - @Override public ExpressionList allEq(Map propertyMap) { return exprList.allEq(propertyMap); @@ -1025,7 +1012,6 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression @Override public String nestedPath(BeanDescriptor desc) { - PrepareDocNested.prepare(exprList, desc, type); String nestedPath = exprList.allDocNestedPath; if (nestedPath != null) { From e47b1737a82382093714d07bc3f20f787c63c7f9 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 10 Aug 2021 22:28:31 +1200 Subject: [PATCH 067/120] Add HashCodeBindHashTest --- .../querydefn/HashCodeBindHashTest.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/querydefn/HashCodeBindHashTest.java diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/HashCodeBindHashTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/HashCodeBindHashTest.java new file mode 100644 index 000000000..dea0a2e0c --- /dev/null +++ b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/HashCodeBindHashTest.java @@ -0,0 +1,37 @@ +package io.ebeaninternal.server.querydefn; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class HashCodeBindHashTest { + + @Test + public void update_with_null() { + + HashCodeBindHash hash = new HashCodeBindHash(); + hash.update(1).update(null).update("hello"); + + HashCodeBindHash hash2 = new HashCodeBindHash(); + hash2.update(1).update(null).update("hello"); + + assertThat(hash).isEqualTo(hash2); + } + + @Test + public void notEqual() { + + HashCodeBindHash hash = new HashCodeBindHash(); + hash.update(1).update(null).update("hello"); + + HashCodeBindHash hash2 = new HashCodeBindHash(); + hash2.update(1).update("hello"); + + HashCodeBindHash hash3 = new HashCodeBindHash(); + hash2.update(1).update(null); + + assertThat(hash).isNotEqualTo(hash2); + assertThat(hash).isNotEqualTo(hash3); + assertThat(hash2).isNotEqualTo(hash3); + } +} From 75fa7cb7fddda9d5699354e8c0a298abfc6888bc Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 10 Aug 2021 13:24:13 +0200 Subject: [PATCH 068/120] PushJson/PopJson did not work correctly, if null beans were involved --- .../type/ScalarTypeJsonObjectMapper.java | 4 +- .../org/tests/json/TestDbJson_Jackson3.java | 16 ++++ .../org/tests/model/json/EBasicJsonMulti.java | 81 +++++++++++++++++++ 3 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 ebean-core/src/test/java/org/tests/model/json/EBasicJsonMulti.java 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 7ae24420f..41cb28d49 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 @@ -80,11 +80,11 @@ class ScalarTypeJsonObjectMapper { @Override public Object read(DataReader reader) throws SQLException { String json = reader.getString(); + // pushJson such that we MD5 and store on EntityBeanIntercept later + reader.pushJson(json); if (json == null || json.isEmpty()) { return null; } - // pushJson such that we MD5 and store on EntityBeanIntercept later - reader.pushJson(json); try { return objectReader.readValue(json, deserType); } catch (IOException e) { diff --git a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java index c1cc3c40d..5b58b3108 100644 --- a/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java +++ b/ebean-core/src/test/java/org/tests/json/TestDbJson_Jackson3.java @@ -10,6 +10,7 @@ import io.ebeantest.LoggedSql; import org.junit.Test; import org.tests.model.json.EBasicJsonJackson3; import org.tests.model.json.EBasicJsonList; +import org.tests.model.json.EBasicJsonMulti; import org.tests.model.json.PlainBean; import org.tests.model.json.PlainBeanDirtyAware; @@ -221,6 +222,21 @@ public class TestDbJson_Jackson3 extends BaseTestCase { LoggedSql.stop(); } + + @Test + public void push_pop_test() { + + EBasicJsonMulti bean = new EBasicJsonMulti(); + bean.setPlainValue2(new PlainBeanDirtyAware("x", 42)); + bean.save(); + + bean = DB.find(EBasicJsonMulti.class, bean.getId()); + bean.setPlainValue1(null); // already null + bean.setPlainValue2(null); + bean.setPlainValue3(null); // already null + BeanState state = DB.getBeanState(bean); + assertThat(state.getDirtyValues()).hasSize(1).containsKey("plainValue2"); + } private void expectedSql(int i, String s) { assertThat(LoggedSql.collect().get(i)).contains(s); diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicJsonMulti.java b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonMulti.java new file mode 100644 index 000000000..23dcd33d9 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicJsonMulti.java @@ -0,0 +1,81 @@ +package org.tests.model.json; + +import io.ebean.Model; +import io.ebean.annotation.DbJson; +import io.ebean.annotation.MutationDetection; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Version; + +import static io.ebean.annotation.MutationDetection.NONE; +import static io.ebean.annotation.MutationDetection.SOURCE; + +@Entity +public class EBasicJsonMulti extends Model { + + @Id + Long id; + + String name; + + @DbJson(length = 500, mutationDetection = SOURCE) + PlainBeanDirtyAware plainValue1; + + @DbJson(length = 500, mutationDetection = SOURCE) + PlainBeanDirtyAware plainValue2; + + @DbJson(length = 500, mutationDetection = SOURCE) + PlainBeanDirtyAware plainValue3; + + @Version + long version; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public PlainBeanDirtyAware getPlainValue1() { + return plainValue1; + } + + public void setPlainValue1(PlainBeanDirtyAware plainValue1) { + this.plainValue1 = plainValue1; + } + + public PlainBeanDirtyAware getPlainValue2() { + return plainValue2; + } + + public void setPlainValue2(PlainBeanDirtyAware plainValue2) { + this.plainValue2 = plainValue2; + } + + public PlainBeanDirtyAware getPlainValue3() { + return plainValue3; + } + + public void setPlainValue3(PlainBeanDirtyAware plainValue3) { + this.plainValue3 = plainValue3; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } +} From 60dfaab22ce4f10539c2c570a8d014d616321efd Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 10 Aug 2021 15:29:10 +0200 Subject: [PATCH 069/120] Enables select + exists for dynamic formula properties --- .../server/deploy/BeanDescriptor.java | 2 +- .../server/query/SqlTreeBuilder.java | 8 ++--- .../java/org/tests/query/TestQueryAlias.java | 29 +++++++++++++++---- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java index 8e8b02b6f..055f2605a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptor.java @@ -2519,7 +2519,7 @@ public class BeanDescriptor implements BeanType, STreeType, SpiBeanType { if (propName.indexOf('(') > -1) { return findSqlTreeFormula(propName, path); } - return _findBeanProperty(propName); + return findProperty(propName); } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java index 239e8a58e..7e165ef57 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java @@ -365,11 +365,11 @@ public final class SqlTreeBuilder { * This means it can included individual properties of an embedded bean. *

*/ - private void addPropertyToSubQuery(SqlTreeProperties selectProps, STreeType desc, String propName) { - STreeProperty p = desc.findProperty(propName); + private void addPropertyToSubQuery(SqlTreeProperties selectProps, STreeType desc, String propName, String path) { + STreeProperty p = desc.findPropertyWithDynamic(propName, path); if (p == null) { logger.error("property [" + propName + "]not found on " + desc + " for query - excluding it."); - + return; } else if (p instanceof STreePropertyAssoc && p.isEmbedded()) { // if the property is embedded we need to lookup the real column name int pos = propName.indexOf('.'); @@ -383,7 +383,7 @@ public final class SqlTreeBuilder { private void addProperty(SqlTreeProperties selectProps, STreeType desc, OrmQueryProperties queryProps, String propName) { if (subQuery) { - addPropertyToSubQuery(selectProps, desc, propName); + addPropertyToSubQuery(selectProps, desc, propName, queryProps.getPath()); return; } diff --git a/ebean-core/src/test/java/org/tests/query/TestQueryAlias.java b/ebean-core/src/test/java/org/tests/query/TestQueryAlias.java index de378586c..4e77d49d6 100644 --- a/ebean-core/src/test/java/org/tests/query/TestQueryAlias.java +++ b/ebean-core/src/test/java/org/tests/query/TestQueryAlias.java @@ -1,7 +1,7 @@ package org.tests.query; import io.ebean.BaseTestCase; -import io.ebean.Ebean; +import io.ebean.DB; import io.ebean.Query; import org.junit.Test; import org.tests.model.basic.CKeyParent; @@ -16,11 +16,11 @@ public class TestQueryAlias extends BaseTestCase { ResetBasicData.reset(); - Query sq = Ebean.createQuery(CKeyParent.class) + Query sq = DB.createQuery(CKeyParent.class) .select("id.oneKey").alias("st0") .setAutoTune(false).where().query(); - Query pq = Ebean.find(CKeyParent.class).alias("myt0").where().in("id.oneKey", sq).query(); + Query pq = DB.find(CKeyParent.class).alias("myt0").where().in("id.oneKey", sq).query(); pq.findList(); @@ -36,17 +36,36 @@ public class TestQueryAlias extends BaseTestCase { assertThat(sql).contains("ckey_parent myt0"); assertThat(sql).contains("(myt0.one_key) in (select st0.one_key from ckey_parent st0)"); } + + @Test + public void testExistsWithConcat() { + + ResetBasicData.reset(); + + Query sq = DB.createQuery(CKeyParent.class) + .select("concat(id.oneKey,id.twoKey)").alias("st0") + .setAutoTune(false).where().query(); + + Query pq = DB.find(CKeyParent.class).alias("myt0").where().in("concat(id.oneKey,id.twoKey)", sq).query(); + + pq.findList(); + + String sql = pq.getGeneratedSql(); + + assertThat(sql).contains("ckey_parent myt0"); + assertThat(sql).contains("(concat(myt0.one_key,myt0.two_key)) in (select concat(st0.one_key,st0.two_key) from ckey_parent st0)"); + } @Test public void testNotExists() { ResetBasicData.reset(); - Query sq = Ebean.createQuery(CKeyParent.class) + Query sq = DB.createQuery(CKeyParent.class) .select("id.oneKey").alias("st0") .setAutoTune(false).where().query(); - Query pq = Ebean.find(CKeyParent.class).alias("myt0").where().notIn("id.oneKey", sq).query(); + Query pq = DB.find(CKeyParent.class).alias("myt0").where().notIn("id.oneKey", sq).query(); pq.findList(); From d08f7af1e0e03a3773eee88b82b1698e30ed43d8 Mon Sep 17 00:00:00 2001 From: Thomas Fellner Date: Tue, 10 Aug 2021 18:31:02 +0200 Subject: [PATCH 070/120] update ebean-ddl-generator version in ebean-core --- ebean-core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index 11aac552a..b99bf98fb 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -72,7 +72,7 @@ io.ebean ebean-ddl-generator - 12.9.4-RC1 + 12.11.0 test From 11e8e3696f7a0c17cefe2a467625f1cb2447d045 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 11 Aug 2021 12:24:36 +1200 Subject: [PATCH 071/120] BindParams does not need encryptionKey in equals/hashCode --- .../src/main/java/io/ebeaninternal/api/BindParams.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java index 3a81f2f0a..b3da53833 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java @@ -410,8 +410,7 @@ public class BindParams implements Serializable { @Override public int hashCode() { int hc = getClass().hashCode(); - hc = hc * 92821 + (encryptionKey ? 0 : 1); - hc = hc * 92821 + (isInParam ? 0 : 1); +`` hc = hc * 92821 + (isInParam ? 0 : 1); hc = hc * 92821 + (isOutParam ? 0 : 1); hc = hc * 92821 + (type); hc = hc * 92821 + (inValue == null ? 0 : inValue.hashCode()); @@ -423,8 +422,7 @@ public class BindParams implements Serializable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Param param = (Param) o; - return encryptionKey == param.encryptionKey && isInParam == param.isInParam && isOutParam == param.isOutParam - && type == param.type && Objects.equals(inValue, param.inValue); + return isInParam == param.isInParam && isOutParam == param.isOutParam && type == param.type && Objects.equals(inValue, param.inValue); } void queryBindHash(BindHash hash) { From fd2e542c0b90433140c41b3434cd0e84873f0643 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 11 Aug 2021 12:43:58 +1200 Subject: [PATCH 072/120] Change BindHash from interface to implementation, Delete unused server persist BindValues --- .../java/io/ebeaninternal/api/BindHash.java | 42 ++++------ .../java/io/ebeaninternal/api/BindParams.java | 2 +- .../server/persist/BindValues.java | 81 ------------------- .../ebeaninternal/server/persist/Binder.java | 27 ------- .../server/querydefn/DefaultOrmQuery.java | 3 +- .../server/querydefn/HashCodeBindHash.java | 63 --------------- .../server/expression/RawExpressionTest.java | 4 +- ...odeBindHashTest.java => BindHashTest.java} | 13 +-- .../server/querydefn/DefaultOrmQueryTest.java | 3 +- 9 files changed, 28 insertions(+), 210 deletions(-) delete mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/persist/BindValues.java delete mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java rename ebean-core/src/test/java/io/ebeaninternal/server/querydefn/{HashCodeBindHashTest.java => BindHashTest.java} (67%) diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java index d70c5f09d..b3ad8e49b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java @@ -1,37 +1,29 @@ package io.ebeaninternal.api; +import java.util.ArrayList; +import java.util.List; + /** * BindHash implementation. - * - * @author Roland Praml, FOCONIS AG - * */ -public interface BindHash { +public class BindHash { - /** - * Update with boolean value. - */ - BindHash update(boolean boolValue); + private final List values = new ArrayList<>(); - /** - * Update with int value. - */ - BindHash update(int intValue); + public BindHash update(Object value) { + values.add(value); + return this; + } - /** - * Update with long value. - */ - BindHash update(long longValue); + @Override + public boolean equals(Object obj) { + return obj instanceof BindHash && ((BindHash) obj).values.equals(values); + } - /** - * Update with object value. - */ - BindHash update(Object value); + @Override + public int hashCode() { + return values.hashCode(); + } - /** - * finishes the hash. May be used to compute internal state. After finish, no - * update method must be called - */ - void finish(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java index b3da53833..74e7dfa23 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java @@ -410,7 +410,7 @@ public class BindParams implements Serializable { @Override public int hashCode() { int hc = getClass().hashCode(); -`` hc = hc * 92821 + (isInParam ? 0 : 1); + hc = hc * 92821 + (isInParam ? 0 : 1); hc = hc * 92821 + (isOutParam ? 0 : 1); hc = hc * 92821 + (type); hc = hc * 92821 + (inValue == null ? 0 : inValue.hashCode()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BindValues.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BindValues.java deleted file mode 100644 index 6d71e8d79..000000000 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BindValues.java +++ /dev/null @@ -1,81 +0,0 @@ -package io.ebeaninternal.server.persist; - -import java.util.ArrayList; - -/** - * Holds a list of bind values for binding to a PreparedStatement. - */ -class BindValues { - - private final ArrayList list = new ArrayList<>(); - - /** - * Create with a Binder. - */ - public BindValues() { - } - - /** - * Add a bind value with its JDBC datatype. - * - * @param value the bind value - * @param dbType the type as per java.sql.Types - */ - public void add(Object value, int dbType, String name) { - list.add(new Value(value, dbType, name)); - } - - /** - * List of bind values. - */ - public ArrayList values() { - return list; - } - - /** - * A Value has additionally the JDBC data type. - */ - public static class Value { - - private final Object value; - - private final int dbType; - - private final String name; - - /** - * Create the value. - */ - Value(Object value, int dbType, String name) { - this.value = value; - this.dbType = dbType; - this.name = name; - } - - /** - * Return the type as per java.sql.Types. - */ - public int getDbType() { - return dbType; - } - - /** - * Return the value. - */ - public Object getValue() { - return value; - } - - /** - * Return the property name. - */ - public String getName() { - return name; - } - - @Override - public String toString() { - return String.valueOf(value); - } - } -} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/Binder.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/Binder.java index 1d94d7a81..600a7e21a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/Binder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/Binder.java @@ -77,33 +77,6 @@ public class Binder { return asOfStandardsBased; } - /** - * Bind the values to the Prepared Statement. - */ - public void bind(BindValues bindValues, DataBind dataBind, StringBuilder bindBuf) throws SQLException { - String logPrefix = ""; - ArrayList list = bindValues.values(); - for (BindValues.Value bindValue : list) { - Object val = bindValue.getValue(); - int dt = bindValue.getDbType(); - bindObject(dataBind, val, dt); - - if (bindBuf != null) { - bindBuf.append(logPrefix); - if (logPrefix.isEmpty()) { - logPrefix = ", "; - } - bindBuf.append(bindValue.getName()); - bindBuf.append("="); - if (isLob(dt)) { - bindBuf.append("[LOB]"); - } else { - bindBuf.append(val); - } - } - } - } - /** * Bind the parameters to the preparedStatement returning the bind log. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index e4735e32b..865b3184b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -1244,9 +1244,8 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { public HashQuery queryHash() { // calculateQueryPlanHash is called just after potential AutoTune tuning // so queryPlanHash is calculated well before this method is called - BindHash hash = new HashCodeBindHash(); + BindHash hash = new BindHash(); queryBindHash(hash); - hash.finish(); return new HashQuery(queryPlanKey, hash); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java deleted file mode 100644 index 9bc9c60fc..000000000 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/HashCodeBindHash.java +++ /dev/null @@ -1,63 +0,0 @@ -package io.ebeaninternal.server.querydefn; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import io.ebeaninternal.api.BindHash; - -/** - * HashCode builder that uses Object.hashCode for computing bind-hashes. - * This is a fast and lightweight implementation, but may produce collisions. - * - * @author Roland Praml, FOCONIS AG - */ -public class HashCodeBindHash implements BindHash { - - private final List values = new ArrayList<>(); - private int hashCode; - - @Override - public BindHash update(int intValue) { - values.add(intValue); - hashCode = hashCode * 92821 + intValue; - return this; - } - - @Override - public BindHash update(long longValue) { - values.add(longValue); - hashCode = hashCode * 92821 + Long.hashCode(longValue); - return this; - } - - @Override - public BindHash update(boolean boolValue) { - values.add(boolValue); - hashCode = hashCode * 92821 + Boolean.hashCode(boolValue); - return this; - } - - @Override - public BindHash update(Object value) { - values.add(value); - hashCode = hashCode * 92821 + Objects.hashCode(value); - return this; - } - - @Override - public void finish() { - // nothing to do - } - - @Override - public boolean equals(Object obj) { - return obj instanceof HashCodeBindHash && ((HashCodeBindHash) obj).values.equals(values); - } - - @Override - public int hashCode() { - return hashCode; - } - -} diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java index 6c608472f..99c7d7eec 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java @@ -4,7 +4,6 @@ import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; import io.ebeaninternal.api.BindHash; -import io.ebeaninternal.server.querydefn.HashCodeBindHash; public class RawExpressionTest extends BaseExpressionTest { @@ -71,9 +70,8 @@ public class RawExpressionTest extends BaseExpressionTest { } private int getHash(RawExpression query) { - BindHash hash = new HashCodeBindHash(); + BindHash hash = new BindHash(); query.queryBindHash(hash); - hash.finish(); return hash.hashCode(); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/HashCodeBindHashTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindHashTest.java similarity index 67% rename from ebean-core/src/test/java/io/ebeaninternal/server/querydefn/HashCodeBindHashTest.java rename to ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindHashTest.java index dea0a2e0c..a74f4432f 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/HashCodeBindHashTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindHashTest.java @@ -1,18 +1,19 @@ package io.ebeaninternal.server.querydefn; +import io.ebeaninternal.api.BindHash; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -public class HashCodeBindHashTest { +public class BindHashTest { @Test public void update_with_null() { - HashCodeBindHash hash = new HashCodeBindHash(); + BindHash hash = new BindHash(); hash.update(1).update(null).update("hello"); - HashCodeBindHash hash2 = new HashCodeBindHash(); + BindHash hash2 = new BindHash(); hash2.update(1).update(null).update("hello"); assertThat(hash).isEqualTo(hash2); @@ -21,13 +22,13 @@ public class HashCodeBindHashTest { @Test public void notEqual() { - HashCodeBindHash hash = new HashCodeBindHash(); + BindHash hash = new BindHash(); hash.update(1).update(null).update("hello"); - HashCodeBindHash hash2 = new HashCodeBindHash(); + BindHash hash2 = new BindHash(); hash2.update(1).update("hello"); - HashCodeBindHash hash3 = new HashCodeBindHash(); + BindHash hash3 = new BindHash(); hash2.update(1).update(null); assertThat(hash).isNotEqualTo(hash2); diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java index cb1738ba8..999459892 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java @@ -113,9 +113,8 @@ public class DefaultOrmQueryTest extends BaseTestCase { } private int getHash(DefaultOrmQuery query) { - BindHash hash = new HashCodeBindHash(); + BindHash hash = new BindHash(); query.queryBindHash(hash); - hash.finish(); return hash.hashCode(); } } From ec7c7048db86a677e85d4d066cd76f77cd1cc23a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 11 Aug 2021 13:19:44 +1200 Subject: [PATCH 073/120] Refactor rename BindHash to BindValuesKey --- .../java/io/ebeaninternal/api/BindHash.java | 29 -------------- .../java/io/ebeaninternal/api/BindParams.java | 12 +++--- .../io/ebeaninternal/api/BindValuesKey.java | 35 +++++++++++++++++ .../java/io/ebeaninternal/api/HashQuery.java | 12 +++--- .../io/ebeaninternal/api/SpiExpression.java | 2 +- .../java/io/ebeaninternal/api/SpiQuery.java | 2 +- .../expression/AbstractTextExpression.java | 4 +- .../expression/AllEqualsExpression.java | 10 ++--- .../expression/ArrayContainsExpression.java | 8 ++-- .../expression/ArrayIsEmptyExpression.java | 6 +-- .../server/expression/BetweenExpression.java | 6 +-- .../expression/BetweenPropertyExpression.java | 6 +-- .../server/expression/BitwiseExpression.java | 6 +-- .../CaseInsensitiveEqualExpression.java | 6 +-- .../expression/DefaultExampleExpression.java | 10 ++--- .../expression/DefaultExpressionList.java | 10 ++--- .../expression/ExistsQueryExpression.java | 6 +-- .../server/expression/IdExpression.java | 6 +-- .../server/expression/IdInExpression.java | 8 ++-- .../server/expression/InExpression.java | 8 ++-- .../server/expression/InPairsExpression.java | 8 ++-- .../server/expression/InQueryExpression.java | 6 +-- .../server/expression/InRangeExpression.java | 6 +-- .../server/expression/IsEmptyExpression.java | 4 +- .../server/expression/JsonPathExpression.java | 6 +-- .../server/expression/JunctionExpression.java | 6 +-- .../server/expression/LikeExpression.java | 6 +-- .../server/expression/LogicExpression.java | 6 +-- .../expression/NativeILikeExpression.java | 6 +-- .../NestedPathWrapperExpression.java | 6 +-- .../server/expression/NoopExpression.java | 4 +- .../server/expression/NotExpression.java | 6 +-- .../server/expression/NullExpression.java | 6 +-- .../server/expression/RawExpression.java | 8 ++-- .../server/expression/SimpleExpression.java | 6 +-- .../server/querydefn/DefaultOrmQuery.java | 18 ++++----- .../server/expression/RawExpressionTest.java | 14 +++---- .../server/querydefn/BindHashTest.java | 38 ------------------- .../server/querydefn/BindValuesKeyTest.java | 38 +++++++++++++++++++ .../server/querydefn/DefaultOrmQueryTest.java | 16 ++++---- 40 files changed, 204 insertions(+), 202 deletions(-) delete mode 100644 ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java create mode 100644 ebean-core/src/main/java/io/ebeaninternal/api/BindValuesKey.java delete mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindHashTest.java create mode 100644 ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindValuesKeyTest.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java deleted file mode 100644 index b3ad8e49b..000000000 --- a/ebean-core/src/main/java/io/ebeaninternal/api/BindHash.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.ebeaninternal.api; - -import java.util.ArrayList; -import java.util.List; - -/** - * BindHash implementation. - */ -public class BindHash { - - private final List values = new ArrayList<>(); - - public BindHash update(Object value) { - values.add(value); - return this; - } - - @Override - public boolean equals(Object obj) { - return obj instanceof BindHash && ((BindHash) obj).values.equals(values); - } - - @Override - public int hashCode() { - return values.hashCode(); - } - - -} diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java index 74e7dfa23..64a0a0287 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/BindParams.java @@ -50,10 +50,10 @@ public class BindParams implements Serializable { positionedParameters.clear(); } - public void queryBindHash(BindHash hash) { - hash.update(positionedParameters.size()); - for (Param positionedParameter : positionedParameters) { - positionedParameter.queryBindHash(hash); + public void queryBindHash(BindValuesKey key) { + key.add(positionedParameters.size()); + for (Param param : positionedParameters) { + param.queryBindHash(key); } } @@ -425,8 +425,8 @@ public class BindParams implements Serializable { return isInParam == param.isInParam && isOutParam == param.isOutParam && type == param.type && Objects.equals(inValue, param.inValue); } - void queryBindHash(BindHash hash) { - hash.update(isInParam).update(isOutParam).update(type).update(inValue); + void queryBindHash(BindValuesKey key) { + key.add(isInParam).add(isOutParam).add(type).add(inValue); } /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/BindValuesKey.java b/ebean-core/src/main/java/io/ebeaninternal/api/BindValuesKey.java new file mode 100644 index 000000000..4a6eac324 --- /dev/null +++ b/ebean-core/src/main/java/io/ebeaninternal/api/BindValuesKey.java @@ -0,0 +1,35 @@ +package io.ebeaninternal.api; + +import java.util.ArrayList; +import java.util.List; + +/** + * BindValues used for L2 query cache key matching. + *

+ * The equals/hashCode implementation must meet the requirement that the query bind values + * match for L2 query cache hit (given the query plan hash is already a match). + */ +public class BindValuesKey { + + private final List values = new ArrayList<>(); + + /** + * Add a bind value. + */ + public BindValuesKey add(Object value) { + values.add(value); + return this; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof BindValuesKey && ((BindValuesKey) obj).values.equals(values); + } + + @Override + public int hashCode() { + return values.hashCode(); + } + + +} diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/HashQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/HashQuery.java index 87241aedc..faddb7bee 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/HashQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/HashQuery.java @@ -6,15 +6,14 @@ package io.ebeaninternal.api; public class HashQuery { private final CQueryPlanKey planHash; - - private final BindHash bindHash; + private final BindValuesKey bindValuesKey; /** * Create the HashQuery. */ - public HashQuery(CQueryPlanKey planHash, BindHash bindHash) { + public HashQuery(CQueryPlanKey planHash, BindValuesKey bindValuesKey) { this.planHash = planHash; - this.bindHash = bindHash; + this.bindValuesKey = bindValuesKey; } @Override @@ -25,7 +24,7 @@ public class HashQuery { @Override public int hashCode() { int hc = 92821 * planHash.hashCode(); - hc = 92821 * hc + bindHash.hashCode(); + hc = 92821 * hc + bindValuesKey.hashCode(); return hc; } @@ -37,8 +36,7 @@ public class HashQuery { if (!(obj instanceof HashQuery)) { return false; } - HashQuery e = (HashQuery) obj; - return e.bindHash.equals(bindHash) && e.planHash.equals(planHash); + return e.bindValuesKey.equals(bindValuesKey) && e.planHash.equals(planHash); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java index 32c3a3518..00879e15d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java @@ -56,7 +56,7 @@ public interface SpiExpression extends Expression { /** * Return the hash value for the values that will be bound. */ - void queryBindHash(BindHash hash); + void queryBindHash(BindValuesKey key); /** * Return true if the expression is the same with respect to bind values. diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java index d8bae7503..2eae4506b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -635,7 +635,7 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod * query). *

*/ - void queryBindHash(BindHash hash); + void queryBindHash(BindValuesKey key); /** * Identifies queries that are exactly the same including bind variables. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java index d377e48dd..2a411675e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -38,7 +38,7 @@ public abstract class AbstractTextExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { + public void queryBindHash(BindValuesKey key) { // do nothing, only execute against document store }; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java index df9e6095b..be0791a12 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -123,13 +123,11 @@ class AllEqualsExpression extends NonPrepareExpression { } @Override - public void queryBindHash(BindHash hash) { - - hash.update(propMap.size()); + public void queryBindHash(BindValuesKey key) { + key.add(propMap.size()); for (Object value : propMap.values()) { - hash.update(value); + key.add(value); } - } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java index 3c200c046..1ca15f8f7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -50,10 +50,10 @@ public class ArrayContainsExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(values.length); + public void queryBindHash(BindValuesKey key) { + key.add(values.length); for (Object value : values) { - hash.update(value); + key.add(value); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java index 0249acabb..5b58be0b4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -34,8 +34,8 @@ public class ArrayIsEmptyExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(empty); + public void queryBindHash(BindValuesKey key) { + key.add(empty); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java index 37a3aab8f..27e7a5909 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -50,8 +50,8 @@ class BetweenExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(low()).update(high()); + public void queryBindHash(BindValuesKey key) { + key.add(low()).add(high()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java index 440dd5f1f..cdc199d70 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.util.SplitName; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -96,8 +96,8 @@ class BetweenPropertyExpression extends NonPrepareExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(val()); + public void queryBindHash(BindValuesKey key) { + key.add(val()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java index db1fa686d..20119b370 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -40,8 +40,8 @@ class BitwiseExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(flags).update(match); + public void queryBindHash(BindValuesKey key) { + key.add(flags).add(match); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java index 485d1b04f..ecefbe08a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.server.el.ElPropertyValue; @@ -70,8 +70,8 @@ class CaseInsensitiveEqualExpression extends AbstractValueExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(val()); + public void queryBindHash(BindValuesKey key) { + key.add(val()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java index 9149923e0..3c0e268b6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java @@ -5,7 +5,7 @@ import io.ebean.LikeType; import io.ebean.bean.EntityBean; import io.ebean.event.BeanQueryRequest; import io.ebean.util.SplitName; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -242,10 +242,10 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio * Return a hash for the actual bind values used. */ @Override - public void queryBindHash(BindHash hash) { - hash.update(list.size()); - for (SpiExpression aList : list) { - aList.queryBindHash(hash); + public void queryBindHash(BindValuesKey key) { + key.add(list.size()); + for (SpiExpression expr : list) { + expr.queryBindHash(key); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index b5f9c6ec1..6c47467f2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -26,7 +26,7 @@ import io.ebean.search.MultiMatch; import io.ebean.search.TextCommonTerms; import io.ebean.search.TextQueryString; import io.ebean.search.TextSimple; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -679,10 +679,10 @@ public class DefaultExpressionList implements SpiExpressionList { * Calculate a hash based on the expressions. */ @Override - public void queryBindHash(BindHash hash) { - hash.update(list.size()); - for (SpiExpression aList : list) { - aList.queryBindHash(hash); + public void queryBindHash(BindValuesKey key) { + key.add(list.size()); + for (SpiExpression expr : list) { + expr.queryBindHash(key); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java index b3fcf8ce0..9f1d1830d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiEbeanServer; @@ -92,8 +92,8 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress } @Override - public void queryBindHash(BindHash hash) { - subQuery.queryBindHash(hash); + public void queryBindHash(BindValuesKey key) { + subQuery.queryBindHash(key); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java index 904fbe9be..5c20e66b3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -78,8 +78,8 @@ class IdExpression extends NonPrepareExpression implements SpiExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(value); + public void queryBindHash(BindValuesKey key) { + key.add(value); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java index 390d0bebb..8dbceb419 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -134,10 +134,10 @@ public class IdInExpression extends NonPrepareExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(idCollection.size()); + public void queryBindHash(BindValuesKey key) { + key.add(idCollection.size()); for (Object elem : idCollection) { - hash.update(elem); + key.add(elem); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java index a5719f71a..bbc2bf7eb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java @@ -2,7 +2,7 @@ package io.ebeaninternal.server.expression; import io.ebean.bean.EntityBean; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -177,10 +177,10 @@ class InExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(bindValues.size()); + public void queryBindHash(BindValuesKey key) { + key.add(bindValues.size()); for (Object bindValue : bindValues) { - hash.update(bindValue); + key.add(bindValue); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java index a7079ae55..6f2aae853 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.expression; import io.ebean.Pairs; import io.ebean.Pairs.Entry; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -125,10 +125,10 @@ class InPairsExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(entries.size()); + public void queryBindHash(BindValuesKey key) { + key.add(entries.size()); for (Pairs.Entry entry : entries) { - hash.update(entry.getA()).update(entry.getB()); + key.add(entry.getA()).add(entry.getB()); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java index 619f7b715..769f83b84 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiEbeanServer; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -73,8 +73,8 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor } @Override - public void queryBindHash(BindHash hash) { - subQuery.queryBindHash(hash); + public void queryBindHash(BindValuesKey key) { + subQuery.queryBindHash(key); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java index abe0b7338..c8a8dc96f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -48,8 +48,8 @@ class InRangeExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(low()).update(high()); + public void queryBindHash(BindValuesKey key) { + key.add(low()).add(high()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java index bb65962b3..4ca943619 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -104,7 +104,7 @@ class IsEmptyExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { + public void queryBindHash(BindValuesKey key) { // no bind values } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java index 18e0aa924..d501068d9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -84,8 +84,8 @@ class JsonPathExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(value).update(upperValue); + public void queryBindHash(BindValuesKey key) { + key.add(value).add(upperValue); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 88614873d..75c17ba19 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -25,7 +25,7 @@ import io.ebean.search.MultiMatch; import io.ebean.search.TextCommonTerms; import io.ebean.search.TextQueryString; import io.ebean.search.TextSimple; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -216,9 +216,9 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression } @Override - public void queryBindHash(BindHash hash) { + public void queryBindHash(BindValuesKey key) { for (SpiExpression expr : exprList.internalList()) { - expr.queryBindHash(hash); + expr.queryBindHash(key); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java index 587e6064c..355cdfa3c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.LikeType; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.server.el.ElPropertyValue; @@ -71,8 +71,8 @@ class LikeExpression extends AbstractValueExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(strValue()); + public void queryBindHash(BindValuesKey key) { + key.add(strValue()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java index cbd487b3e..d6f7894e0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.expression; import io.ebean.Expression; import io.ebean.Junction; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -169,8 +169,8 @@ abstract class LogicExpression implements SpiExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(expOne).update(expTwo); + public void queryBindHash(BindValuesKey key) { + key.add(expOne).add(expTwo); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java index 8c51d2f5d..efb77d37a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.LikeType; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.server.el.ElPropertyValue; @@ -55,8 +55,8 @@ class NativeILikeExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(val); + public void queryBindHash(BindValuesKey key) { + key.add(val); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java index f3ed1badd..0931486af 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -80,8 +80,8 @@ class NestedPathWrapperExpression implements SpiExpression { } @Override - public void queryBindHash(BindHash hash) { - delegate.queryBindHash(hash); + public void queryBindHash(BindValuesKey key) { + delegate.queryBindHash(key); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java index 92180cea1..0a8a67f24 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -75,7 +75,7 @@ class NoopExpression implements SpiExpression { } @Override - public void queryBindHash(BindHash hash) { + public void queryBindHash(BindValuesKey key) { // no bind values } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java index e9df6d856..4d6a4aba1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java @@ -2,7 +2,7 @@ package io.ebeaninternal.server.expression; import io.ebean.Expression; import io.ebean.event.BeanQueryRequest; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.NaturalKeyQueryData; import io.ebeaninternal.api.SpiExpression; @@ -100,8 +100,8 @@ final class NotExpression implements SpiExpression { } @Override - public void queryBindHash(BindHash hash) { - exp.queryBindHash(hash); + public void queryBindHash(BindValuesKey key) { + exp.queryBindHash(key); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java index daded43cb..1ec123fda 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.expression; import io.ebean.util.SplitName; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -95,7 +95,7 @@ class NullExpression extends AbstractExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(notNull); + public void queryBindHash(BindValuesKey key) { + key.add(notNull); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java index 721d69b25..080f541b7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.expression; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.ManyWhereJoins; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; @@ -74,10 +74,10 @@ class RawExpression extends NonPrepareExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(values.length); + public void queryBindHash(BindValuesKey key) { + key.add(values.length); for (Object value : values) { - hash.update(value); + key.add(value); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java index e50d9856c..3e0db8707 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java @@ -5,7 +5,7 @@ import io.ebean.plugin.ExpressionPath; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.server.el.ElPropertyValue; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.NaturalKeyQueryData; import java.io.IOException; @@ -122,8 +122,8 @@ public class SimpleExpression extends AbstractValueExpression { } @Override - public void queryBindHash(BindHash hash) { - hash.update(value()); + public void queryBindHash(BindValuesKey key) { + key.add(value()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index 865b3184b..4508458b8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -1225,12 +1225,12 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { *

*/ @Override - public void queryBindHash(BindHash hash) { - hash.update(id); - if (whereExpressions != null) whereExpressions.queryBindHash(hash); - if (havingExpressions != null) havingExpressions.queryBindHash(hash); - if (bindParams != null) bindParams.queryBindHash(hash); - hash.update(asOf).update(versionsStart).update(versionsEnd); + public void queryBindHash(BindValuesKey key) { + key.add(id); + if (whereExpressions != null) whereExpressions.queryBindHash(key); + if (havingExpressions != null) havingExpressions.queryBindHash(key); + if (bindParams != null) bindParams.queryBindHash(key); + key.add(asOf).add(versionsStart).add(versionsEnd); } /** @@ -1244,9 +1244,9 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { public HashQuery queryHash() { // calculateQueryPlanHash is called just after potential AutoTune tuning // so queryPlanHash is calculated well before this method is called - BindHash hash = new BindHash(); - queryBindHash(hash); - return new HashQuery(queryPlanKey, hash); + BindValuesKey bindKey = new BindValuesKey(); + queryBindHash(bindKey); + return new HashQuery(queryPlanKey, bindKey); } @Override diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java index 99c7d7eec..3568a3bf6 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.expression; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; public class RawExpressionTest extends BaseExpressionTest { @@ -62,16 +62,16 @@ public class RawExpressionTest extends BaseExpressionTest { } public void assert_queryBindHash_isDifferent(RawExpression exp0, RawExpression exp1) { - assertThat(getHash(exp0)).isNotEqualTo(getHash(exp1)); + assertThat(bindKey(exp0)).isNotEqualTo(bindKey(exp1)); } public void assert_queryBindHash_isSame(RawExpression exp0, RawExpression exp1) { - assertThat(getHash(exp0)).isEqualTo(getHash(exp1)); + assertThat(bindKey(exp0)).isEqualTo(bindKey(exp1)); } - private int getHash(RawExpression query) { - BindHash hash = new BindHash(); - query.queryBindHash(hash); - return hash.hashCode(); + private BindValuesKey bindKey(RawExpression query) { + BindValuesKey bindValuesKey = new BindValuesKey(); + query.queryBindHash(bindValuesKey); + return bindValuesKey; } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindHashTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindHashTest.java deleted file mode 100644 index a74f4432f..000000000 --- a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindHashTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package io.ebeaninternal.server.querydefn; - -import io.ebeaninternal.api.BindHash; -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class BindHashTest { - - @Test - public void update_with_null() { - - BindHash hash = new BindHash(); - hash.update(1).update(null).update("hello"); - - BindHash hash2 = new BindHash(); - hash2.update(1).update(null).update("hello"); - - assertThat(hash).isEqualTo(hash2); - } - - @Test - public void notEqual() { - - BindHash hash = new BindHash(); - hash.update(1).update(null).update("hello"); - - BindHash hash2 = new BindHash(); - hash2.update(1).update("hello"); - - BindHash hash3 = new BindHash(); - hash2.update(1).update(null); - - assertThat(hash).isNotEqualTo(hash2); - assertThat(hash).isNotEqualTo(hash3); - assertThat(hash2).isNotEqualTo(hash3); - } -} diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindValuesKeyTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindValuesKeyTest.java new file mode 100644 index 000000000..1a7d3b39f --- /dev/null +++ b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/BindValuesKeyTest.java @@ -0,0 +1,38 @@ +package io.ebeaninternal.server.querydefn; + +import io.ebeaninternal.api.BindValuesKey; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class BindValuesKeyTest { + + @Test + public void update_with_null() { + + BindValuesKey hash = new BindValuesKey(); + hash.add(1).add(null).add("hello"); + + BindValuesKey hash2 = new BindValuesKey(); + hash2.add(1).add(null).add("hello"); + + assertThat(hash).isEqualTo(hash2); + } + + @Test + public void notEqual() { + + BindValuesKey hash = new BindValuesKey(); + hash.add(1).add(null).add("hello"); + + BindValuesKey hash2 = new BindValuesKey(); + hash2.add(1).add("hello"); + + BindValuesKey hash3 = new BindValuesKey(); + hash2.add(1).add(null); + + assertThat(hash).isNotEqualTo(hash2); + assertThat(hash).isNotEqualTo(hash3); + assertThat(hash2).isNotEqualTo(hash3); + } +} diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java index 999459892..b3b657c4a 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java @@ -4,7 +4,7 @@ package io.ebeaninternal.server.querydefn; import io.ebean.BaseTestCase; import io.ebean.CacheMode; import io.ebean.Ebean; -import io.ebeaninternal.api.BindHash; +import io.ebeaninternal.api.BindValuesKey; import io.ebeaninternal.api.SpiQuery; import io.ebeaninternal.server.core.OrmQueryRequest; import org.junit.Test; @@ -63,7 +63,7 @@ public class DefaultOrmQueryTest extends BaseTestCase { prepare(q1, q2); assertThat(q1.createQueryPlanKey()).isNotEqualTo(q2.createQueryPlanKey()); - assertThat(getHash(q1)).isNotEqualTo(getHash(q2)); + assertThat(bindKey(q1)).isNotEqualTo(bindKey(q2)); } @Test @@ -74,7 +74,7 @@ public class DefaultOrmQueryTest extends BaseTestCase { prepare(q1, q2); assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey()); - assertThat(getHash(q1)).isNotEqualTo(getHash(q2)); + assertThat(bindKey(q1)).isNotEqualTo(bindKey(q2)); } @Test @@ -85,7 +85,7 @@ public class DefaultOrmQueryTest extends BaseTestCase { prepare(q1, q2); assertThat(q1.createQueryPlanKey()).isEqualTo(q2.createQueryPlanKey()); - assertThat(getHash(q1)).isEqualTo(getHash(q2)); + assertThat(bindKey(q1)).isEqualTo(bindKey(q2)); } @Test @@ -112,9 +112,9 @@ public class DefaultOrmQueryTest extends BaseTestCase { q2.prepare(r2); } - private int getHash(DefaultOrmQuery query) { - BindHash hash = new BindHash(); - query.queryBindHash(hash); - return hash.hashCode(); + private BindValuesKey bindKey(DefaultOrmQuery query) { + BindValuesKey key = new BindValuesKey(); + query.queryBindHash(key); + return key; } } From 144a3b54bb51d804712a086a0e1921eceb1faf86 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 11 Aug 2021 13:25:04 +1200 Subject: [PATCH 074/120] Refactor rename method queryBindHash() to queryBindKey() --- .../java/io/ebeaninternal/api/SpiExpression.java | 4 ++-- .../main/java/io/ebeaninternal/api/SpiQuery.java | 8 +++----- .../server/expression/AbstractTextExpression.java | 2 +- .../server/expression/AllEqualsExpression.java | 2 +- .../server/expression/ArrayContainsExpression.java | 2 +- .../server/expression/ArrayIsEmptyExpression.java | 2 +- .../server/expression/BetweenExpression.java | 2 +- .../expression/BetweenPropertyExpression.java | 2 +- .../server/expression/BitwiseExpression.java | 2 +- .../expression/CaseInsensitiveEqualExpression.java | 2 +- .../expression/DefaultExampleExpression.java | 7 ++----- .../server/expression/DefaultExpressionList.java | 7 ++----- .../server/expression/ExistsQueryExpression.java | 4 ++-- .../server/expression/IdExpression.java | 2 +- .../server/expression/IdInExpression.java | 2 +- .../server/expression/InExpression.java | 2 +- .../server/expression/InPairsExpression.java | 2 +- .../server/expression/InQueryExpression.java | 4 ++-- .../server/expression/InRangeExpression.java | 2 +- .../server/expression/IsEmptyExpression.java | 2 +- .../server/expression/JsonPathExpression.java | 2 +- .../server/expression/JunctionExpression.java | 4 ++-- .../server/expression/LikeExpression.java | 2 +- .../server/expression/LogicExpression.java | 2 +- .../server/expression/NativeILikeExpression.java | 2 +- .../expression/NestedPathWrapperExpression.java | 4 ++-- .../server/expression/NoopExpression.java | 2 +- .../server/expression/NotExpression.java | 4 ++-- .../server/expression/NullExpression.java | 2 +- .../server/expression/RawExpression.java | 2 +- .../server/expression/SimpleExpression.java | 2 +- .../server/querydefn/DefaultOrmQuery.java | 14 ++++---------- .../server/expression/RawExpressionTest.java | 2 +- .../server/querydefn/DefaultOrmQueryTest.java | 2 +- 34 files changed, 47 insertions(+), 61 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java index 00879e15d..8fe986259 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiExpression.java @@ -54,9 +54,9 @@ public interface SpiExpression extends Expression { void queryPlanHash(StringBuilder builder); /** - * Return the hash value for the values that will be bound. + * Build the key for bind values of the query. */ - void queryBindHash(BindValuesKey key); + void queryBindKey(BindValuesKey key); /** * Return true if the expression is the same with respect to bind values. diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java index 2eae4506b..5ba0b6eeb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -629,13 +629,11 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod CQueryPlanKey prepare(SpiOrmQueryRequest request); /** - * Calculate a hash based on the bind values used in the query. + * Build the key for the bind values used in the query (for l2 query cache). *

- * Combined with queryPlanHash() to return getQueryHash (a unique hash for a - * query). - *

+ * Combined with queryPlanHash() to return queryHash (a unique key for a query). */ - void queryBindHash(BindValuesKey key); + void queryBindKey(BindValuesKey key); /** * Identifies queries that are exactly the same including bind variables. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java index 2a411675e..363bcb08d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java @@ -38,7 +38,7 @@ public abstract class AbstractTextExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { // do nothing, only execute against document store }; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java index be0791a12..56761dcf2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java @@ -123,7 +123,7 @@ class AllEqualsExpression extends NonPrepareExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(propMap.size()); for (Object value : propMap.values()) { key.add(value); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java index 1ca15f8f7..7a9e903f6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java @@ -50,7 +50,7 @@ public class ArrayContainsExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(values.length); for (Object value : values) { key.add(value); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java index 5b58be0b4..f9cd530c8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java @@ -34,7 +34,7 @@ public class ArrayIsEmptyExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(empty); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java index 27e7a5909..ed3d58d8b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java @@ -50,7 +50,7 @@ class BetweenExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(low()).add(high()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java index cdc199d70..55b08380d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java @@ -96,7 +96,7 @@ class BetweenPropertyExpression extends NonPrepareExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(val()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java index 20119b370..460af37ec 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java @@ -40,7 +40,7 @@ class BitwiseExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(flags).add(match); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java index ecefbe08a..3a6224d9c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java @@ -70,7 +70,7 @@ class CaseInsensitiveEqualExpression extends AbstractValueExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(val()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java index 3c0e268b6..e6353edd0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java @@ -238,14 +238,11 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio builder.append("]"); } - /** - * Return a hash for the actual bind values used. - */ @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(list.size()); for (SpiExpression expr : list) { - expr.queryBindHash(key); + expr.queryBindKey(key); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index 6c47467f2..97899f091 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -675,14 +675,11 @@ public class DefaultExpressionList implements SpiExpressionList { builder.append("]"); } - /** - * Calculate a hash based on the expressions. - */ @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(list.size()); for (SpiExpression expr : list) { - expr.queryBindHash(key); + expr.queryBindKey(key); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java index 9f1d1830d..4ba939066 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java @@ -92,8 +92,8 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress } @Override - public void queryBindHash(BindValuesKey key) { - subQuery.queryBindHash(key); + public void queryBindKey(BindValuesKey key) { + subQuery.queryBindKey(key); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java index 5c20e66b3..94cab6de7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java @@ -78,7 +78,7 @@ class IdExpression extends NonPrepareExpression implements SpiExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(value); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java index 8dbceb419..edf56b443 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java @@ -134,7 +134,7 @@ public class IdInExpression extends NonPrepareExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(idCollection.size()); for (Object elem : idCollection) { key.add(elem); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java index bbc2bf7eb..0bc5a4588 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java @@ -177,7 +177,7 @@ class InExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(bindValues.size()); for (Object bindValue : bindValues) { key.add(bindValue); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java index 6f2aae853..e5bd27413 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java @@ -125,7 +125,7 @@ class InPairsExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(entries.size()); for (Pairs.Entry entry : entries) { key.add(entry.getA()).add(entry.getB()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java index 769f83b84..48647d0c2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java @@ -73,8 +73,8 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor } @Override - public void queryBindHash(BindValuesKey key) { - subQuery.queryBindHash(key); + public void queryBindKey(BindValuesKey key) { + subQuery.queryBindKey(key); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java index c8a8dc96f..04b242ba8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java @@ -48,7 +48,7 @@ class InRangeExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(low()).add(high()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java index 4ca943619..d6b878bfa 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java @@ -104,7 +104,7 @@ class IsEmptyExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { // no bind values } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java index d501068d9..1d954dcc1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java @@ -84,7 +84,7 @@ class JsonPathExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(value).add(upperValue); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 75c17ba19..a253bbb2b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -216,9 +216,9 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { for (SpiExpression expr : exprList.internalList()) { - expr.queryBindHash(key); + expr.queryBindKey(key); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java index 355cdfa3c..f40501929 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java @@ -71,7 +71,7 @@ class LikeExpression extends AbstractValueExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(strValue()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java index d6f7894e0..a66e2e88a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java @@ -169,7 +169,7 @@ abstract class LogicExpression implements SpiExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(expOne).add(expTwo); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java index efb77d37a..f64933df5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java @@ -55,7 +55,7 @@ class NativeILikeExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(val); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java index 0931486af..b76bfef4d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java @@ -80,8 +80,8 @@ class NestedPathWrapperExpression implements SpiExpression { } @Override - public void queryBindHash(BindValuesKey key) { - delegate.queryBindHash(key); + public void queryBindKey(BindValuesKey key) { + delegate.queryBindKey(key); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java index 0a8a67f24..6c8d709e7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java @@ -75,7 +75,7 @@ class NoopExpression implements SpiExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { // no bind values } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java index 4d6a4aba1..462e60d9e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NotExpression.java @@ -100,8 +100,8 @@ final class NotExpression implements SpiExpression { } @Override - public void queryBindHash(BindValuesKey key) { - exp.queryBindHash(key); + public void queryBindKey(BindValuesKey key) { + exp.queryBindKey(key); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java index 1ec123fda..2808acce7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java @@ -95,7 +95,7 @@ class NullExpression extends AbstractExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(notNull); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java index 080f541b7..9e1c3e8dc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java @@ -74,7 +74,7 @@ class RawExpression extends NonPrepareExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(values.length); for (Object value : values) { key.add(value); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java index 3e0db8707..bc23b84f2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java @@ -122,7 +122,7 @@ public class SimpleExpression extends AbstractValueExpression { } @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(value()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index 4508458b8..834abb856 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -1218,17 +1218,11 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { } } - /** - * Calculate a hash based on the bind values used in the query. - *

- * Used with queryPlanHash() to get a unique hash for a query. - *

- */ @Override - public void queryBindHash(BindValuesKey key) { + public void queryBindKey(BindValuesKey key) { key.add(id); - if (whereExpressions != null) whereExpressions.queryBindHash(key); - if (havingExpressions != null) havingExpressions.queryBindHash(key); + if (whereExpressions != null) whereExpressions.queryBindKey(key); + if (havingExpressions != null) havingExpressions.queryBindKey(key); if (bindParams != null) bindParams.queryBindHash(key); key.add(asOf).add(versionsStart).add(versionsEnd); } @@ -1245,7 +1239,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { // calculateQueryPlanHash is called just after potential AutoTune tuning // so queryPlanHash is calculated well before this method is called BindValuesKey bindKey = new BindValuesKey(); - queryBindHash(bindKey); + queryBindKey(bindKey); return new HashQuery(queryPlanKey, bindKey); } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java index 3568a3bf6..eb12ff460 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/expression/RawExpressionTest.java @@ -71,7 +71,7 @@ public class RawExpressionTest extends BaseExpressionTest { private BindValuesKey bindKey(RawExpression query) { BindValuesKey bindValuesKey = new BindValuesKey(); - query.queryBindHash(bindValuesKey); + query.queryBindKey(bindValuesKey); return bindValuesKey; } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java index b3b657c4a..b2b4902ad 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/querydefn/DefaultOrmQueryTest.java @@ -114,7 +114,7 @@ public class DefaultOrmQueryTest extends BaseTestCase { private BindValuesKey bindKey(DefaultOrmQuery query) { BindValuesKey key = new BindValuesKey(); - query.queryBindHash(key); + query.queryBindKey(key); return key; } } From c267366578b7877313f87569b503e77f331a6d8b Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 11 Aug 2021 15:32:54 +1200 Subject: [PATCH 075/120] Refactor tidy internals - aList -> expr in for loops etc. No functional change. --- .../io/ebeaninternal/api/LoadBeanRequest.java | 13 +------ .../server/core/DefaultServer.java | 12 +++--- .../deploy/meta/DeployBeanDescriptor.java | 6 +-- .../expression/DefaultExampleExpression.java | 16 +++----- .../expression/DefaultExpressionList.java | 38 ++++++++----------- .../server/expression/JunctionExpression.java | 5 +-- 6 files changed, 33 insertions(+), 57 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/LoadBeanRequest.java b/ebean-core/src/main/java/io/ebeaninternal/api/LoadBeanRequest.java index fef666a63..9d72463a5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/LoadBeanRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/LoadBeanRequest.java @@ -92,9 +92,7 @@ public class LoadBeanRequest extends LoadRequest { * Return the list of Id values for the beans in the lazy load buffer. */ public List getIdList() { - List idList = new ArrayList<>(); - BeanDescriptor desc = loadBuffer.getBeanDescriptor(); for (EntityBeanIntercept ebi : batch) { idList.add(desc.getId(ebi.getOwner())); @@ -106,10 +104,8 @@ public class LoadBeanRequest extends LoadRequest { * Configure the query for lazy loading execution. */ public void configureQuery(SpiQuery query, List idList) { - query.setMode(SpiQuery.Mode.LAZYLOAD_BEAN); query.setPersistenceContext(loadBuffer.getPersistenceContext()); - String mode = isLazy() ? "+lazy" : "+query"; query.setLoadDescription(mode, getDescription()); @@ -117,9 +113,7 @@ public class LoadBeanRequest extends LoadRequest { // cascade the batch size (if set) for further lazy loading query.setLazyLoadBatchSize(getBatchSize()); } - loadBuffer.configureQuery(query, lazyLoadProperty); - if (idList.size() == 1) { query.where().idEq(idList.get(0)); } else { @@ -131,19 +125,16 @@ public class LoadBeanRequest extends LoadRequest { * Load the beans into the L2 cache if that is requested and check for load failures due to deletes. */ public void postLoad(List list) { - Set loadedIds = new HashSet<>(); - BeanDescriptor desc = loadBuffer.getBeanDescriptor(); // collect Ids and maybe load bean cache - for (Object aList : list) { - EntityBean loadedBean = (EntityBean) aList; + for (Object bean : list) { + EntityBean loadedBean = (EntityBean) bean; loadedIds.add(desc.getId(loadedBean)); } if (isLoadCache()) { desc.cacheBeanPutAll(list); } - if (lazyLoadProperty != null) { for (EntityBeanIntercept ebi : batch) { // check if the underlying row in DB was deleted. Mark the bean as 'failed' if diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index 2040e3f78..4f0eed00b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -2055,17 +2055,15 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { return transactionManager; } - public void register(BeanPersistController c) { - List> list = beanDescriptorManager.getBeanDescriptorList(); - for (BeanDescriptor aList : list) { - aList.register(c); + public void register(BeanPersistController controller) { + for (BeanDescriptor desc : beanDescriptorManager.getBeanDescriptorList()) { + desc.register(controller); } } public void deregister(BeanPersistController c) { - List> list = beanDescriptorManager.getBeanDescriptorList(); - for (BeanDescriptor aList : list) { - aList.deregister(c); + for (BeanDescriptor desc : beanDescriptorManager.getBeanDescriptorList()) { + desc.deregister(c); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java index 79ca0beb1..f0184948e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java @@ -702,13 +702,11 @@ public class DeployBeanDescriptor { } public void sortProperties() { - ArrayList list = new ArrayList<>(propMap.values()); list.sort(PROP_ORDER); - propMap = new LinkedHashMap<>(list.size()); - for (DeployBeanProperty aList : list) { - addBeanProperty(aList); + for (DeployBeanProperty property : list) { + addBeanProperty(property); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java index e6353edd0..cd8a59857 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java @@ -137,10 +137,8 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio @Override public void containsMany(BeanDescriptor desc, ManyWhereJoins whereManyJoins) { list = buildExpressions(desc); - if (list != null) { - for (SpiExpression aList : list) { - aList.containsMany(desc, whereManyJoins); - } + for (SpiExpression expr : list) { + expr.containsMany(desc, whereManyJoins); } } @@ -187,8 +185,8 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio @Override public void validate(SpiExpressionValidation validation) { - for (SpiExpression aList : list) { - aList.validate(validation); + for (SpiExpression expr : list) { + expr.validate(validation); } } @@ -229,10 +227,9 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio */ @Override public void queryPlanHash(StringBuilder builder) { - builder.append("Example["); - for (SpiExpression aList : list) { - aList.queryPlanHash(builder); + for (SpiExpression expr : list) { + expr.queryPlanHash(builder); builder.append(","); } builder.append("]"); @@ -264,7 +261,6 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio * Build the List of expressions. */ private ArrayList buildExpressions(BeanDescriptor beanDescriptor) { - ArrayList list = new ArrayList<>(); addExpressions(list, beanDescriptor, entity, null); return list; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index 97899f091..ed3f57e14 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -110,10 +110,8 @@ public class DefaultExpressionList implements SpiExpressionList { * @return A single SpiExpression that has the nestedPath set */ SpiExpression wrap(List list, String nestedPath, Junction.Type type) { - DefaultExpressionList wrapper = new DefaultExpressionList<>(query, expr, null, list, false); wrapper.setAllDocNested(nestedPath); - if (type != null) { return new JunctionExpression<>(type, wrapper); } else { @@ -122,15 +120,15 @@ public class DefaultExpressionList implements SpiExpressionList { } void simplifyEntries() { - for (SpiExpression element : list) { - element.simplify(); + for (SpiExpression expr : list) { + expr.simplify(); } } @Override public void prefixProperty(String path) { - for (SpiExpression exp : list) { - exp.prefixProperty(path); + for (SpiExpression expr : list) { + expr.prefixProperty(path); } } @@ -175,7 +173,6 @@ public class DefaultExpressionList implements SpiExpressionList { context.startNested(allDocNestedPath); } int size = list.size(); - SpiExpression first = list.get(0); boolean explicitBool = first instanceof SpiJunction; boolean implicitBool = !explicitBool && size > 1; @@ -211,7 +208,6 @@ public class DefaultExpressionList implements SpiExpressionList { @Override public void writeDocQuery(DocQueryContext context, SpiExpression idEquals) throws IOException { - if (allDocNestedPath != null) { context.startNested(allDocNestedPath); } @@ -228,8 +224,8 @@ public class DefaultExpressionList implements SpiExpressionList { if (idEquals != null) { idEquals.writeDocQuery(context); } - for (SpiExpression aList : list) { - aList.writeDocQuery(context); + for (SpiExpression expr : list) { + expr.writeDocQuery(context); } context.endBool(); } @@ -279,16 +275,15 @@ public class DefaultExpressionList implements SpiExpressionList { */ @Override public void containsMany(BeanDescriptor desc, ManyWhereJoins whereManyJoins) { - - for (SpiExpression aList : list) { - aList.containsMany(desc, whereManyJoins); + for (SpiExpression expr : list) { + expr.containsMany(desc, whereManyJoins); } } @Override public void validate(SpiExpressionValidation validation) { - for (SpiExpression aList : list) { - aList.validate(validation); + for (SpiExpression expr : list) { + expr.validate(validation); } } @@ -631,7 +626,6 @@ public class DefaultExpressionList implements SpiExpressionList { @Override public void addSql(SpiExpressionRequest request) { - for (int i = 0, size = list.size(); i < size; i++) { SpiExpression expression = list.get(i); if (i > 0) { @@ -643,15 +637,15 @@ public class DefaultExpressionList implements SpiExpressionList { @Override public void addBindValues(SpiExpressionRequest request) { - for (SpiExpression aList : list) { - aList.addBindValues(request); + for (SpiExpression expr : list) { + expr.addBindValues(request); } } @Override public void prepareExpression(BeanQueryRequest request) { - for (SpiExpression aList : list) { - aList.prepareExpression(request); + for (SpiExpression expr : list) { + expr.prepareExpression(request); } } @@ -668,8 +662,8 @@ public class DefaultExpressionList implements SpiExpressionList { if (allDocNestedPath != null) { builder.append("path:").append(allDocNestedPath).append(" "); } - for (SpiExpression aList : list) { - aList.queryPlanHash(builder); + for (SpiExpression expr : list) { + expr.queryPlanHash(builder); builder.append(","); } builder.append("]"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index a253bbb2b..5637fba7f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -207,9 +207,8 @@ class JunctionExpression implements SpiJunction, SpiExpression, Expression @Override public void queryPlanHash(StringBuilder builder) { builder.append(type).append("["); - List list = exprList.internalList(); - for (SpiExpression aList : list) { - aList.queryPlanHash(builder); + for (SpiExpression expr : exprList.internalList()) { + expr.queryPlanHash(builder); builder.append(","); } builder.append("]"); From f50f0192d155bd1cb71b1a5b369a481d75fffe32 Mon Sep 17 00:00:00 2001 From: Thomas Fellner Date: Wed, 11 Aug 2021 08:47:49 +0200 Subject: [PATCH 076/120] Switch DB2 driver to the publicly available JCC driver --- ebean-core/pom.xml | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index b99bf98fb..5324aec82 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -20,22 +20,13 @@ - db2 + - com.ibm.jdbc - db2jcc4 - 4.23.42 + com.ibm.db2 + jcc + 11.5.5.0 test From 1a2aba3f56df9c4d58e3e18f1498693492115b66 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Wed, 11 Aug 2021 08:54:40 +0200 Subject: [PATCH 077/120] Distinguish between exists and in subquery --- .../server/autotune/service/BaseQueryTuner.java | 3 ++- .../main/java/io/ebeaninternal/api/SpiEbeanServer.java | 3 ++- .../src/main/java/io/ebeaninternal/api/SpiQuery.java | 9 +++++++-- .../io/ebeaninternal/server/core/DefaultServer.java | 4 ++-- .../server/expression/ExistsQueryExpression.java | 3 ++- .../server/expression/InQueryExpression.java | 3 ++- .../java/io/ebeaninternal/server/query/SqlTree.java | 1 + .../io/ebeaninternal/server/query/SqlTreeBuilder.java | 10 +++++++++- .../server/querydefn/DefaultOrmQuery.java | 5 +++-- .../java/io/ebeaninternal/api/TDSpiEbeanServer.java | 6 +++--- .../org/tests/query/cancel/SqlQueryCancelTest.java | 8 ++++---- 11 files changed, 37 insertions(+), 18 deletions(-) diff --git a/ebean-autotune/src/main/java/io/ebeaninternal/server/autotune/service/BaseQueryTuner.java b/ebean-autotune/src/main/java/io/ebeaninternal/server/autotune/service/BaseQueryTuner.java index af969fd53..b93be5cc8 100644 --- a/ebean-autotune/src/main/java/io/ebeaninternal/server/autotune/service/BaseQueryTuner.java +++ b/ebean-autotune/src/main/java/io/ebeaninternal/server/autotune/service/BaseQueryTuner.java @@ -146,7 +146,8 @@ public class BaseQueryTuner { case ID_LIST: case UPDATE: case DELETE: - case SUBQUERY: + case SQ_EXISTS: + case SQ_IN: return false; default: // not using autoTune when explicitly loading the l2 bean cache diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java index daf6418d0..fae60f49d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiEbeanServer.java @@ -8,6 +8,7 @@ import io.ebean.config.dbplatform.DatabasePlatform; import io.ebean.event.readaudit.ReadAuditLogger; import io.ebean.event.readaudit.ReadAuditPrepare; import io.ebean.meta.MetricVisitor; +import io.ebeaninternal.api.SpiQuery.Type; import io.ebeaninternal.server.core.SpiResultSet; import io.ebeaninternal.server.core.timezone.DataTimeZone; import io.ebeaninternal.server.deploy.BeanDescriptor; @@ -149,7 +150,7 @@ public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanCollect /** * Compile a query. */ - CQuery compileQuery(Query query, Transaction t); + CQuery compileQuery(Type type, Query query, Transaction t); /** * Execute the findId's query but without copying the query. diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java index 5ba0b6eeb..12a25fed8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -92,9 +92,14 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod COUNT(FIND_COUNT, "findCount"), /** - * A subquery used as part of a where clause. + * A subquery used as part of an exists where clause. */ - SUBQUERY(FIND_SUBQUERY, "subquery"), + SQ_EXISTS(FIND_SUBQUERY, "sqExists"), + + /** + * A subquery used as part of an in where clause. + */ + SQ_IN(FIND_SUBQUERY, "sqIn"), /** * Delete query. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index 4f0eed00b..c52befdcc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -526,8 +526,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { * Compile a query. Only valid for ORM queries. */ @Override - public CQuery compileQuery(Query query, Transaction t) { - SpiOrmQueryRequest qr = createQueryRequest(Type.SUBQUERY, query, t); + public CQuery compileQuery(Type type, Query query, Transaction t) { + SpiOrmQueryRequest qr = createQueryRequest(type, query, t); OrmQueryRequest orm = (OrmQueryRequest) qr; return cqueryEngine.buildQuery(orm); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java index 4ba939066..71ca665fe 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java @@ -9,6 +9,7 @@ import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.api.SpiExpressionValidation; import io.ebeaninternal.api.SpiQuery; +import io.ebeaninternal.api.SpiQuery.Type; import io.ebeaninternal.server.deploy.BeanDescriptor; import io.ebeaninternal.server.query.CQuery; @@ -82,7 +83,7 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress */ protected CQuery compileSubQuery(BeanQueryRequest queryRequest) { SpiEbeanServer ebeanServer = (SpiEbeanServer) queryRequest.getEbeanServer(); - return ebeanServer.compileQuery(subQuery, queryRequest.getTransaction()); + return ebeanServer.compileQuery(Type.SQ_EXISTS, subQuery, queryRequest.getTransaction()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java index 48647d0c2..a2d6d787c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java @@ -6,6 +6,7 @@ import io.ebeaninternal.api.SpiEbeanServer; import io.ebeaninternal.api.SpiExpression; import io.ebeaninternal.api.SpiExpressionRequest; import io.ebeaninternal.api.SpiQuery; +import io.ebeaninternal.api.SpiQuery.Type; import io.ebeaninternal.server.query.CQuery; import java.io.IOException; @@ -69,7 +70,7 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor private CQuery compileSubQuery(BeanQueryRequest queryRequest) { SpiEbeanServer ebeanServer = (SpiEbeanServer) queryRequest.getEbeanServer(); - return ebeanServer.compileQuery(subQuery, queryRequest.getTransaction()); + return ebeanServer.compileQuery(Type.SQ_IN, subQuery, queryRequest.getTransaction()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTree.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTree.java index 1befa650b..5f548fd59 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTree.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTree.java @@ -101,6 +101,7 @@ class SqlTree { * Return the String for the actual SQL. */ String getSelectSql() { + assert selectSql != null : "selectSql was null"; return selectSql; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java index 06465355c..a344244c4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java @@ -102,7 +102,11 @@ public final class SqlTreeBuilder { this.query = request.getQuery(); this.temporalMode = SpiQuery.TemporalMode.of(query); this.disableLazyLoad = query.isDisableLazyLoading(); - this.subQuery = Type.SUBQUERY == query.getType() || Type.ID_LIST == query.getType() || Type.DELETE == query.getType() || query.isCountDistinct(); + this.subQuery = Type.SQ_EXISTS == query.getType() + || Type.SQ_IN == query.getType() + || Type.ID_LIST == query.getType() + || Type.DELETE == query.getType() + || query.isCountDistinct(); this.includeJoin = query.getM2mIncludeJoin(); this.manyWhereJoins = query.getManyWhereJoins(); this.queryDetail = query.getDetail(); @@ -146,6 +150,10 @@ public final class SqlTreeBuilder { if (rawSql) { return "Not Used"; } + if (query.getType() ==Type.SQ_EXISTS) { + // effective query is "where exists (select 1 from ...)" + return "1"; + } rootNode.appendSelect(ctx, subQuery); return trimComma(ctx.getContent()); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index db3a605ea..dea84fb80 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -565,7 +565,8 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { * Limit the number of fetch joins to Many properties, mark as query joins as needed. */ private void markQueryJoins() { - detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), type != Type.ATTRIBUTE && type != Type.SUBQUERY); + detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), + type != Type.ATTRIBUTE && type != Type.SQ_EXISTS && type != Type.SQ_IN); } private boolean isAllowOneManyFetch() { @@ -578,7 +579,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { @Override public void setDefaultSelectClause() { - if (type != Type.ATTRIBUTE && type != Type.SUBQUERY) { + if (type != Type.ATTRIBUTE && type != Type.SQ_EXISTS && type != Type.SQ_IN) { detail.setDefaultSelectClause(beanDescriptor); } else if (!detail.hasSelectClause()) { // explicit empty select when single attribute query on non-root fetch path diff --git a/ebean-core/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java b/ebean-core/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java index b09a0f54e..cb7e613a3 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java +++ b/ebean-core/src/test/java/io/ebeaninternal/api/TDSpiEbeanServer.java @@ -45,6 +45,7 @@ import io.ebean.plugin.Property; import io.ebean.plugin.SpiServer; import io.ebean.text.csv.CsvReader; import io.ebean.text.json.JsonContext; +import io.ebeaninternal.api.SpiQuery.Type; import io.ebeaninternal.server.core.SpiResultSet; import io.ebeaninternal.server.core.timezone.DataTimeZone; import io.ebeaninternal.server.deploy.BeanDescriptor; @@ -54,7 +55,6 @@ import io.ebeaninternal.server.transaction.RemoteTransactionEvent; import javax.persistence.OptimisticLockException; import javax.persistence.PersistenceException; import javax.sql.DataSource; -import java.lang.reflect.Type; import java.time.Clock; import java.util.Collection; import java.util.Collections; @@ -256,7 +256,7 @@ public class TDSpiEbeanServer implements SpiEbeanServer { } @Override - public CQuery compileQuery(Query query, Transaction t) { + public CQuery compileQuery(Type type, Query query, Transaction t) { return null; } @@ -316,7 +316,7 @@ public class TDSpiEbeanServer implements SpiEbeanServer { } @Override - public boolean isSupportedType(Type genericType) { + public boolean isSupportedType(java.lang.reflect.Type genericType) { return false; } diff --git a/ebean-core/src/test/java/org/tests/query/cancel/SqlQueryCancelTest.java b/ebean-core/src/test/java/org/tests/query/cancel/SqlQueryCancelTest.java index 9fc3d6b57..5fedc53e0 100644 --- a/ebean-core/src/test/java/org/tests/query/cancel/SqlQueryCancelTest.java +++ b/ebean-core/src/test/java/org/tests/query/cancel/SqlQueryCancelTest.java @@ -113,8 +113,8 @@ public class SqlQueryCancelTest extends BaseTestCase { doCancelOrmAtBegin(Query::findOne); doCancelOrmAtBegin(q -> q.setMaxRows(1000).findPagedList().getList()); // untested doCancelOrmAtBegin(Query::findSet); - doCancelOrmAtBegin(Query::findSingleAttribute); - doCancelOrmAtBegin(Query::findSingleAttributeList); + doCancelOrmAtBegin(q -> q.select("name").findSingleAttribute()); + doCancelOrmAtBegin(q -> q.select("name").findSingleAttributeList()); doCancelOrmAtBegin(Query::findStream); // testDuringRun(Query::findVersions); // EBasic has no history support, but it should work if @History is added @@ -138,8 +138,8 @@ public class SqlQueryCancelTest extends BaseTestCase { // findOne cannot be tested, as H2 does the cancel check every 128 rows only doCancelOrmDuringRun(q -> q.setMaxRows(1000).findPagedList().getList()); // untested doCancelOrmDuringRun(Query::findSet); - doCancelOrmDuringRun(Query::findSingleAttribute); - doCancelOrmDuringRun(Query::findSingleAttributeList); + doCancelOrmDuringRun(q -> q.select("name").findSingleAttribute()); + doCancelOrmDuringRun(q -> q.select("name").findSingleAttributeList()); doCancelOrmDuringRun(Query::findStream); // testDuringRun(Query::findVersions); // EBasic has no history support, but it should work if @History is added From 2d240202022ab1e00033aebdd0f278d401aee4a0 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Wed, 11 Aug 2021 09:32:21 +0200 Subject: [PATCH 078/120] Added / enhanced test case --- .../server/query/SqlTreeBuilder.java | 2 +- .../java/org/tests/query/TestQueryExists.java | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java index a344244c4..65fa4f7f8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java @@ -150,7 +150,7 @@ public final class SqlTreeBuilder { if (rawSql) { return "Not Used"; } - if (query.getType() ==Type.SQ_EXISTS) { + if (query.getType() == Type.SQ_EXISTS) { // effective query is "where exists (select 1 from ...)" return "1"; } diff --git a/ebean-core/src/test/java/org/tests/query/TestQueryExists.java b/ebean-core/src/test/java/org/tests/query/TestQueryExists.java index 93155bf9a..f885852b7 100644 --- a/ebean-core/src/test/java/org/tests/query/TestQueryExists.java +++ b/ebean-core/src/test/java/org/tests/query/TestQueryExists.java @@ -1,7 +1,7 @@ package org.tests.query; import io.ebean.BaseTestCase; -import io.ebean.Ebean; +import io.ebean.DB; import io.ebean.Query; import io.ebeantest.LoggedSql; @@ -21,7 +21,7 @@ public class TestQueryExists extends BaseTestCase { ResetBasicData.reset(); - Query query = Ebean.find(Order.class) + Query query = DB.find(Order.class) .where().gt("id", 1) .query(); @@ -34,8 +34,8 @@ public class TestQueryExists extends BaseTestCase { assertThat(sql).contains("select t0.id from o_order t0 where t0.id > ? limit 1"); } - assertThat(Ebean.find(Order.class).where().gt("id", 1).exists()).isTrue(); - assertThat(Ebean.find(Order.class).where().or().gt("id", 1).isNull("shipDate").exists()).isTrue(); + assertThat(DB.find(Order.class).where().gt("id", 1).exists()).isTrue(); + assertThat(DB.find(Order.class).where().or().gt("id", 1).isNull("shipDate").exists()).isTrue(); } @Test @@ -43,13 +43,13 @@ public class TestQueryExists extends BaseTestCase { ResetBasicData.reset(); - Query query = Ebean.find(Order.class) + Query query = DB.find(Order.class) .where().raw("exists (select 1 from o_order_detail where order_id = t0.id)") .query(); List ordersThatHave = query.findList(); - Query query2 = Ebean.find(Order.class) + Query query2 = DB.find(Order.class) .where().raw("not exists (select 1 from o_order_detail where order_id = t0.id)") .query(); @@ -67,13 +67,13 @@ public class TestQueryExists extends BaseTestCase { ResetBasicData.reset(); - Query query = Ebean.find(Customer.class) + Query query = DB.find(Customer.class) .where().raw("exists (select 1 from contact where customer_id = t0.id)") .query(); List customersWithContacts = query.findList(); - Query query2 = Ebean.find(Customer.class) + Query query2 = DB.find(Customer.class) .where().raw("not exists (select 1 FROM contact where customer_id = t0.id)") .query(); @@ -89,26 +89,26 @@ public class TestQueryExists extends BaseTestCase { public void testExists() { ResetBasicData.reset(); - Query subQuery = Ebean.find(Order.class).alias("sq").select("id").where().raw("sq.kcustomer_id = qt.id").query(); + Query subQuery = DB.find(Order.class).alias("sq").select("id").where().raw("sq.kcustomer_id = qt.id").query(); - Query query = Ebean.find(Customer.class).alias("qt").where().exists(subQuery).query(); + Query query = DB.find(Customer.class).alias("qt").where().exists(subQuery).query(); query.findList(); String sql = query.getGeneratedSql(); - assertThat(sql).contains("exists ("); + assertThat(sql).contains("exists (select 1 from"); } @Test public void testNotExists() { ResetBasicData.reset(); - Query subQuery = Ebean.find(Order.class).alias("sq").select("id").where().raw("sq.kcustomer_id = qt.id").query(); - Query query = Ebean.find(Customer.class).alias("qt").where().notExists(subQuery).query(); + Query subQuery = DB.find(Order.class).alias("sq").where().raw("sq.kcustomer_id = qt.id").query(); + Query query = DB.find(Customer.class).alias("qt").where().notExists(subQuery).query(); query.findList(); String sql = query.getGeneratedSql(); - assertThat(sql).contains("not exists ("); + assertThat(sql).contains("not exists (select 1 from"); } } From b676476cd257b70f74f60419a093bf3d1972956b Mon Sep 17 00:00:00 2001 From: rbygrave Date: Wed, 11 Aug 2021 20:51:46 +1200 Subject: [PATCH 079/120] Add SpiQuery.Type.defaultSelect() for ATTRIBUTE and sub-query type queries --- .../java/io/ebeaninternal/api/SpiQuery.java | 21 +++++++++---- .../server/query/CQueryBuilder.java | 30 ------------------- .../server/querydefn/DefaultOrmQuery.java | 5 ++-- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java index 12a25fed8..5a6ae2217 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiQuery.java @@ -84,7 +84,7 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod /** * Find single attribute. */ - ATTRIBUTE(FIND_ATTRIBUTE, "findAttribute"), + ATTRIBUTE(FIND_ATTRIBUTE, "findAttribute", false, false), /** * Find rowCount. @@ -94,12 +94,12 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod /** * A subquery used as part of an exists where clause. */ - SQ_EXISTS(FIND_SUBQUERY, "sqExists"), + SQ_EXISTS(FIND_SUBQUERY, "sqExists", false, false), /** * A subquery used as part of an in where clause. */ - SQ_IN(FIND_SUBQUERY, "sqIn"), + SQ_IN(FIND_SUBQUERY, "sqIn", false, false), /** * Delete query. @@ -112,17 +112,21 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod UPDATE(FIND_UPDATE, "update", true); private final boolean update; + private final boolean defaultSelect; private final String profileEventId; private final String label; Type(String profileEventId, String label) { - this(profileEventId, label, false); + this(profileEventId, label, false, true); } - Type(String profileEventId, String label, boolean update) { + this(profileEventId, label, update, true); + } + Type(String profileEventId, String label, boolean update, boolean defaultSelect) { this.profileEventId = profileEventId; this.label = label; this.update = update; + this.defaultSelect = defaultSelect; } /** @@ -132,6 +136,13 @@ public interface SpiQuery extends Query, SpiQueryFetch, TxnProfileEventCod return update; } + /** + * Return true if this allows default select clause. + */ + public boolean defaultSelect() { + return defaultSelect; + } + public String profileEventId() { return profileEventId; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java index 41439e4b6..9a4b1d32e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java @@ -46,9 +46,7 @@ class CQueryBuilder { private final SqlLimiter sqlLimiter; private final CQueryBuilderRawSql rawSqlHandler; private final Binder binder; - private final boolean selectCountWithAlias; - private final CQueryHistorySupport historySupport; private final CQueryDraftSupport draftSupport; private final DatabasePlatform dbPlatform; @@ -79,7 +77,6 @@ class CQueryBuilder { if (sb.length() > 0) { sb.append(", "); } - sb.append(name); sb.append("."); sb.append(token.trim()); @@ -91,7 +88,6 @@ class CQueryBuilder { * Build the delete query. */ CQueryUpdate buildUpdateQuery(boolean deleteRequest, OrmQueryRequest request) { - SpiQuery query = request.getQuery(); String rootTableAlias = query.getAlias(); query.setupForDeleteOrUpdate(); @@ -105,7 +101,6 @@ class CQueryBuilder { } predicates.prepare(true); - SqlTree sqlTree = createSqlTree(request, predicates); String sql; @@ -114,7 +109,6 @@ class CQueryBuilder { } else { sql = buildUpdateSql(request, rootTableAlias, predicates, sqlTree); } - // cache the query plan queryPlan = new CQueryPlan(request, sql, sqlTree, predicates.getLogWhereSql()); request.putQueryPlan(queryPlan); @@ -122,7 +116,6 @@ class CQueryBuilder { } private String buildDeleteSql(OrmQueryRequest request, String rootTableAlias, CQueryPredicates predicates, SqlTree sqlTree) { - String alias = alias(rootTableAlias); if (sqlTree.noJoins() && !request.getQuery().hasMaxRowsOrFirstRow()) { if (dbPlatform.isSupportsDeleteTableAlias()) { @@ -151,7 +144,6 @@ class CQueryBuilder { } private String buildUpdateSql(OrmQueryRequest request, String rootTableAlias, CQueryPredicates predicates, SqlTree sqlTree) { - StringBuilder sb = new StringBuilder(200); sb.append("update ").append(request.getBeanDescriptor().getBaseTable()); if (rootTableAlias != null) { @@ -159,7 +151,6 @@ class CQueryBuilder { } sb.append(" set ").append(predicates.getDbUpdateClause()); String updateClause = sb.toString(); - if (sqlTree.noJoins() && request.isInlineSqlUpdateLimit()) { // simple - update table set ... where ... return aliasStrip(buildSqlUpdate(updateClause, request, predicates, sqlTree).getSql()); @@ -186,7 +177,6 @@ class CQueryBuilder { } CQueryFetchSingleAttribute buildFetchAttributeQuery(OrmQueryRequest request) { - SpiQuery query = request.getQuery(); query.setSingleAttribute(); if (!query.isIncludeSoftDeletes()) { @@ -218,7 +208,6 @@ class CQueryBuilder { * Build the find ids query. */ CQueryFetchSingleAttribute buildFetchIdsQuery(OrmQueryRequest request) { - SpiQuery query = request.getQuery(); query.setSelectId(); BeanDescriptor desc = request.getBeanDescriptor(); @@ -246,9 +235,7 @@ class CQueryBuilder { * Build the row count query. */ CQueryRowCount buildRowCountQuery(OrmQueryRequest request) { - SpiQuery query = request.getQuery(); - // always set the order by to null for row count query query.setOrder(null); query.setFirstRow(0); @@ -310,7 +297,6 @@ class CQueryBuilder { // cache the query plan queryPlan = new CQueryPlan(request, sql, sqlTree, predicates.getLogWhereSql()); request.putQueryPlan(queryPlan); - return new CQueryRowCount(queryPlan, request, predicates); } @@ -334,9 +320,7 @@ class CQueryBuilder { * names to physical deployment column names. */ CQuery buildQuery(OrmQueryRequest request) { - CQueryPredicates predicates = new CQueryPredicates(binder, request); - CQueryPlan queryPlan = request.getQueryPlan(); if (queryPlan != null) { // Reuse the query plan so skip generating SqlTree and SQL. @@ -370,7 +354,6 @@ class CQueryBuilder { boolean rawSql = request.isRawSql(); if (rawSql) { queryPlan = new CQueryPlanRawSql(request, res, sqlTree, predicates.getLogWhereSql()); - } else { queryPlan = new CQueryPlan(request, res, sqlTree, false, predicates.getLogWhereSql()); } @@ -380,11 +363,9 @@ class CQueryBuilder { // log the query plan based bean type (i.e. ignoring query disabling for logging the sql/plan) desc.getReadAuditLogger().queryPlan(new ReadAuditQueryPlan(desc.getFullName(), queryPlan.getAuditQueryKey(), queryPlan.getSql())); } - // cache the query plan because we can reuse it and also // gather query performance statistics based on it. request.putQueryPlan(queryPlan); - return new CQuery<>(request, predicates, queryPlan); } @@ -393,18 +374,15 @@ class CQueryBuilder { *

* The SqlTree is immutable after construction and so is safe to use by * concurrent threads. - *

*

* The predicates is used to add additional joins that come from the where or * order by clauses that are not already included for the select clause. - *

*/ private SqlTree createSqlTree(OrmQueryRequest request, CQueryPredicates predicates) { return createSqlTree(request, predicates, false); } private SqlTree createSqlTree(OrmQueryRequest request, CQueryPredicates predicates, boolean forceColumnAlias) { - if (request.isNativeSql()) { return createNativeSqlTree(request, predicates); } @@ -423,9 +401,7 @@ class CQueryBuilder { * Create the SqlTree by reading the ResultSetMetaData and mapping table/columns to bean property paths. */ private SqlTree createNativeSqlTree(OrmQueryRequest request, CQueryPredicates predicates) { - SpiQuery query = request.getQuery(); - // parse named parameters returning the final sql to execute String sql = predicates.parseBindParams(query.getNativeSql()); if (query.hasMaxRowsOrFirstRow()) { @@ -469,10 +445,8 @@ class CQueryBuilder { } private SqlTree createRawSqlSqlTree(OrmQueryRequest request, CQueryPredicates predicates) { - BeanDescriptor descriptor = request.getBeanDescriptor(); ColumnMapping columnMapping = request.getQuery().getRawSql().getColumnMapping(); - PathProperties pathProps = new PathProperties(); // convert list of columns into (tree like) PathProperties @@ -498,12 +472,10 @@ class CQueryBuilder { } OrmQueryDetail detail = new OrmQueryDetail(); - // transfer PathProperties into OrmQueryDetail for (PathProperties.Props props : pathProps.getPathProps()) { detail.fetch(props.getPath(), props.getProperties()); } - // check if @Id property included in RawSql boolean rawNoId = true; BeanProperty idProperty = descriptor.getIdProperty(); @@ -511,7 +483,6 @@ class CQueryBuilder { // contains the @Id property for the root level bean rawNoId = false; } - // build SqlTree based on OrmQueryDetail of the RawSql return new SqlTreeBuilder(request, predicates, detail, rawNoId).build(); } @@ -603,7 +574,6 @@ class CQueryBuilder { private void appendSelect() { if (selectClause != null) { sb.append(selectClause); - } else { useSqlLimiter = (query.hasMaxRowsOrFirstRow() && select.getManyProperty() == null); if (!useSqlLimiter) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index dea84fb80..b5aeec323 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -565,8 +565,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { * Limit the number of fetch joins to Many properties, mark as query joins as needed. */ private void markQueryJoins() { - detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), - type != Type.ATTRIBUTE && type != Type.SQ_EXISTS && type != Type.SQ_IN); + detail.markQueryJoins(beanDescriptor, lazyLoadManyPath, isAllowOneManyFetch(), type.defaultSelect()); } private boolean isAllowOneManyFetch() { @@ -579,7 +578,7 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { @Override public void setDefaultSelectClause() { - if (type != Type.ATTRIBUTE && type != Type.SQ_EXISTS && type != Type.SQ_IN) { + if (type.defaultSelect()) { detail.setDefaultSelectClause(beanDescriptor); } else if (!detail.hasSelectClause()) { // explicit empty select when single attribute query on non-root fetch path From c51140b59aadbfa83f5d39b9f3a73eb5a3ae7fbc Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 12 Aug 2021 13:01:07 +1200 Subject: [PATCH 080/120] Add DefaultServer.toString() and tidy DbOffline remove unnecessary log message --- ebean-core/src/main/java/io/ebeaninternal/api/DbOffline.java | 5 ----- .../java/io/ebeaninternal/server/core/DefaultServer.java | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/DbOffline.java b/ebean-core/src/main/java/io/ebeaninternal/api/DbOffline.java index 3c5ca5a7b..9e184ad61 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/DbOffline.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/DbOffline.java @@ -1,8 +1,6 @@ package io.ebeaninternal.api; import io.ebean.annotation.Platform; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Helper to indicate that an EbeanServer should come up offline @@ -10,8 +8,6 @@ import org.slf4j.LoggerFactory; */ public class DbOffline { - private static final Logger logger = LoggerFactory.getLogger(DbOffline.class); - private static final String KEY = "ebean.dboffline"; private static boolean generateMigration; @@ -73,7 +69,6 @@ public class DbOffline { public static void reset() { generateMigration = false; System.clearProperty(KEY); - logger.debug("reset"); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index c52befdcc..1c77e06a8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -490,6 +490,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { } } + @Override + public String toString() { + return "Database{" + serverName + "}"; + } + /** * Return the server name. */ From eeacad0fb987735a82c45b0c7788232900f27bbb Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 12 Aug 2021 14:36:14 +1200 Subject: [PATCH 081/120] #2307 - ENH: Add DatabaseFactory.disableShutdownHook() ... [ alias for ShutdownManager.deregisterShutdownHook() ] --- .../main/java/io/ebean/DatabaseFactory.java | 23 +++++++-- .../java/io/ebean/event/ShutdownManager.java | 22 ++++----- .../server/lib/ShutdownManagerTest.java | 48 +++++++++++++++++++ 3 files changed, 78 insertions(+), 15 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/DatabaseFactory.java b/ebean-api/src/main/java/io/ebean/DatabaseFactory.java index 4aace866a..8dbf05fd0 100644 --- a/ebean-api/src/main/java/io/ebean/DatabaseFactory.java +++ b/ebean-api/src/main/java/io/ebean/DatabaseFactory.java @@ -2,6 +2,7 @@ package io.ebean; import io.ebean.config.ContainerConfig; import io.ebean.config.DatabaseConfig; +import io.ebean.event.ShutdownManager; import io.ebean.service.SpiContainer; import io.ebean.service.SpiContainerFactory; @@ -16,18 +17,15 @@ import java.util.concurrent.locks.ReentrantLock; *

* This uses either DatabaseConfig or properties in the application.properties file to * configure and create a Database instance. - *

*

* The Database instance can either be registered with the DB singleton or * not. The DB singleton effectively holds a map of Database by a name. * If the Database is registered with the DB singleton you can retrieve it * later via {@link DB#byName(String)}. - *

*

* One Database can be nominated as the 'default/primary' Database. Many * methods on the DB singleton such as {@link DB#find(Class)} are just a * convenient way of using the 'default/primary' Database. - *

*/ public class DatabaseFactory { @@ -68,6 +66,16 @@ public class DatabaseFactory { /** * Create using the DatabaseConfig object to configure the database. + * + *
{@code
+   *
+   *   DatabaseConfig config = new DatabaseConfig();
+   *   config.setName("db");
+   *   config.loadProperties();
+   *
+   *   Database database = DatabaseFactory.create(config);
+   *
+   * }
*/ public static Database create(DatabaseConfig config) { lock.lock(); @@ -115,7 +123,6 @@ public class DatabaseFactory { * Shutdown gracefully all Database instances cleaning up any resources as required. *

* This is typically invoked via JVM shutdown hook and not explicitly called. - *

*/ public static void shutdown() { lock.lock(); @@ -126,6 +133,14 @@ public class DatabaseFactory { } } + /** + * Removes the JVM shutdown hook and means the application must shut down ebean + * explicitly using {@link DatabaseFactory#shutdown()}. + */ + public static void disableShutdownHook() { + ShutdownManager.deregisterShutdownHook(); + } + private static Database createInternal(DatabaseConfig config) { return getContainer(config.getContainerConfig()).createServer(config); } diff --git a/ebean-api/src/main/java/io/ebean/event/ShutdownManager.java b/ebean-api/src/main/java/io/ebean/event/ShutdownManager.java index f762b0084..4011683ca 100644 --- a/ebean-api/src/main/java/io/ebean/event/ShutdownManager.java +++ b/ebean-api/src/main/java/io/ebean/event/ShutdownManager.java @@ -14,10 +14,9 @@ import java.util.List; import java.util.concurrent.locks.ReentrantLock; /** - * Manages the shutdown of the JVM Runtime. + * Manages the shutdown of Ebean. *

* Makes sure all the resources are shutdown properly and in order. - *

*/ public final class ShutdownManager { @@ -44,6 +43,9 @@ public final class ShutdownManager { private ShutdownManager() { } + /** + * Registers the container (potentially with cluster management). + */ public static void registerContainer(SpiContainer ebeanContainer) { container = ebeanContainer; } @@ -94,7 +96,7 @@ public final class ShutdownManager { /** * Register the shutdown hook with the Runtime. */ - protected static void registerShutdownHook() { + private static void registerShutdownHook() { lock.lock(); try { String value = System.getProperty("ebean.registerShutdownHook"); @@ -123,13 +125,10 @@ public final class ShutdownManager { // Already run shutdown... return; } - if (logger.isDebugEnabled()) { logger.debug("Shutting down"); } - stopping = true; - deregisterShutdownHook(); String shutdownRunner = System.getProperty("ebean.shutdown.runnable"); @@ -147,7 +146,6 @@ public final class ShutdownManager { // shutdown cluster networking if active container.shutdown(); } - // shutdown any registered servers that have not // already been shutdown manually for (Database server : databases) { @@ -158,7 +156,6 @@ public final class ShutdownManager { ex.printStackTrace(); } } - if ("true".equalsIgnoreCase(System.getProperty("ebean.datasource.deregisterAllDrivers", "false"))) { deregisterAllJdbcDrivers(); } @@ -168,15 +165,15 @@ public final class ShutdownManager { } private static void deregisterAllJdbcDrivers() { - // This manually deregisters all JDBC drivers + // This manually de-registers all JDBC drivers Enumeration drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { Driver driver = drivers.nextElement(); try { - logger.info("Deregistering jdbc driver: " + driver); + logger.info("De-registering jdbc driver: " + driver); DriverManager.deregisterDriver(driver); } catch (SQLException e) { - logger.error("Error deregistering driver " + driver, e); + logger.error("Error de-registering driver " + driver, e); } } } @@ -209,6 +206,9 @@ public final class ShutdownManager { } private static class ShutdownHook extends Thread { + private ShutdownHook() { + super("EbeanHook"); + } @Override public void run() { ShutdownManager.shutdown(); diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/lib/ShutdownManagerTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/lib/ShutdownManagerTest.java index e5f8c3853..f643597ed 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/lib/ShutdownManagerTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/lib/ShutdownManagerTest.java @@ -2,12 +2,60 @@ package io.ebeaninternal.server.lib; import io.ebean.BaseTestCase; import io.ebean.DB; +import io.ebean.Database; +import io.ebean.DatabaseFactory; import io.ebean.event.ShutdownManager; import org.junit.Ignore; import org.junit.Test; public class ShutdownManagerTest extends BaseTestCase { + /** + * Run this test manually. Most typical when we want the application code to control shutdown. + */ + @Ignore + @Test + public void test_disableShutdownHook_shutdownManually() { + // disable hook to make sure app code controls when shutdown is executed + DatabaseFactory.disableShutdownHook(); + DB.getDefault(); + + System.out.println("shutdown manually ... "); + // application code explicitly calls shutdown() + DatabaseFactory.shutdown(); + } + + /** + * Run this test manually. + */ + @Ignore + @Test + public void test_shutdownHook() { + DB.getDefault(); // shutdown fired via shutdown hook, default behaviour + } + + /** + * Run this test manually. + */ + @Ignore + @Test + public void test_disableShutdownHook() { + DB.getDefault(); + DatabaseFactory.disableShutdownHook(); // no shutdown is run here (not great, don't do this) + } + + /** + * Run this test manually. + */ + @Ignore + @Test + public void test_shutdownManually() { + DB.getDefault(); + System.out.println("shutdown manually ... "); + // note this removes the shutdown hook, only "useful" if it runs BEFORE a JVM shutdown is invoked (hook invoked) + DatabaseFactory.shutdown(); + } + /** * Run this test manually. */ From a17683c549adc153981399d0f61c0d7ca36aa9c5 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 12 Aug 2021 16:32:12 +1200 Subject: [PATCH 082/120] #2307 - Tidy ShutdownManager DatabaseFactory only --- .../main/java/io/ebean/DatabaseFactory.java | 19 +++++-------------- .../server/lib/ShutdownManagerTest.java | 6 +++--- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/DatabaseFactory.java b/ebean-api/src/main/java/io/ebean/DatabaseFactory.java index 8dbf05fd0..588f48c24 100644 --- a/ebean-api/src/main/java/io/ebean/DatabaseFactory.java +++ b/ebean-api/src/main/java/io/ebean/DatabaseFactory.java @@ -2,7 +2,6 @@ package io.ebean; import io.ebean.config.ContainerConfig; import io.ebean.config.DatabaseConfig; -import io.ebean.event.ShutdownManager; import io.ebean.service.SpiContainer; import io.ebean.service.SpiContainerFactory; @@ -46,7 +45,7 @@ public class DatabaseFactory { public static void initialiseContainer(ContainerConfig containerConfig) { lock.lock(); try { - getContainer(containerConfig); + container(containerConfig); } finally { lock.unlock(); } @@ -58,7 +57,7 @@ public class DatabaseFactory { public static Database create(String name) { lock.lock(); try { - return getContainer(null).createServer(name); + return container(null).createServer(name); } finally { lock.unlock(); } @@ -133,24 +132,16 @@ public class DatabaseFactory { } } - /** - * Removes the JVM shutdown hook and means the application must shut down ebean - * explicitly using {@link DatabaseFactory#shutdown()}. - */ - public static void disableShutdownHook() { - ShutdownManager.deregisterShutdownHook(); - } - private static Database createInternal(DatabaseConfig config) { - return getContainer(config.getContainerConfig()).createServer(config); + return container(config.getContainerConfig()).createServer(config); } /** - * Get the EbeanContainer initialising it if necessary. + * Return the SpiContainer initialising it if necessary. * * @param containerConfig the configuration controlling clustering communication */ - private static SpiContainer getContainer(ContainerConfig containerConfig) { + private static SpiContainer container(ContainerConfig containerConfig) { // thread safe in that all calling methods hold lock if (container != null) { return container; diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/lib/ShutdownManagerTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/lib/ShutdownManagerTest.java index f643597ed..c48756ed7 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/lib/ShutdownManagerTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/lib/ShutdownManagerTest.java @@ -17,12 +17,12 @@ public class ShutdownManagerTest extends BaseTestCase { @Test public void test_disableShutdownHook_shutdownManually() { // disable hook to make sure app code controls when shutdown is executed - DatabaseFactory.disableShutdownHook(); + ShutdownManager.deregisterShutdownHook(); DB.getDefault(); System.out.println("shutdown manually ... "); // application code explicitly calls shutdown() - DatabaseFactory.shutdown(); + ShutdownManager.shutdown(); } /** @@ -41,7 +41,7 @@ public class ShutdownManagerTest extends BaseTestCase { @Test public void test_disableShutdownHook() { DB.getDefault(); - DatabaseFactory.disableShutdownHook(); // no shutdown is run here (not great, don't do this) + ShutdownManager.deregisterShutdownHook(); // no shutdown is run here (not great, don't do this) } /** From fc7379aabc56b1697872df9c34fffb46fa7a1ea6 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Fri, 13 Aug 2021 09:18:31 +1200 Subject: [PATCH 083/120] Tidy internals - server.persist.dml package for whitespace and typos --- .../server/persist/PstmtFactory.java | 5 --- .../server/persist/dml/DeleteHandler.java | 2 -- .../server/persist/dml/DeleteMeta.java | 8 +---- .../server/persist/dml/DmlBeanPersister.java | 6 ---- .../persist/dml/DmlBeanPersisterFactory.java | 3 -- .../server/persist/dml/DmlHandler.java | 18 ---------- .../persist/dml/GenerateDmlRequest.java | 5 --- .../server/persist/dml/InsertHandler.java | 28 +++------------ .../server/persist/dml/InsertMeta.java | 21 +++--------- .../server/persist/dml/MetaFactory.java | 19 +++-------- .../server/persist/dml/UpdateHandler.java | 5 --- .../server/persist/dml/UpdateMeta.java | 11 ------ .../server/persist/dml/UpdatePlan.java | 34 ------------------- 13 files changed, 14 insertions(+), 151 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/PstmtFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/PstmtFactory.java index cf8b294df..14b24dd3b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/PstmtFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/PstmtFactory.java @@ -56,7 +56,6 @@ class PstmtFactory { if (t.isLogSql()) { t.logSql(TrimLogSql.trim(sql)); } - Connection conn = t.getInternalConnection(); PreparedStatement stmt = conn.prepareStatement(sql); BatchedPstmt bs = new BatchedPstmt(stmt, false, sql, t); @@ -68,10 +67,8 @@ class PstmtFactory { * Return a callable statement taking into account batch requirements. */ CallableStatement getCstmtBatch(SpiTransaction t, boolean logSql, String sql, BatchPostExecute batchExe) throws SQLException { - BatchedPstmtHolder batch = t.getBatchControl().getPstmtHolder(); CallableStatement stmt = (CallableStatement) batch.getStmt(sql, batchExe); - if (stmt != null) { return stmt; } @@ -79,10 +76,8 @@ class PstmtFactory { if (logSql) { t.logSql(sql); } - Connection conn = t.getInternalConnection(); stmt = conn.prepareCall(sql); - BatchedPstmt bs = new BatchedPstmt(stmt, false, sql, t); batch.addStmt(bs, batchExe); return stmt; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteHandler.java index 7889e94af..9320a49fa 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteHandler.java @@ -29,10 +29,8 @@ public class DeleteHandler extends DmlHandler { */ @Override public void bind() throws SQLException { - sql = meta.getSql(persistRequest); SpiTransaction t = persistRequest.getTransaction(); - PreparedStatement pstmt; if (persistRequest.isBatched()) { pstmt = getPstmtBatch(t, sql, persistRequest, false); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteMeta.java index c51a62531..ccb196947 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteMeta.java @@ -41,9 +41,7 @@ final class DeleteMeta extends BaseMeta { * Bind the request based on the concurrency mode. */ public void bind(PersistRequestBean persist, DmlHandler bind) throws SQLException { - EntityBean bean = persist.getEntityBean(); - id.dmlBind(bind, bean); if (tenantId != null) { tenantId.dmlBind(bind, bean); @@ -58,7 +56,6 @@ final class DeleteMeta extends BaseMeta { * get or generate the sql based on the concurrency mode. */ public String getSql(PersistRequestBean request) { - if (id.isEmpty()) { throw new IllegalStateException("Can not deleteById on " + request.getFullName() + " as no @Id property"); } @@ -77,10 +74,7 @@ final class DeleteMeta extends BaseMeta { } private String genSql(ConcurrencyMode conMode, String table) { - - GenerateDmlRequest request = new GenerateDmlRequest(); - request.append("delete from ").append(table); - request.append(" where "); + GenerateDmlRequest request = new GenerateDmlRequest().append("delete from ").append(table).append(" where "); return appendWhere(request, conMode); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersister.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersister.java index 5c925e8d2..f07d207b8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersister.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersister.java @@ -19,11 +19,8 @@ import java.sql.SQLException; public final class DmlBeanPersister implements BeanPersister { private final DatabasePlatform dbPlatform; - private final UpdateMeta updateMeta; - private final InsertMeta insertMeta; - private final DeleteMeta deleteMeta; DmlBeanPersister(DatabasePlatform dbPlatform, UpdateMeta updateMeta, InsertMeta insertMeta, DeleteMeta deleteMeta) { @@ -61,7 +58,6 @@ public final class DmlBeanPersister implements BeanPersister { * execute request taking batching into account. */ private int execute(PersistRequestBean request, PersistHandler handler) { - boolean batched = request.isBatched(); try { handler.bind(); @@ -72,7 +68,6 @@ public final class DmlBeanPersister implements BeanPersister { } else { return handler.executeNoBatch(); } - } catch (SQLException e) { // log the error to the transaction log String msg = "Error[" + StringHelper.removeNewLines(e.getMessage()) + "]"; @@ -80,7 +75,6 @@ public final class DmlBeanPersister implements BeanPersister { request.getTransaction().logSummary(msg); } throw dbPlatform.translate(msg, e); - } finally { if (!batched) { handler.close(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersisterFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersisterFactory.java index a06ac1505..6e349dee1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersisterFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersisterFactory.java @@ -11,7 +11,6 @@ import io.ebeaninternal.server.persist.BeanPersisterFactory; public class DmlBeanPersisterFactory implements BeanPersisterFactory { private final DatabasePlatform dbPlatform; - private final MetaFactory metaFactory; public DmlBeanPersisterFactory(DatabasePlatform dbPlatform) { @@ -24,11 +23,9 @@ public class DmlBeanPersisterFactory implements BeanPersisterFactory { */ @Override public BeanPersister create(BeanDescriptor desc) { - if (desc.isDocStoreOnly()) { return new DocStoreBeanPersister(GeneratedProperties.of(desc)); } - UpdateMeta updMeta = metaFactory.createUpdate(desc); DeleteMeta delMeta = metaFactory.createDelete(desc); InsertMeta insMeta = metaFactory.createInsert(desc); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlHandler.java index 0a4bb6b8a..3baeb6551 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlHandler.java @@ -27,28 +27,14 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest { private static final short BATCHED_FIRST = 1; private static final short BATCHED = 2; - /** - * The originating request. - */ final PersistRequestBean persistRequest; - private final StringBuilder bindLog; - final SpiTransaction transaction; - private final boolean logLevelSql; - private final long now; - - /** - * The PreparedStatement used for the dml. - */ DataBind dataBind; - BatchedPstmt batchedPstmt; - String sql; - private short batchedStatus; DmlHandler(PersistRequestBean persistRequest) { @@ -226,7 +212,6 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest { } private void bindInternal(boolean log, Object value, BeanProperty prop) throws SQLException { - if (log) { if (bindLog.length() > 0) { bindLog.append(","); @@ -249,14 +234,12 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest { * Check with useGeneratedKeys to get appropriate PreparedStatement. */ PreparedStatement getPstmt(SpiTransaction t, String sql, boolean genKeys) throws SQLException { - Connection conn = t.getInternalConnection(); if (genKeys) { // the Id generated is always the first column // Required to stop Oracle10 giving us Oracle rowId?? // Other jdbc drivers seem fine without this hint. return conn.prepareStatement(sql, GENERATED_KEY_COLUMNS); - } else { return conn.prepareStatement(sql); } @@ -272,7 +255,6 @@ public abstract class DmlHandler implements PersistHandler, BindableRequest { batchedStatus = batchedPstmt.isEmpty() ? BATCHED_FIRST : BATCHED; return batchedPstmt.getStatement(request); } - batchedStatus = BATCHED_FIRST; PreparedStatement stmt = getPstmt(t, sql, genKeys); batchedPstmt = new BatchedPstmt(stmt, genKeys, sql, t); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GenerateDmlRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GenerateDmlRequest.java index 5093ae111..809115563 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GenerateDmlRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GenerateDmlRequest.java @@ -6,14 +6,10 @@ package io.ebeaninternal.server.persist.dml; public class GenerateDmlRequest { private final StringBuilder sb = new StringBuilder(100); - private StringBuilder insertBindBuffer; - private String prefix; private String prefix2; - private int insertMode; - private int bindColumnCount; /** @@ -33,7 +29,6 @@ public class GenerateDmlRequest { } public void appendColumn(String column, String bind) { - ++bindColumnCount; sb.append(prefix); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java index f1508bf50..d9fb1e8f0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java @@ -20,24 +20,11 @@ import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; */ public class InsertHandler extends DmlHandler { - /** - * The associated InsertMeta data. - */ private final InsertMeta meta; - - /** - * Set to true when the key is concatenated. - */ - private final boolean concatinatedKey; - - /** - * Flag set when using getGeneratedKeys. - */ + private final boolean concatenatedKey; private boolean useGeneratedKeys; - /** - * A SQL Select used to fetch back the Id where generatedKeys is not - * supported. + * SQL Select used to fetch back the Id where generatedKeys is not supported. */ private boolean useSelectLastInsertedId; @@ -47,7 +34,7 @@ public class InsertHandler extends DmlHandler { public InsertHandler(PersistRequestBean persist, InsertMeta meta) { super(persist); this.meta = meta; - this.concatinatedKey = meta.isConcatenatedKey(); + this.concatenatedKey = meta.isConcatenatedKey(); } @Override @@ -60,17 +47,14 @@ public class InsertHandler extends DmlHandler { */ @Override public void bind() throws SQLException { - BeanDescriptor desc = persistRequest.getBeanDescriptor(); EntityBean bean = persistRequest.getEntityBean(); - Object idValue = desc.getId(bean); - boolean withId = !isNullOrZero(idValue); // check to see if we are going to use generated keys if (!withId) { - if (concatinatedKey) { + if (concatenatedKey) { // expecting a concatenated key that can // be built from supplied AssocOne beans withId = meta.deriveConcatenatedId(persistRequest); @@ -84,10 +68,8 @@ public class InsertHandler extends DmlHandler { } SpiTransaction t = persistRequest.getTransaction(); - // get the appropriate sql sql = meta.getSql(withId, persistRequest.isPublish()); - PreparedStatement pstmt; if (persistRequest.isBatched()) { pstmt = getPstmtBatch(t, sql, persistRequest, useGeneratedKeys); @@ -139,7 +121,6 @@ public class InsertHandler extends DmlHandler { * For non batch insert with generated keys. */ private void getGeneratedKeys() throws SQLException { - ResultSet rset = dataBind.getPstmt().getGeneratedKeys(); try { setGeneratedKey(rset); @@ -164,7 +145,6 @@ public class InsertHandler extends DmlHandler { * SQL select to fetch back the Id value. */ private void fetchGeneratedKeyUsingSelect() throws SQLException { - PreparedStatement stmt = null; ResultSet rset = null; try { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertMeta.java index abaefd095..588b778e7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertMeta.java @@ -26,28 +26,18 @@ final class InsertMeta { private final String sqlWithId; private final String sqlDraftNullId; private final String sqlDraftWithId; - private final BindableId id; - private final Bindable discriminator; - private final BindableList all; - private final BindableList allExcludeDraftOnly; - private final boolean supportsGetGeneratedKeys; - - private final boolean concatinatedKey; - + private final boolean concatenatedKey; /** * Used for DB that do not support getGeneratedKeys. */ private final boolean supportsSelectLastInsertedId; - private final Bindable shadowFKey; - private final String[] identityDbColumns; - private final Platform platform; InsertMeta(DatabasePlatform dbPlatform, BeanDescriptor desc, Bindable shadowFKey, BindableId id, BindableList all) { @@ -66,7 +56,7 @@ final class InsertMeta { // only available for single Id property if (id.isConcatenated()) { // concatenated key - this.concatinatedKey = true; + this.concatenatedKey = true; this.identityDbColumns = null; this.sqlNullId = null; this.sqlDraftNullId = null; @@ -75,7 +65,7 @@ final class InsertMeta { } else { // insert sql for db identity or sequence insert - this.concatinatedKey = false; + this.concatenatedKey = false; if (id.getIdentityColumn() == null) { this.identityDbColumns = new String[]{}; this.supportsGetGeneratedKeys = false; @@ -99,7 +89,7 @@ final class InsertMeta { * Return true if this is a concatenated key. */ boolean isConcatenatedKey() { - return concatinatedKey; + return concatenatedKey; } String[] getIdentityDbColumns() { @@ -133,7 +123,6 @@ final class InsertMeta { * Bind the request based on whether the id value(s) are null. */ public void bind(DmlHandler request, EntityBean bean, boolean withId, boolean publish) throws SQLException { - if (withId) { id.dmlBind(request, bean); } @@ -154,7 +143,6 @@ final class InsertMeta { * get the sql based whether the id value(s) are null. */ public String getSql(boolean withId, boolean publish) { - if (withId) { return publish ? sqlWithId : sqlDraftWithId; } else { @@ -163,7 +151,6 @@ final class InsertMeta { } private String genSql(boolean nullId, String table, boolean draftTable) { - GenerateDmlRequest request = new GenerateDmlRequest(); request.setInsertSetMode(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/MetaFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/MetaFactory.java index 6df6d088c..de7c2bb39 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/MetaFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/MetaFactory.java @@ -24,19 +24,17 @@ import java.util.List; */ class MetaFactory { - private final FactoryBaseProperties baseFact; - private final FactoryEmbedded embeddedFact; - private final FactoryVersion versionFact = new FactoryVersion(); - private final FactoryAssocOnes assocOneFact = new FactoryAssocOnes(); - - private final FactoryId idFact = new FactoryId(); - /** * Include Lobs in the base statement. Generally true. Oracle9 used to require * a separate statement for Clobs and Blobs. */ private static final boolean includeLobs = true; + private final FactoryBaseProperties baseFact; + private final FactoryEmbedded embeddedFact; + private final FactoryVersion versionFact = new FactoryVersion(); + private final FactoryAssocOnes assocOneFact = new FactoryAssocOnes(); + private final FactoryId idFact = new FactoryId(); private final DatabasePlatform dbPlatform; MetaFactory(DatabasePlatform dbPlatform) { @@ -52,9 +50,7 @@ class MetaFactory { * Create the UpdateMeta for the given bean type. */ UpdateMeta createUpdate(BeanDescriptor desc) { - List setList = new ArrayList<>(); - baseFact.create(setList, desc, DmlMode.UPDATE, includeLobs); embeddedFact.create(setList, desc, DmlMode.UPDATE, includeLobs); assocOneFact.create(setList, desc, DmlMode.UPDATE); @@ -75,7 +71,6 @@ class MetaFactory { * Create the DeleteMeta for the given bean type. */ DeleteMeta createDelete(BeanDescriptor desc) { - BindableId id = idFact.createId(desc); Bindable version = versionFact.createForDelete(desc); Bindable tenantId = versionFact.createTenantId(desc); @@ -86,19 +81,15 @@ class MetaFactory { * Create the InsertMeta for the given bean type. */ InsertMeta createInsert(BeanDescriptor desc) { - BindableId id = idFact.createId(desc); List allList = new ArrayList<>(); - baseFact.create(allList, desc, DmlMode.INSERT, includeLobs); embeddedFact.create(allList, desc, DmlMode.INSERT, includeLobs); assocOneFact.create(allList, desc, DmlMode.INSERT); BindableList allBindable = new BindableList(allList); - BeanPropertyAssocOne unidirectional = desc.getUnidirectional(); - Bindable shadowFkey; if (unidirectional == null) { shadowFkey = null; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateHandler.java index 85f96c192..8a3e724c8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateHandler.java @@ -14,7 +14,6 @@ import java.sql.SQLException; public class UpdateHandler extends DmlHandler { private final UpdateMeta meta; - private boolean emptySetClause; UpdateHandler(PersistRequestBean persist, UpdateMeta meta) { @@ -32,18 +31,14 @@ public class UpdateHandler extends DmlHandler { */ @Override public void bind() throws SQLException { - SpiUpdatePlan updatePlan = meta.getUpdatePlan(persistRequest); - if (updatePlan.isEmptySetClause()) { emptySetClause = true; return; } sql = updatePlan.getSql(); - SpiTransaction t = persistRequest.getTransaction(); - PreparedStatement pstmt; if (persistRequest.isBatched()) { pstmt = getPstmtBatch(t, sql, persistRequest, false); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateMeta.java index 49dbbaea4..4b667e521 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateMeta.java @@ -30,16 +30,12 @@ final class UpdateMeta extends BaseMeta { * Bind the request based on the concurrency mode. */ public void bind(PersistRequestBean persist, DmlHandler bind, SpiUpdatePlan updatePlan) throws SQLException { - EntityBean bean = persist.getEntityBean(); - updatePlan.bindSet(bind, bean); - id.dmlBind(bind, bean); if (tenantId != null) { tenantId.dmlBind(bind, bean); } - if (persist.getConcurrencyMode() == ConcurrencyMode.VERSION) { version.dmlBind(bind, bean); } @@ -53,9 +49,7 @@ final class UpdateMeta extends BaseMeta { } private SpiUpdatePlan getDynamicUpdatePlan(PersistRequestBean persistRequest) { - String key = persistRequest.getUpdatePlanHash(); - // check if we can use a cached UpdatePlan BeanDescriptor beanDescriptor = persistRequest.getBeanDescriptor(); SpiUpdatePlan updatePlan = beanDescriptor.getUpdatePlan(key); @@ -71,20 +65,16 @@ final class UpdateMeta extends BaseMeta { BindableList bindableList = new BindableList(list); ConcurrencyMode mode = persistRequest.getConcurrencyMode(); - // build the SQL for this update statement String sql = genSql(mode, bindableList, persistRequest.getUpdateTable()); updatePlan = new UpdatePlan(key, mode, sql, bindableList); - // add the UpdatePlan to the cache beanDescriptor.putUpdatePlan(key, updatePlan); - return updatePlan; } private String genSql(ConcurrencyMode conMode, BindableList bindableList, String tableName) { - GenerateDmlRequest request = new GenerateDmlRequest(); request.append("update ").append(tableName).append(" set "); request.setUpdateSetMode(); @@ -95,7 +85,6 @@ final class UpdateMeta extends BaseMeta { // with the result that nothing is in the set clause return null; } - request.append(" where "); return appendWhere(request, conMode); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdatePlan.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdatePlan.java index 9422d83dd..97811b5cf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdatePlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdatePlan.java @@ -13,26 +13,13 @@ import java.sql.SQLException; class UpdatePlan implements SpiUpdatePlan { private final String key; - private final ConcurrencyMode mode; - private final String sql; - private final Bindable set; - private final long timeCreated; - private final boolean emptySetClause; - private long timeLastUsed; - /** - * Create a non cached UpdatePlan. - */ - UpdatePlan(ConcurrencyMode mode, String sql, Bindable set) { - this(null, mode, sql, set); - } - /** * Create a UpdatePlan with a given key. */ @@ -50,9 +37,6 @@ class UpdatePlan implements SpiUpdatePlan { return emptySetClause; } - /** - * Run the prepared statement binding for the 'update set' properties. - */ @Override public void bindSet(DmlHandler bind, EntityBean bean) throws SQLException { set.dmlBind(bind, bean); @@ -60,49 +44,31 @@ class UpdatePlan implements SpiUpdatePlan { this.timeLastUsed = System.currentTimeMillis(); } - /** - * Return the time this plan was created. - */ @Override public long getTimeCreated() { return timeCreated; } - /** - * Return the time this plan was last used. - */ @Override public long getTimeLastUsed() { return timeLastUsed; } - /** - * Return the key. - */ @Override public String getKey() { return key; } - /** - * Return the concurrency mode for this plan. - */ @Override public ConcurrencyMode getMode() { return mode; } - /** - * Return the DML statement. - */ @Override public String getSql() { return sql; } - /** - * Return the Bindable properties for the update set. - */ @Override public Bindable getSet() { return set; From 965c1e803fa67806d39e725ec1c640bc933bd830 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Fri, 13 Aug 2021 10:47:14 +0200 Subject: [PATCH 084/120] FIX: mutationDetection = SOURCE works also for special json types --- .../server/type/DefaultTypeManager.java | 13 +- .../server/type/ScalarTypeJsonList.java | 66 ++++---- .../server/type/ScalarTypeJsonMap.java | 116 +++++++++----- .../type/ScalarTypeJsonMapPostgres.java | 22 +-- .../server/type/ScalarTypeJsonSet.java | 68 ++++---- .../server/type/ScalarTypeJsonListTest.java | 12 +- .../java/org/tests/json/TestOldValue.java | 120 ++++++++++++++ .../org/tests/model/json/EBasicOldValue.java | 146 ++++++++++++++++++ 8 files changed, 446 insertions(+), 117 deletions(-) create mode 100644 ebean-core/src/test/java/org/tests/json/TestOldValue.java create mode 100644 ebean-core/src/test/java/org/tests/model/json/EBasicOldValue.java 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 1400b2180..4419f1e1f 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 @@ -289,7 +289,7 @@ public final class DefaultTypeManager implements TypeManager { @Override public ScalarType getDbMapScalarType() { - return (postgres) ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR); + return (postgres) ? hstoreType : ScalarTypeJsonMap.typeFor(false, Types.VARCHAR, false); } @Override @@ -312,7 +312,7 @@ public final class DefaultTypeManager implements TypeManager { return arrayTypeSetFactory.typeFor(valueType, nullable); } // fallback to JSON storage in VARCHAR column - return new ScalarTypeJsonSet.Varchar(getDocType(valueType), nullable); + return new ScalarTypeJsonSet.Varchar(getDocType(valueType), nullable, false); // TODO: keepSource for @DbArray? } private ScalarType getArrayScalarTypeList(Type valueType, boolean nullable) { @@ -323,7 +323,7 @@ public final class DefaultTypeManager implements TypeManager { return arrayTypeListFactory.typeFor(valueType, nullable); } // fallback to JSON storage in VARCHAR column - return new ScalarTypeJsonList.Varchar(getDocType(valueType), nullable); + return new ScalarTypeJsonList.Varchar(getDocType(valueType), nullable, false); // TODO: keepSource for @DbArray? } private Class> asEnumClass(Type valueType) { @@ -340,10 +340,11 @@ public final class DefaultTypeManager implements TypeManager { Type genericType = prop.getGenericType(); boolean hasJacksonAnnotations = objectMapperPresent && checkJacksonAnnotations(prop); + boolean keepSource = prop.getMutationDetection() == MutationDetection.SOURCE; if (type.equals(List.class)) { DocPropertyType docType = getDocType(genericType); if (!hasJacksonAnnotations && isValueTypeSimple(genericType)) { - return ScalarTypeJsonList.typeFor(postgres, dbType, docType, prop.isNullable()); + return ScalarTypeJsonList.typeFor(postgres, dbType, docType, prop.isNullable(), keepSource); } else { return createJsonObjectMapperType(prop, dbType, docType); } @@ -351,14 +352,14 @@ public final class DefaultTypeManager implements TypeManager { if (type.equals(Set.class)) { DocPropertyType docType = getDocType(genericType); if (!hasJacksonAnnotations && isValueTypeSimple(genericType)) { - return ScalarTypeJsonSet.typeFor(postgres, dbType, docType, prop.isNullable()); + return ScalarTypeJsonSet.typeFor(postgres, dbType, docType, prop.isNullable(), keepSource); } else { return createJsonObjectMapperType(prop, dbType, docType); } } if (type.equals(Map.class)) { if (!hasJacksonAnnotations && isMapValueTypeObject(genericType)) { - return ScalarTypeJsonMap.typeFor(postgres, dbType); + return ScalarTypeJsonMap.typeFor(postgres, dbType, keepSource); } else { return createJsonObjectMapperType(prop, dbType, DocPropertyType.OBJECT); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java index a196085a6..7ca361405 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java @@ -24,24 +24,24 @@ public class ScalarTypeJsonList { /** * Return the appropriate ScalarType based requested dbType and if Postgres. */ - public static ScalarType typeFor(boolean postgres, int dbType, DocPropertyType docType, boolean nullable) { + public static ScalarType typeFor(boolean postgres, int dbType, DocPropertyType docType, boolean nullable, boolean keepSource) { if (postgres) { switch (dbType) { case DbPlatformType.JSONB: - return new ScalarTypeJsonList.JsonB(docType, nullable); + return new ScalarTypeJsonList.JsonB(docType, nullable, keepSource); case DbPlatformType.JSON: - return new ScalarTypeJsonList.Json(docType, nullable); + return new ScalarTypeJsonList.Json(docType, nullable, keepSource); } } - return new ScalarTypeJsonList.Varchar(docType, nullable); + return new ScalarTypeJsonList.Varchar(docType, nullable, keepSource); } /** * List mapped to DB VARCHAR. */ public static class Varchar extends ScalarTypeJsonList.Base { - public Varchar(DocPropertyType docType, boolean nullable) { - super(Types.VARCHAR, docType, nullable); + public Varchar(DocPropertyType docType, boolean nullable, boolean keepSource) { + super(Types.VARCHAR, docType, nullable, keepSource); } } @@ -49,8 +49,8 @@ public class ScalarTypeJsonList { * List mapped to Postgres JSON. */ private static class Json extends ScalarTypeJsonList.PgBase { - public Json(DocPropertyType docType, boolean nullable) { - super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, docType, nullable); + public Json(DocPropertyType docType, boolean nullable, boolean keepSource) { + super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, docType, nullable, keepSource); } } @@ -58,8 +58,8 @@ public class ScalarTypeJsonList { * List mapped to Postgres JSONB. */ private static class JsonB extends ScalarTypeJsonList.PgBase { - public JsonB(DocPropertyType docType, boolean nullable) { - super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, docType, nullable); + public JsonB(DocPropertyType docType, boolean nullable, boolean keepSource) { + super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, docType, nullable, keepSource); } } @@ -68,14 +68,24 @@ public class ScalarTypeJsonList { */ @SuppressWarnings("rawtypes") private abstract static class Base extends ScalarTypeJsonCollection { + private final boolean keepSource; - public Base(int dbType, DocPropertyType docType, boolean nullable) { + public Base(int dbType, DocPropertyType docType, boolean nullable, boolean keepSource) { super(List.class, dbType, docType, nullable); + this.keepSource = keepSource; + } + + @Override + public boolean isJsonMapper() { + return keepSource; } @Override public List read(DataReader reader) throws SQLException { String json = reader.getString(); + if (isJsonMapper()) { + reader.pushJson(json); + } try { // parse JSON into modifyAware list return EJson.parseList(json, true); @@ -85,17 +95,15 @@ public class ScalarTypeJsonList { } @Override - public void bind(DataBinder binder, List value) throws SQLException { + public final void bind(DataBinder binder, List value) throws SQLException { + String rawJson = isJsonMapper() ? binder.popJson() : null; + if (rawJson == null && value != null) { + rawJson = formatValue(value); + } if (value == null) { bindNull(binder); - } else if (value.isEmpty()) { - binder.setString("[]"); } else { - try { - binder.setString(EJson.write(value)); - } catch (IOException e) { - throw new SQLException("Failed to format List into JSON content", e); - } + bindRawJson(binder, rawJson); } } @@ -107,9 +115,16 @@ public class ScalarTypeJsonList { binder.setString("[]"); } } + + protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException { + binder.setString(rawJson); + } @Override public String formatValue(List value) { + if (value.isEmpty()) { + return "[]"; + } try { return EJson.write(value); } catch (IOException e) { @@ -144,19 +159,14 @@ public class ScalarTypeJsonList { final String pgType; - PgBase(int jdbcType, String pgType, DocPropertyType docType, boolean nullable) { - super(jdbcType, docType, nullable); + PgBase(int jdbcType, String pgType, DocPropertyType docType, boolean nullable, boolean keepSource) { + super(jdbcType, docType, nullable, keepSource); this.pgType = pgType; } - @SuppressWarnings("rawtypes") @Override - public void bind(DataBinder binder, List value) throws SQLException { - if (value == null) { - bindNull(binder); - } else { - binder.setObject(PostgresHelper.asObject(pgType, formatValue(value))); - } + protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException { + binder.setObject(PostgresHelper.asObject(pgType, rawJson)); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMap.java index 6dd4f900b..507e7012b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMap.java @@ -15,6 +15,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.sql.SQLException; import java.sql.Types; @@ -26,27 +27,21 @@ import java.util.Map; @SuppressWarnings("rawtypes") public abstract class ScalarTypeJsonMap extends ScalarTypeBase { - private static final ScalarTypeJsonMap CLOB = new ScalarTypeJsonMap.Clob(); - private static final ScalarTypeJsonMap BLOB = new ScalarTypeJsonMap.Blob(); - private static final ScalarTypeJsonMap VARCHAR = new ScalarTypeJsonMap.Varchar(); - private static final ScalarTypeJsonMap JSON = new ScalarTypeJsonMapPostgres.JSON(); - private static final ScalarTypeJsonMap JSONB = new ScalarTypeJsonMapPostgres.JSONB(); - /** * Return the ScalarType for the requested dbType and postgres. */ - public static ScalarTypeJsonMap typeFor(boolean postgres, int dbType) { + public static ScalarTypeJsonMap typeFor(boolean postgres, int dbType, boolean keepSource) { switch (dbType) { case Types.VARCHAR: - return VARCHAR; + return new ScalarTypeJsonMap.Varchar(keepSource); case Types.BLOB: - return BLOB; + return new ScalarTypeJsonMap.Blob(keepSource); case Types.CLOB: - return CLOB; + return new ScalarTypeJsonMap.Clob(keepSource); case DbPlatformType.JSONB: - return postgres ? JSONB : CLOB; + return postgres ? new ScalarTypeJsonMapPostgres.JSONB(keepSource) : new ScalarTypeJsonMap.Clob(keepSource); case DbPlatformType.JSON: - return postgres ? JSON : CLOB; + return postgres ? new ScalarTypeJsonMapPostgres.JSON(keepSource) : new ScalarTypeJsonMap.Clob(keepSource); default: throw new IllegalStateException("Unknown dbType " + dbType); } @@ -54,41 +49,50 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { public static class Clob extends ScalarTypeJsonMap { - public Clob() { - super(Types.CLOB); + public Clob(boolean keepSource) { + super(Types.CLOB, keepSource); } @Override - public Map read(DataReader reader) throws SQLException { - String content = reader.getStringFromStream(); - if (content == null) { - return null; - } - return parse(content); + protected String readJson(DataReader reader) throws SQLException { + return reader.getStringFromStream(); } } public static class Varchar extends ScalarTypeJsonMap { - public Varchar() { - super(Types.VARCHAR); + public Varchar(boolean keepSource) { + super(Types.VARCHAR, keepSource); } } public static class Blob extends ScalarTypeJsonMap { - public Blob() { - super(Types.BLOB); + public Blob(boolean keepSource) { + super(Types.BLOB, keepSource); } @Override public Map read(DataReader reader) throws SQLException { InputStream is = reader.getBinaryStream(); if (is == null) { + if (isJsonMapper()) { + reader.pushJson(null); + } return null; } try { - try (InputStreamReader inputStreamReader = new InputStreamReader(is)) { - return parse(inputStreamReader); + if (isJsonMapper()) { + StringWriter rawJson = new StringWriter(); + try (InputStreamReader inputStreamReader = new InputStreamReader(is, StandardCharsets.UTF_8)) { + inputStreamReader.transferTo(rawJson); + } + reader.pushJson(rawJson.toString()); + return parse(rawJson.toString()); + + } else { + try (InputStreamReader inputStreamReader = new InputStreamReader(is, StandardCharsets.UTF_8)) { + return parse(inputStreamReader); + } } } catch (IOException e) { throw new SQLException("Error reading Blob stream from DB", e); @@ -96,18 +100,22 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } @Override - public void bind(DataBinder binder, Map value) throws SQLException { - if (value == null) { - binder.setNull(Types.BLOB); - } else { - String rawJson = formatValue(value); - binder.setBytes(rawJson.getBytes(StandardCharsets.UTF_8)); - } + protected void bindNull(DataBinder binder) throws SQLException { + binder.setNull(Types.BLOB); } + + @Override + protected void bindJson(DataBinder binder, String rawJson) throws SQLException { + binder.setBytes(rawJson.getBytes(StandardCharsets.UTF_8)); + } + } - public ScalarTypeJsonMap(int jdbcType) { + private final boolean keepSource; + + public ScalarTypeJsonMap(int jdbcType, boolean keepSource) { super(Map.class, false, jdbcType); + this.keepSource = keepSource; } /** @@ -125,26 +133,56 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { public boolean isDirty(Object value) { return TypeJsonManager.checkIsDirty(value); } + + + + @Override + public boolean isJsonMapper() { + return keepSource; + } + @Override public Map read(DataReader reader) throws SQLException { - String rawJson = reader.getString(); + String rawJson = readJson(reader); + if (isJsonMapper()) { + reader.pushJson(rawJson); + } + if (rawJson == null) { return null; } + return parse(rawJson); } + + protected String readJson(DataReader reader) throws SQLException { + return reader.getString(); + } + @Override - public void bind(DataBinder binder, Map value) throws SQLException { + public final void bind(DataBinder binder, Map value) throws SQLException { + String rawJson = isJsonMapper() ? binder.popJson() : null; + if (rawJson == null && value != null) { + rawJson = formatValue(value); + } + if (value == null) { - binder.setNull(Types.VARCHAR); + bindNull(binder); } else { - String rawJson = formatValue(value); - binder.setString(rawJson); + bindJson(binder, rawJson); } } + + protected void bindNull(DataBinder binder) throws SQLException { + binder.setNull(Types.VARCHAR); + } + protected void bindJson(DataBinder binder, String rawJson) throws SQLException { + binder.setString(rawJson); + } + @Override public Object toJdbcType(Object value) { return value; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMapPostgres.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMapPostgres.java index 87eecc5f9..46a585ebc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMapPostgres.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMapPostgres.java @@ -4,7 +4,6 @@ import io.ebean.config.dbplatform.DbPlatformType; import io.ebean.core.type.DataBinder; import java.sql.SQLException; -import java.util.Map; /** * Support for the Postgres DB types JSON and JSONB. @@ -13,15 +12,18 @@ public abstract class ScalarTypeJsonMapPostgres extends ScalarTypeJsonMap { final String postgresType; - ScalarTypeJsonMapPostgres(int jdbcType, String postgresType) { - super(jdbcType); + ScalarTypeJsonMapPostgres(int jdbcType, String postgresType, boolean keepSource) { + super(jdbcType, keepSource); this.postgresType = postgresType; } - @SuppressWarnings("rawtypes") @Override - public void bind(DataBinder binder, Map value) throws SQLException { - String rawJson = (value == null) ? null : formatValue(value); + protected void bindNull(DataBinder binder) throws SQLException { + binder.setObject(PostgresHelper.asObject(postgresType, null)); + } + + @Override + protected void bindJson(DataBinder binder, String rawJson) throws SQLException { binder.setObject(PostgresHelper.asObject(postgresType, rawJson)); } @@ -30,8 +32,8 @@ public abstract class ScalarTypeJsonMapPostgres extends ScalarTypeJsonMap { */ public static class JSON extends ScalarTypeJsonMapPostgres { - public JSON() { - super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE); + public JSON(boolean keepSource) { + super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, keepSource); } } @@ -40,8 +42,8 @@ public abstract class ScalarTypeJsonMapPostgres extends ScalarTypeJsonMap { */ public static class JSONB extends ScalarTypeJsonMapPostgres { - public JSONB() { - super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE); + public JSONB(boolean keepSource) { + super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, keepSource); } } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java index d95adb572..7e728b0d3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java @@ -26,24 +26,24 @@ public class ScalarTypeJsonSet { /** * Return the appropriate ScalarType for the requested dbType and Postgres. */ - public static ScalarType typeFor(boolean postgres, int dbType, DocPropertyType docPropertyType, boolean nullable) { + public static ScalarType typeFor(boolean postgres, int dbType, DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { if (postgres) { switch (dbType) { case DbPlatformType.JSONB: - return new ScalarTypeJsonSet.JsonB(docPropertyType, nullable); + return new ScalarTypeJsonSet.JsonB(docPropertyType, nullable, keepSource); case DbPlatformType.JSON: - return new ScalarTypeJsonSet.Json(docPropertyType, nullable); + return new ScalarTypeJsonSet.Json(docPropertyType, nullable, keepSource); } } - return new ScalarTypeJsonSet.Varchar(docPropertyType, nullable); + return new ScalarTypeJsonSet.Varchar(docPropertyType, nullable, keepSource); } /** * List mapped to DB VARCHAR. */ public static class Varchar extends ScalarTypeJsonSet.Base { - public Varchar(DocPropertyType docPropertyType, boolean nullable) { - super(Types.VARCHAR, docPropertyType, nullable); + public Varchar(DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { + super(Types.VARCHAR, docPropertyType, nullable, keepSource); } } @@ -51,8 +51,8 @@ public class ScalarTypeJsonSet { * List mapped to Postgres JSON. */ private static class Json extends ScalarTypeJsonSet.PgBase { - public Json(DocPropertyType docPropertyType, boolean nullable) { - super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, docPropertyType, nullable); + public Json(DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { + super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, docPropertyType, nullable, keepSource); } } @@ -60,8 +60,8 @@ public class ScalarTypeJsonSet { * List mapped to Postgres JSONB. */ private static class JsonB extends ScalarTypeJsonSet.PgBase { - public JsonB(DocPropertyType docPropertyType, boolean nullable) { - super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, docPropertyType, nullable); + public JsonB(DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { + super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, docPropertyType, nullable, keepSource); } } @@ -71,13 +71,25 @@ public class ScalarTypeJsonSet { @SuppressWarnings("rawtypes") private abstract static class Base extends ScalarTypeJsonCollection { - public Base(int dbType, DocPropertyType docPropertyType, boolean nullable) { + private boolean keepSource; + + public Base(int dbType, DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { super(Set.class, dbType, docPropertyType, nullable); + this.keepSource = keepSource; } + + @Override + public boolean isJsonMapper() { + return keepSource; + } + @Override public Set read(DataReader reader) throws SQLException { String json = reader.getString(); + if (isJsonMapper()) { + reader.pushJson(json); + } try { // parse JSON into modifyAware list return EJson.parseSet(json, true); @@ -87,17 +99,15 @@ public class ScalarTypeJsonSet { } @Override - public void bind(DataBinder binder, Set value) throws SQLException { + public final void bind(DataBinder binder, Set value) throws SQLException { + String rawJson = isJsonMapper() ? binder.popJson() : null; + if (rawJson == null && value != null) { + rawJson = formatValue(value); + } if (value == null) { bindNull(binder); - } else if (value.isEmpty()) { - binder.setString("[]"); } else { - try { - binder.setString(EJson.write(value)); - } catch (IOException e) { - throw new SQLException("Failed to format Set into JSON content", e); - } + bindRawJson(binder, rawJson); } } @@ -110,8 +120,15 @@ public class ScalarTypeJsonSet { } } + protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException { + binder.setString(rawJson); + } + @Override public String formatValue(Set value) { + if (value.isEmpty()) { + return "[]"; + } try { return EJson.write(value); } catch (IOException e) { @@ -151,19 +168,14 @@ public class ScalarTypeJsonSet { final String pgType; - PgBase(int jdbcType, String pgType, DocPropertyType docPropertyType, boolean nullable) { - super(jdbcType, docPropertyType, nullable); + PgBase(int jdbcType, String pgType, DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { + super(jdbcType, docPropertyType, nullable, keepSource); this.pgType = pgType; } - @SuppressWarnings("rawtypes") @Override - public void bind(DataBinder binder, Set value) throws SQLException { - if (value == null) { - bindNull(binder); - } else { - binder.setObject(PostgresHelper.asObject(pgType, formatValue(value))); - } + protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException { + binder.setObject(PostgresHelper.asObject(pgType, rawJson)); } @Override diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeJsonListTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeJsonListTest.java index ff329efac..43ed867ba 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeJsonListTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeJsonListTest.java @@ -11,19 +11,19 @@ public class ScalarTypeJsonListTest extends BasePlatformArrayTypeFactoryTest { @Test public void typeFor_expect_nullToEmpty_when_postgresNonNull() throws SQLException { - assertBindNullTo_PGObjectEmpty(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONB, DocPropertyType.OBJECT, false)); - assertBindNullTo_PGObjectEmpty(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSON, DocPropertyType.OBJECT, false)); + assertBindNullTo_PGObjectEmpty(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONB, DocPropertyType.OBJECT, false, false)); + assertBindNullTo_PGObjectEmpty(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSON, DocPropertyType.OBJECT, false, false)); - assertBindNullTo_EmptyString(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONVarchar, DocPropertyType.OBJECT, false)); + assertBindNullTo_EmptyString(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONVarchar, DocPropertyType.OBJECT, false, false)); } @Test public void typeFor_expect_nullToNull_when_nullable() throws SQLException { - assertBindNullTo_PGObjectNull(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONB, DocPropertyType.OBJECT, true)); - assertBindNullTo_PGObjectNull(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSON, DocPropertyType.OBJECT, true)); + assertBindNullTo_PGObjectNull(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONB, DocPropertyType.OBJECT, true, false)); + assertBindNullTo_PGObjectNull(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSON, DocPropertyType.OBJECT, true, false)); - assertBindNullTo_Null(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONVarchar, DocPropertyType.OBJECT, true)); + assertBindNullTo_Null(ScalarTypeJsonList.typeFor(true, ExtraDbTypes.JSONVarchar, DocPropertyType.OBJECT, true, false)); } } diff --git a/ebean-core/src/test/java/org/tests/json/TestOldValue.java b/ebean-core/src/test/java/org/tests/json/TestOldValue.java new file mode 100644 index 000000000..dec8a9f05 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/json/TestOldValue.java @@ -0,0 +1,120 @@ +package org.tests.json; + +import io.ebean.BaseTestCase; +import io.ebean.DB; +import io.ebean.ValuePair; +import io.ebean.annotation.ForPlatform; +import io.ebean.annotation.Platform; +import io.ebean.text.TextException; + +import org.assertj.core.api.SoftAssertions; +import org.ebeantest.LoggedSqlCollector; +import org.junit.Ignore; +import org.junit.Test; +import org.tests.model.json.EBasicJsonList; +import org.tests.model.json.EBasicOldValue; +import org.tests.model.json.PlainBean; + +import javax.persistence.PersistenceException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +public class TestOldValue extends BaseTestCase { + + + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void testDbJsonOldValue() throws Exception { + EBasicOldValue bean = new EBasicOldValue(); + + bean.getStringList().add("sl1"); + bean.getStringSet().add("ss1"); + bean.getObjectMap().put("sk1","sm1"); + bean.getLongList().add(1L); + bean.getLongSet().add(1001L); + bean.getLongMap().put("lk1",2001L); + bean.getIntList().add(2); + bean.getIntSet().add(1002); + bean.getIntMap().put("ik1",2002); + + DB.save(bean); + bean = DB.find(EBasicOldValue.class, bean.getId()); + + bean.getStringList().add("sl2"); + bean.getStringSet().add("ss2"); + bean.getObjectMap().put("sk2","sm2"); + bean.getLongList().add(5L); + bean.getLongSet().add(1005L); + bean.getLongMap().put("lk2",2005L); + bean.getIntList().add(6); + bean.getIntSet().add(1006); + bean.getIntMap().put("ik2",2006); + + + Map dirty = DB.getBeanState(bean).getDirtyValues(); + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(dirty).hasSize(9); + + softly.assertThat((List)dirty.get("stringList").getOldValue()).containsExactly("sl1"); + softly.assertThat((List)dirty.get("stringList").getNewValue()).containsExactly("sl1", "sl2"); + softly.assertThat((List)dirty.get("longList").getOldValue()).containsExactly(1L); + softly.assertThat((List)dirty.get("longList").getNewValue()).containsExactly(1L, 5L); + softly.assertThat((List)dirty.get("intList").getOldValue()).containsExactly(2); + softly.assertThat((List)dirty.get("intList").getNewValue()).containsExactly(2, 6); + + softly.assertThat((Set)dirty.get("stringSet").getOldValue()).containsExactly("ss1"); + softly.assertThat((Set)dirty.get("stringSet").getNewValue()).containsExactly("ss1", "ss2"); + softly.assertThat((Set)dirty.get("longSet").getOldValue()).containsExactly(1001L); + softly.assertThat((Set)dirty.get("longSet").getNewValue()).containsExactly(1001L, 1005L); + softly.assertThat((Set)dirty.get("intSet").getOldValue()).containsExactly(1002); + softly.assertThat((Set)dirty.get("intSet").getNewValue()).containsExactly(1002, 1006); + + softly.assertThat((Map)dirty.get("objectMap").getOldValue()).containsEntry("sk1","sm1").hasSize(1); + softly.assertThat((Map)dirty.get("objectMap").getNewValue()).containsEntry("sk1","sm1").containsEntry("sk2","sm2").hasSize(2); + softly.assertThat((Map)dirty.get("longMap").getOldValue()).containsEntry("lk1",2001L).hasSize(1); + softly.assertThat((Map)dirty.get("longMap").getNewValue()).containsEntry("lk1",2001L).containsEntry("lk2",2005L).hasSize(2); + softly.assertThat((Map)dirty.get("intMap").getOldValue()).containsEntry("ik1",2002).hasSize(1); + softly.assertThat((Map)dirty.get("intMap").getNewValue()).containsEntry("ik1",2002).containsEntry("ik2",2006).hasSize(2); + + softly.assertAll(); + + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + @Ignore("Old value detection does not work for @DbArray") + public void testDbArrayOldValue() throws Exception { + EBasicOldValue bean = new EBasicOldValue(); + + bean.getStringArr().add("sa1"); + + + DB.save(bean); + bean = DB.find(EBasicOldValue.class, bean.getId()); + + bean.getStringArr().add("sa2"); + + + + Map dirty = DB.getBeanState(bean).getDirtyValues(); + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(dirty).hasSize(1); + + softly.assertThat((List)dirty.get("stringArr").getOldValue()).containsExactly("sa1"); + softly.assertThat((List)dirty.get("stringArr").getNewValue()).containsExactly("sa1", "sa2"); + + softly.assertAll(); + + } +} diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicOldValue.java b/ebean-core/src/test/java/org/tests/model/json/EBasicOldValue.java new file mode 100644 index 000000000..27a086ad5 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicOldValue.java @@ -0,0 +1,146 @@ +package org.tests.model.json; + +import io.ebean.annotation.DbArray; +import io.ebean.annotation.DbJson; + +import javax.persistence.Entity; +import javax.persistence.Id; +import java.util.*; + +import static io.ebean.annotation.MutationDetection.SOURCE; + +@Entity +public class EBasicOldValue { + + @Id + Long id; + + String name; + + @DbJson(mutationDetection = SOURCE) + Set stringSet = new LinkedHashSet<>(); + + @DbJson(mutationDetection = SOURCE) + Set longSet = new LinkedHashSet<>(); + + @DbJson(mutationDetection = SOURCE) + Set intSet = new LinkedHashSet<>(); + + @DbJson(mutationDetection = SOURCE) + List stringList = new ArrayList<>(); + + @DbJson(mutationDetection = SOURCE) + List longList = new ArrayList<>(); + + @DbJson(mutationDetection = SOURCE) + List intList = new ArrayList<>(); + + @DbJson(mutationDetection = SOURCE) + Map objectMap = new LinkedHashMap<>(); + + @DbJson(mutationDetection = SOURCE) + Map longMap = new LinkedHashMap<>(); + + @DbJson(mutationDetection = SOURCE) + Map intMap = new LinkedHashMap<>(); + + @DbArray() + List stringArr = new ArrayList<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getStringSet() { + return stringSet; + } + + public void setStringSet(Set stringSet) { + this.stringSet = stringSet; + } + + public Set getLongSet() { + return longSet; + } + + public void setLongSet(Set longSet) { + this.longSet = longSet; + } + + public Set getIntSet() { + return intSet; + } + + public void setIntSet(Set intSet) { + this.intSet = intSet; + } + + public List getStringList() { + return stringList; + } + + public void setStringList(List stringList) { + this.stringList = stringList; + } + + public List getLongList() { + return longList; + } + + public void setLongList(List longList) { + this.longList = longList; + } + + public List getIntList() { + return intList; + } + + public void setIntList(List intList) { + this.intList = intList; + } + + public Map getObjectMap() { + return objectMap; + } + + public void setObjectMap(Map objectMap) { + this.objectMap = objectMap; + } + + public Map getLongMap() { + return longMap; + } + + public void setLongMap(Map longMap) { + this.longMap = longMap; + } + + public Map getIntMap() { + return intMap; + } + + public void setIntMap(Map intMap) { + this.intMap = intMap; + } + + public List getStringArr() { + return stringArr; + } + + public void setStringArr(List stringArr) { + this.stringArr = stringArr; + } + +} From 6b263919d5ccd5c8f552d3268bbb01eb9ea84e65 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Fri, 13 Aug 2021 11:19:24 +0200 Subject: [PATCH 085/120] handle also JsonNode --- .../server/type/DefaultTypeManager.java | 2 +- .../java/org/tests/json/TestOldValue.java | 31 +++++++------------ .../org/tests/model/json/EBasicOldValue.java | 15 +++++++++ 3 files changed, 28 insertions(+), 20 deletions(-) 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 4419f1e1f..6e1e1f0d7 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 @@ -364,7 +364,7 @@ public final class DefaultTypeManager implements TypeManager { return createJsonObjectMapperType(prop, dbType, DocPropertyType.OBJECT); } } - if (objectMapperPresent) { + if (objectMapperPresent && prop.getMutationDetection() == MutationDetection.DEFAULT) { if (type.equals(JsonNode.class)) { switch (dbType) { case Types.VARCHAR: diff --git a/ebean-core/src/test/java/org/tests/json/TestOldValue.java b/ebean-core/src/test/java/org/tests/json/TestOldValue.java index dec8a9f05..f7bd391e5 100644 --- a/ebean-core/src/test/java/org/tests/json/TestOldValue.java +++ b/ebean-core/src/test/java/org/tests/json/TestOldValue.java @@ -3,32 +3,19 @@ package org.tests.json; import io.ebean.BaseTestCase; import io.ebean.DB; import io.ebean.ValuePair; -import io.ebean.annotation.ForPlatform; -import io.ebean.annotation.Platform; -import io.ebean.text.TextException; import org.assertj.core.api.SoftAssertions; -import org.ebeantest.LoggedSqlCollector; import org.junit.Ignore; import org.junit.Test; -import org.tests.model.json.EBasicJsonList; import org.tests.model.json.EBasicOldValue; -import org.tests.model.json.PlainBean; -import javax.persistence.PersistenceException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashSet; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; + import java.util.List; import java.util.Map; import java.util.Set; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - public class TestOldValue extends BaseTestCase { @@ -37,6 +24,7 @@ public class TestOldValue extends BaseTestCase { @Test public void testDbJsonOldValue() throws Exception { EBasicOldValue bean = new EBasicOldValue(); + JsonNodeFactory jnf = new JsonNodeFactory(false); bean.getStringList().add("sl1"); bean.getStringSet().add("ss1"); @@ -47,7 +35,9 @@ public class TestOldValue extends BaseTestCase { bean.getIntList().add(2); bean.getIntSet().add(1002); bean.getIntMap().put("ik1",2002); - + + bean.setJsonNode(jnf.arrayNode().add("Foo")); + DB.save(bean); bean = DB.find(EBasicOldValue.class, bean.getId()); @@ -60,11 +50,11 @@ public class TestOldValue extends BaseTestCase { bean.getIntList().add(6); bean.getIntSet().add(1006); bean.getIntMap().put("ik2",2006); - + ((ArrayNode)bean.getJsonNode()).add("Bar"); Map dirty = DB.getBeanState(bean).getDirtyValues(); SoftAssertions softly = new SoftAssertions(); - softly.assertThat(dirty).hasSize(9); + softly.assertThat(dirty).hasSize(10); softly.assertThat((List)dirty.get("stringList").getOldValue()).containsExactly("sl1"); softly.assertThat((List)dirty.get("stringList").getNewValue()).containsExactly("sl1", "sl2"); @@ -87,6 +77,9 @@ public class TestOldValue extends BaseTestCase { softly.assertThat((Map)dirty.get("intMap").getOldValue()).containsEntry("ik1",2002).hasSize(1); softly.assertThat((Map)dirty.get("intMap").getNewValue()).containsEntry("ik1",2002).containsEntry("ik2",2006).hasSize(2); + softly.assertThat((ArrayNode)dirty.get("jsonNode").getOldValue()).hasToString("[\"Foo\"]"); + softly.assertThat((ArrayNode)dirty.get("jsonNode").getNewValue()).hasToString("[\"Foo\",\"Bar\"]"); + softly.assertAll(); } diff --git a/ebean-core/src/test/java/org/tests/model/json/EBasicOldValue.java b/ebean-core/src/test/java/org/tests/model/json/EBasicOldValue.java index 27a086ad5..37e805412 100644 --- a/ebean-core/src/test/java/org/tests/model/json/EBasicOldValue.java +++ b/ebean-core/src/test/java/org/tests/model/json/EBasicOldValue.java @@ -5,6 +5,9 @@ import io.ebean.annotation.DbJson; import javax.persistence.Entity; import javax.persistence.Id; + +import com.fasterxml.jackson.databind.JsonNode; + import java.util.*; import static io.ebean.annotation.MutationDetection.SOURCE; @@ -44,9 +47,13 @@ public class EBasicOldValue { @DbJson(mutationDetection = SOURCE) Map intMap = new LinkedHashMap<>(); + @DbJson(mutationDetection = SOURCE) + JsonNode jsonNode; + @DbArray() List stringArr = new ArrayList<>(); + public Long getId() { return id; } @@ -135,6 +142,14 @@ public class EBasicOldValue { this.intMap = intMap; } + public JsonNode getJsonNode() { + return jsonNode; + } + + public void setJsonNode(JsonNode jsonNode) { + this.jsonNode = jsonNode; + } + public List getStringArr() { return stringArr; } From 843b90cbbad96f70667a22785dd1d557ea3e1f96 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Fri, 13 Aug 2021 11:52:31 +0200 Subject: [PATCH 086/120] FIX: mutation info is not restored on cache hit --- .../server/deploy/BeanPropertyJsonMapper.java | 13 ++++++++++++ .../org/tests/changelog/TestChangeLog.java | 21 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index fdea2e449..f1b77f4bd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -5,6 +5,7 @@ import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; import io.ebean.bean.MutableValueInfo; import io.ebean.bean.MutableValueNext; +import io.ebean.bean.PersistenceContext; import io.ebean.core.type.DataReader; import io.ebean.core.type.ScalarType; import io.ebean.text.TextException; @@ -104,6 +105,18 @@ public class BeanPropertyJsonMapper extends BeanPropertyJsonBasic { throw new PersistenceException("Error readSet on " + descriptor + "." + name, e); } } + + @Override + public void setCacheDataValue(EntityBean bean, Object cacheData, PersistenceContext context) { + if (cacheData instanceof String) { + // parse back from string to support optimisation of java object serialisation + final MutableValueInfo hash = createMutableInfo((String)cacheData); + bean._ebean_getIntercept().mutableInfo(propertyIndex, hash); + cacheData = scalarType.parse((String) cacheData); + } + setValue(bean, cacheData); + } + private static final class NextPair implements MutableValueNext { diff --git a/ebean-core/src/test/java/org/tests/changelog/TestChangeLog.java b/ebean-core/src/test/java/org/tests/changelog/TestChangeLog.java index a10a41276..75f8c97bd 100644 --- a/ebean-core/src/test/java/org/tests/changelog/TestChangeLog.java +++ b/ebean-core/src/test/java/org/tests/changelog/TestChangeLog.java @@ -28,7 +28,7 @@ import java.util.ArrayList; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; public class TestChangeLog extends BaseTestCase { @@ -158,6 +158,25 @@ public class TestChangeLog extends BaseTestCase { assertThat(change.getData()).contains("\"plainBean\":{\"name\":\"B\""); assertThat(change.getOldData()).contains("\"plainBean\":{\"name\":\"A\""); } + + @Test + public void testMutationWithCache() throws Exception { + EBasicChangeLog bean = new EBasicChangeLog(); + bean.setName("Name1"); + bean.setPlainBean(new PlainBean("foo", 42)); + server.save(bean); + BeanChange change = firstChange(); + assertThat(change.getData()).contains("\"plainBean\""); + + server.find(EBasicChangeLog.class, bean.getId()); // load cache + bean = server.find(EBasicChangeLog.class, bean.getId()); // hit cache + bean.setShortDescription("Desc"); + server.save(bean); + + change = firstChange(); + assertThat(change.getData()).doesNotContain("\"plainBean\""); + } + private Database createServer() { DatabaseConfig config = new DatabaseConfig(); From ada8df5755e92292ceeda24eefa02558c860308f Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 15 Aug 2021 12:05:30 +1200 Subject: [PATCH 087/120] Improve startup logging messages --- .../server/core/DatabasePlatformFactory.java | 10 +++----- .../server/core/DefaultContainer.java | 25 ++++++------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java index a96907848..9a7c54034 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DatabasePlatformFactory.java @@ -36,9 +36,8 @@ import java.sql.SQLException; /** * Create a DatabasePlatform from the configuration. *

- * Will used platform name or use the meta data from the JDBC driver to + * Will used platform name or use the metadata from the JDBC driver to * determine the platform automatically. - *

*/ public class DatabasePlatformFactory { @@ -54,14 +53,12 @@ public class DatabasePlatformFactory { logger.info("offline platform [{}]", offlinePlatform); return byDatabaseName(offlinePlatform); } - if (config.getDatabasePlatformName() != null) { // choose based on dbName return byDatabaseName(config.getDatabasePlatformName()); } - if (config.getDataSourceConfig().isOffline()) { - throw new PersistenceException("You must specify a DatabasePlatformName when you are offline"); + throw new PersistenceException("DatabasePlatformName must be specified with offline mode"); } // guess using meta data from driver return byDataSource(config.getDataSource()); @@ -142,10 +139,10 @@ public class DatabasePlatformFactory { * Find the platform by the metaData.getDatabaseProductName(). */ private DatabasePlatform byDatabaseMeta(DatabaseMetaData metaData, Connection connection) throws SQLException { - String dbProductName = metaData.getDatabaseProductName().toLowerCase(); final int majorVersion = metaData.getDatabaseMajorVersion(); final int minorVersion = metaData.getDatabaseMinorVersion(); + logger.debug("platform for productName[{}] version[{}.{}]", dbProductName, majorVersion, minorVersion); if (dbProductName.contains("oracle")) { return oracleVersion(majorVersion); @@ -206,7 +203,6 @@ public class DatabasePlatformFactory { } catch (SQLException e) { logger.warn("Error running detection query on Postgres", e); } - if (majorVersion <= 9) { return new Postgres9Platform(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java index 2c8bbfecc..e912b8cbb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java @@ -34,7 +34,7 @@ import java.util.concurrent.locks.ReentrantLock; */ public class DefaultContainer implements SpiContainer { - private static final Logger logger = LoggerFactory.getLogger("io.ebean.internal.DefaultContainer"); + private static final Logger logger = LoggerFactory.getLogger("io.ebean.DB"); private final ReentrantLock lock = new ReentrantLock(); private final ClusterManager clusterManager; @@ -77,9 +77,10 @@ public class DefaultContainer implements SpiContainer { public SpiEbeanServer createServer(DatabaseConfig config) { lock.lock(); try { + long start = System.currentTimeMillis(); applyConfigServices(config); setNamingConvention(config); - BootupClasses bootupClasses = getBootupClasses(config); + BootupClasses bootupClasses = bootupClasses(config); boolean online = true; if (config.isDocStoreOnly()) { @@ -101,22 +102,18 @@ public class DefaultContainer implements SpiContainer { // use a configured DbEncrypt rather than the platform default config.getDatabasePlatform().setDbEncrypt(config.getDbEncrypt()); } - // inform the NamingConvention of the associated DatabasePlatform config.getNamingConvention().setDatabasePlatform(config.getDatabasePlatform()); - // executor and l2 caching service setup early (used during server construction) SpiBackgroundExecutor executor = createBackgroundExecutor(config); InternalConfiguration c = new InternalConfiguration(online, clusterManager, executor, config, bootupClasses); - DefaultServer server = new DefaultServer(c, c.cacheManager()); - - // generate and run DDL if required - // if there are any other tasks requiring action in their plugins, do them as well + // generate and run DDL if required plus other plugins if (!DbOffline.isGenerateMigration()) { startServer(online, server); } DbOffline.reset(); + logger.info("started database[{}] platform[{}] in {}ms", config.getName(), config.getDatabasePlatform().getPlatform(), System.currentTimeMillis() - start); return server; } finally { lock.unlock(); @@ -161,9 +158,8 @@ public class DefaultContainer implements SpiContainer { * Get the entities, scalarTypes, Listeners etc combining the class registered * ones with the already created instances. */ - private BootupClasses getBootupClasses(DatabaseConfig config) { - - BootupClasses bootup = getBootupClasses1(config); + private BootupClasses bootupClasses(DatabaseConfig config) { + BootupClasses bootup = bootupClasses1(config); bootup.addIdGenerators(config.getIdGenerators()); bootup.addPersistControllers(config.getPersistControllers()); bootup.addPostLoaders(config.getPostLoaders()); @@ -173,7 +169,6 @@ public class DefaultContainer implements SpiContainer { bootup.addQueryAdapters(config.getQueryAdapters()); bootup.addServerConfigStartup(config.getServerConfigStartupListeners()); bootup.addChangeLogInstances(config); - bootup.runServerConfigStartup(config); return bootup; } @@ -181,14 +176,12 @@ public class DefaultContainer implements SpiContainer { /** * Get the class based entities, scalarTypes, Listeners etc. */ - private BootupClasses getBootupClasses1(DatabaseConfig config) { - + private BootupClasses bootupClasses1(DatabaseConfig config) { List> entityClasses = config.getClasses(); if (config.isDisableClasspathSearch() || (entityClasses != null && !entityClasses.isEmpty())) { // use classes we explicitly added via configuration return new BootupClasses(entityClasses); } - return BootupClassPathSearch.search(config); } @@ -205,7 +198,6 @@ public class DefaultContainer implements SpiContainer { * Set the DatabasePlatform if it has not already been set. */ private void setDatabasePlatform(DatabaseConfig config) { - DatabasePlatform platform = config.getDatabasePlatform(); if (platform == null) { if (config.getTenantMode().isDynamicDataSource()) { @@ -215,7 +207,6 @@ public class DefaultContainer implements SpiContainer { platform = new DatabasePlatformFactory().create(config); config.setDatabasePlatform(platform); } - logger.info("DatabasePlatform name:{} platform:{}", config.getName(), platform.getName()); platform.configure(config.getPlatformConfig()); } From 1297324fa9b4e778a9b0f0e8305feda3c06df875 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 15 Aug 2021 13:47:46 +1200 Subject: [PATCH 088/120] Fix where using JDK 10 Reader.transferTo() method plus add final to methods and classes --- .../server/type/ScalarTypeJsonList.java | 46 ++++---- .../server/type/ScalarTypeJsonMap.java | 111 ++++++++---------- .../type/ScalarTypeJsonMapPostgres.java | 18 +-- .../type/ScalarTypeJsonObjectMapper.java | 26 ++-- .../server/type/ScalarTypeJsonSet.java | 46 ++++---- 5 files changed, 118 insertions(+), 129 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java index 7ca361405..699c7ad0f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java @@ -19,12 +19,12 @@ import java.util.List; /** * Types for mapping List in JSON format to DB types VARCHAR, JSON and JSONB. */ -public class ScalarTypeJsonList { +class ScalarTypeJsonList { /** * Return the appropriate ScalarType based requested dbType and if Postgres. */ - public static ScalarType typeFor(boolean postgres, int dbType, DocPropertyType docType, boolean nullable, boolean keepSource) { + static ScalarType typeFor(boolean postgres, int dbType, DocPropertyType docType, boolean nullable, boolean keepSource) { if (postgres) { switch (dbType) { case DbPlatformType.JSONB: @@ -39,8 +39,8 @@ public class ScalarTypeJsonList { /** * List mapped to DB VARCHAR. */ - public static class Varchar extends ScalarTypeJsonList.Base { - public Varchar(DocPropertyType docType, boolean nullable, boolean keepSource) { + static final class Varchar extends ScalarTypeJsonList.Base { + Varchar(DocPropertyType docType, boolean nullable, boolean keepSource) { super(Types.VARCHAR, docType, nullable, keepSource); } } @@ -48,8 +48,8 @@ public class ScalarTypeJsonList { /** * List mapped to Postgres JSON. */ - private static class Json extends ScalarTypeJsonList.PgBase { - public Json(DocPropertyType docType, boolean nullable, boolean keepSource) { + private final static class Json extends ScalarTypeJsonList.PgBase { + Json(DocPropertyType docType, boolean nullable, boolean keepSource) { super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, docType, nullable, keepSource); } } @@ -57,8 +57,8 @@ public class ScalarTypeJsonList { /** * List mapped to Postgres JSONB. */ - private static class JsonB extends ScalarTypeJsonList.PgBase { - public JsonB(DocPropertyType docType, boolean nullable, boolean keepSource) { + private static final class JsonB extends ScalarTypeJsonList.PgBase { + JsonB(DocPropertyType docType, boolean nullable, boolean keepSource) { super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, docType, nullable, keepSource); } } @@ -68,22 +68,22 @@ public class ScalarTypeJsonList { */ @SuppressWarnings("rawtypes") private abstract static class Base extends ScalarTypeJsonCollection { - private final boolean keepSource; + final boolean keepSource; - public Base(int dbType, DocPropertyType docType, boolean nullable, boolean keepSource) { + private Base(int dbType, DocPropertyType docType, boolean nullable, boolean keepSource) { super(List.class, dbType, docType, nullable); this.keepSource = keepSource; } - + @Override - public boolean isJsonMapper() { + public final boolean isJsonMapper() { return keepSource; } @Override - public List read(DataReader reader) throws SQLException { + public final List read(DataReader reader) throws SQLException { String json = reader.getString(); - if (isJsonMapper()) { + if (keepSource) { reader.pushJson(json); } try { @@ -96,7 +96,7 @@ public class ScalarTypeJsonList { @Override public final void bind(DataBinder binder, List value) throws SQLException { - String rawJson = isJsonMapper() ? binder.popJson() : null; + String rawJson = keepSource ? binder.popJson() : null; if (rawJson == null && value != null) { rawJson = formatValue(value); } @@ -115,15 +115,15 @@ public class ScalarTypeJsonList { binder.setString("[]"); } } - + protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException { binder.setString(rawJson); } @Override - public String formatValue(List value) { + public final String formatValue(List value) { if (value.isEmpty()) { - return "[]"; + return "[]"; } try { return EJson.write(value); @@ -133,7 +133,7 @@ public class ScalarTypeJsonList { } @Override - public List parse(String value) { + public final List parse(String value) { try { return EJson.parseList(value, false); } catch (IOException e) { @@ -142,12 +142,12 @@ public class ScalarTypeJsonList { } @Override - public List jsonRead(JsonParser parser) throws IOException { + public final List jsonRead(JsonParser parser) throws IOException { return EJson.parseList(parser, parser.getCurrentToken()); } @Override - public void jsonWrite(JsonGenerator writer, List value) throws IOException { + public final void jsonWrite(JsonGenerator writer, List value) throws IOException { EJson.write(value, writer); } } @@ -165,12 +165,12 @@ public class ScalarTypeJsonList { } @Override - protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException { + protected final void bindRawJson(DataBinder binder, String rawJson) throws SQLException { binder.setObject(PostgresHelper.asObject(pgType, rawJson)); } @Override - protected void bindNull(DataBinder binder) throws SQLException { + protected final void bindNull(DataBinder binder) throws SQLException { binder.setObject(PostgresHelper.asObject(pgType, nullable ? null : "[]")); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMap.java index 507e7012b..93ecdab79 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMap.java @@ -9,13 +9,7 @@ import io.ebean.core.type.DocPropertyType; import io.ebean.text.TextException; import io.ebean.text.json.EJson; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringWriter; +import java.io.*; import java.nio.charset.StandardCharsets; import java.sql.SQLException; import java.sql.Types; @@ -25,12 +19,12 @@ import java.util.Map; * Type which maps Map to various DB types (Clob, Varchar, Blob) in JSON format. */ @SuppressWarnings("rawtypes") -public abstract class ScalarTypeJsonMap extends ScalarTypeBase { +abstract class ScalarTypeJsonMap extends ScalarTypeBase { /** * Return the ScalarType for the requested dbType and postgres. */ - public static ScalarTypeJsonMap typeFor(boolean postgres, int dbType, boolean keepSource) { + static ScalarTypeJsonMap typeFor(boolean postgres, int dbType, boolean keepSource) { switch (dbType) { case Types.VARCHAR: return new ScalarTypeJsonMap.Varchar(keepSource); @@ -47,9 +41,8 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } } - public static class Clob extends ScalarTypeJsonMap { - - public Clob(boolean keepSource) { + private static final class Clob extends ScalarTypeJsonMap { + Clob(boolean keepSource) { super(Types.CLOB, keepSource); } @@ -59,15 +52,14 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } } - public static class Varchar extends ScalarTypeJsonMap { - - public Varchar(boolean keepSource) { + private static final class Varchar extends ScalarTypeJsonMap { + Varchar(boolean keepSource) { super(Types.VARCHAR, keepSource); } } - public static class Blob extends ScalarTypeJsonMap { - public Blob(boolean keepSource) { + private static final class Blob extends ScalarTypeJsonMap { + Blob(boolean keepSource) { super(Types.BLOB, keepSource); } @@ -75,23 +67,23 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { public Map read(DataReader reader) throws SQLException { InputStream is = reader.getBinaryStream(); if (is == null) { - if (isJsonMapper()) { + if (keepSource) { reader.pushJson(null); } return null; } try { - if (isJsonMapper()) { - StringWriter rawJson = new StringWriter(); - try (InputStreamReader inputStreamReader = new InputStreamReader(is, StandardCharsets.UTF_8)) { - inputStreamReader.transferTo(rawJson); + if (keepSource) { + StringWriter jsonBuffer = new StringWriter(); + try (InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8)) { + transferTo(streamReader, jsonBuffer); } - reader.pushJson(rawJson.toString()); - return parse(rawJson.toString()); - + String rawJson = jsonBuffer.toString(); + reader.pushJson(rawJson); + return parse(rawJson); } else { - try (InputStreamReader inputStreamReader = new InputStreamReader(is, StandardCharsets.UTF_8)) { - return parse(inputStreamReader); + try (InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8)) { + return parse(streamReader); } } } catch (IOException e) { @@ -99,21 +91,29 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } } + private static void transferTo(Reader reader, Writer out) throws IOException { + char[] buffer = new char[2048]; + int nRead; + while ((nRead = reader.read(buffer, 0, 2048)) >= 0) { + out.write(buffer, 0, nRead); + } + } + @Override protected void bindNull(DataBinder binder) throws SQLException { binder.setNull(Types.BLOB); } - + @Override protected void bindJson(DataBinder binder, String rawJson) throws SQLException { binder.setBytes(rawJson.getBytes(StandardCharsets.UTF_8)); } - + } - private final boolean keepSource; - - public ScalarTypeJsonMap(int jdbcType, boolean keepSource) { + final boolean keepSource; + + ScalarTypeJsonMap(int jdbcType, boolean keepSource) { super(Map.class, false, jdbcType); this.keepSource = keepSource; } @@ -122,7 +122,7 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { * Map is a mutable type. Use the isDirty() method to check for dirty state. */ @Override - public boolean isMutable() { + public final boolean isMutable() { return true; } @@ -133,48 +133,41 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { public boolean isDirty(Object value) { return TypeJsonManager.checkIsDirty(value); } - - - + @Override - public boolean isJsonMapper() { + public final boolean isJsonMapper() { return keepSource; } - @Override public Map read(DataReader reader) throws SQLException { String rawJson = readJson(reader); - if (isJsonMapper()) { + if (keepSource) { reader.pushJson(rawJson); } - if (rawJson == null) { return null; } - return parse(rawJson); } - protected String readJson(DataReader reader) throws SQLException { return reader.getString(); } - + @Override public final void bind(DataBinder binder, Map value) throws SQLException { - String rawJson = isJsonMapper() ? binder.popJson() : null; + String rawJson = keepSource ? binder.popJson() : null; if (rawJson == null && value != null) { rawJson = formatValue(value); } - if (value == null) { bindNull(binder); } else { bindJson(binder, rawJson); } } - + protected void bindNull(DataBinder binder) throws SQLException { binder.setNull(Types.VARCHAR); } @@ -182,19 +175,19 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { protected void bindJson(DataBinder binder, String rawJson) throws SQLException { binder.setString(rawJson); } - + @Override - public Object toJdbcType(Object value) { + public final Object toJdbcType(Object value) { return value; } @Override - public Map toBeanType(Object value) { + public final Map toBeanType(Object value) { return (Map) value; } @Override - public String formatValue(Map v) { + public final String formatValue(Map v) { try { return EJson.write(v); } catch (IOException e) { @@ -203,7 +196,7 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } @Override - public Map parse(String value) { + public final Map parse(String value) { try { // return a modify aware map return EJson.parseObject(value, true); @@ -212,7 +205,7 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } } - public Map parse(Reader reader) { + public final Map parse(Reader reader) { try { // return a modify aware map return EJson.parseObject(reader, true); @@ -222,17 +215,17 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } @Override - public Map convertFromMillis(long dateTime) { + public final Map convertFromMillis(long dateTime) { throw new RuntimeException("Should never be called"); } @Override - public boolean isDateTimeCapable() { + public final boolean isDateTimeCapable() { return false; } @Override - public Map readData(DataInput dataInput) throws IOException { + public final Map readData(DataInput dataInput) throws IOException { if (!dataInput.readBoolean()) { return null; } else { @@ -241,7 +234,7 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } @Override - public void writeData(DataOutput dataOutput, Map map) throws IOException { + public final void writeData(DataOutput dataOutput, Map map) throws IOException { if (map == null) { dataOutput.writeBoolean(false); } else { @@ -250,17 +243,17 @@ public abstract class ScalarTypeJsonMap extends ScalarTypeBase { } @Override - public void jsonWrite(JsonGenerator writer, Map value) throws IOException { + public final void jsonWrite(JsonGenerator writer, Map value) throws IOException { EJson.write(value, writer); } @Override - public Map jsonRead(JsonParser parser) throws IOException { + public final Map jsonRead(JsonParser parser) throws IOException { return EJson.parseObject(parser, parser.getCurrentToken()); } @Override - public DocPropertyType getDocType() { + public final DocPropertyType getDocType() { return DocPropertyType.OBJECT; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMapPostgres.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMapPostgres.java index 46a585ebc..ae33fa0e4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMapPostgres.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonMapPostgres.java @@ -8,9 +8,9 @@ import java.sql.SQLException; /** * Support for the Postgres DB types JSON and JSONB. */ -public abstract class ScalarTypeJsonMapPostgres extends ScalarTypeJsonMap { +abstract class ScalarTypeJsonMapPostgres extends ScalarTypeJsonMap { - final String postgresType; + private final String postgresType; ScalarTypeJsonMapPostgres(int jdbcType, String postgresType, boolean keepSource) { super(jdbcType, keepSource); @@ -18,21 +18,21 @@ public abstract class ScalarTypeJsonMapPostgres extends ScalarTypeJsonMap { } @Override - protected void bindNull(DataBinder binder) throws SQLException { + protected final void bindNull(DataBinder binder) throws SQLException { binder.setObject(PostgresHelper.asObject(postgresType, null)); } - + @Override - protected void bindJson(DataBinder binder, String rawJson) throws SQLException { + protected final void bindJson(DataBinder binder, String rawJson) throws SQLException { binder.setObject(PostgresHelper.asObject(postgresType, rawJson)); } /** * ScalarType mapping java Map type to Postgres JSON database type. */ - public static class JSON extends ScalarTypeJsonMapPostgres { + static final class JSON extends ScalarTypeJsonMapPostgres { - public JSON(boolean keepSource) { + JSON(boolean keepSource) { super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, keepSource); } } @@ -40,9 +40,9 @@ public abstract class ScalarTypeJsonMapPostgres extends ScalarTypeJsonMap { /** * ScalarType mapping java Map type to Postgres JSONB database type. */ - public static class JSONB extends ScalarTypeJsonMapPostgres { + static final class JSONB extends ScalarTypeJsonMapPostgres { - public JSONB(boolean keepSource) { + JSONB(boolean keepSource) { super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, keepSource); } } 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 41cb28d49..65cb88cdc 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 @@ -46,7 +46,7 @@ class ScalarTypeJsonObjectMapper { /** * No mutation detection on this json property. */ - private static class NoMutationDetection extends Base { + private static final class NoMutationDetection extends Base { NoMutationDetection(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) { super(Object.class, jsonManager, field, dbType, docType); @@ -66,7 +66,7 @@ class ScalarTypeJsonObjectMapper { /** * Supports HASH and SOURCE dirty detection modes. */ - private static class GenericObject extends Base { + private static final class GenericObject extends Base { GenericObject(TypeJsonManager jsonManager, AnnotatedField field, int dbType, DocPropertyType docType) { super(Object.class, jsonManager, field, dbType, docType); @@ -167,20 +167,20 @@ class ScalarTypeJsonObjectMapper { } @Override - public Object toJdbcType(Object value) { + public final Object toJdbcType(Object value) { // no type conversion supported return value; } @Override @SuppressWarnings("unchecked") - public T toBeanType(Object value) { + public final T toBeanType(Object value) { // no type conversion supported return (T) value; } @Override - public String formatValue(T value) { + public final String formatValue(T value) { try { return objectWriter.writeValueAsString(value); } catch (JsonProcessingException e) { @@ -189,7 +189,7 @@ class ScalarTypeJsonObjectMapper { } @Override - public T parse(String value) { + public final T parse(String value) { try { return objectReader.readValue(value, deserType); } catch (IOException e) { @@ -198,32 +198,32 @@ class ScalarTypeJsonObjectMapper { } @Override - public DocPropertyType getDocType() { + public final DocPropertyType getDocType() { return docType; } @Override - public boolean isDateTimeCapable() { + public final boolean isDateTimeCapable() { return false; } @Override - public T convertFromMillis(long dateTime) { + public final T convertFromMillis(long dateTime) { throw new IllegalStateException("Not supported"); } @Override - public T jsonRead(JsonParser parser) throws IOException { + public final T jsonRead(JsonParser parser) throws IOException { return objectReader.readValue(parser, deserType); } @Override - public void jsonWrite(JsonGenerator writer, T value) throws IOException { + public final void jsonWrite(JsonGenerator writer, T value) throws IOException { objectWriter.writeValue(writer, value); } @Override - public T readData(DataInput dataInput) throws IOException { + public final T readData(DataInput dataInput) throws IOException { if (!dataInput.readBoolean()) { return null; } else { @@ -232,7 +232,7 @@ class ScalarTypeJsonObjectMapper { } @Override - public void writeData(DataOutput dataOutput, T value) throws IOException { + public final void writeData(DataOutput dataOutput, T value) throws IOException { if (value == null) { dataOutput.writeBoolean(false); } else { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java index 7e728b0d3..86a39443e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java @@ -21,12 +21,12 @@ import java.util.Set; /** * Types for mapping List in JSON format to DB types VARCHAR, JSON and JSONB. */ -public class ScalarTypeJsonSet { +final class ScalarTypeJsonSet { /** * Return the appropriate ScalarType for the requested dbType and Postgres. */ - public static ScalarType typeFor(boolean postgres, int dbType, DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { + static ScalarType typeFor(boolean postgres, int dbType, DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { if (postgres) { switch (dbType) { case DbPlatformType.JSONB: @@ -41,7 +41,7 @@ public class ScalarTypeJsonSet { /** * List mapped to DB VARCHAR. */ - public static class Varchar extends ScalarTypeJsonSet.Base { + static final class Varchar extends ScalarTypeJsonSet.Base { public Varchar(DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { super(Types.VARCHAR, docPropertyType, nullable, keepSource); } @@ -50,8 +50,8 @@ public class ScalarTypeJsonSet { /** * List mapped to Postgres JSON. */ - private static class Json extends ScalarTypeJsonSet.PgBase { - public Json(DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { + private static final class Json extends ScalarTypeJsonSet.PgBase { + private Json(DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { super(DbPlatformType.JSON, PostgresHelper.JSON_TYPE, docPropertyType, nullable, keepSource); } } @@ -59,35 +59,31 @@ public class ScalarTypeJsonSet { /** * List mapped to Postgres JSONB. */ - private static class JsonB extends ScalarTypeJsonSet.PgBase { - public JsonB(DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { + private static final class JsonB extends ScalarTypeJsonSet.PgBase { + private JsonB(DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { super(DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE, docPropertyType, nullable, keepSource); } } - /** - * Base class for List handling. - */ @SuppressWarnings("rawtypes") private abstract static class Base extends ScalarTypeJsonCollection { - private boolean keepSource; - - public Base(int dbType, DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { + final boolean keepSource; + + private Base(int dbType, DocPropertyType docPropertyType, boolean nullable, boolean keepSource) { super(Set.class, dbType, docPropertyType, nullable); this.keepSource = keepSource; } - @Override - public boolean isJsonMapper() { + public final boolean isJsonMapper() { return keepSource; } - + @Override - public Set read(DataReader reader) throws SQLException { + public final Set read(DataReader reader) throws SQLException { String json = reader.getString(); - if (isJsonMapper()) { + if (keepSource) { reader.pushJson(json); } try { @@ -100,7 +96,7 @@ public class ScalarTypeJsonSet { @Override public final void bind(DataBinder binder, Set value) throws SQLException { - String rawJson = isJsonMapper() ? binder.popJson() : null; + String rawJson = keepSource ? binder.popJson() : null; if (rawJson == null && value != null) { rawJson = formatValue(value); } @@ -125,7 +121,7 @@ public class ScalarTypeJsonSet { } @Override - public String formatValue(Set value) { + public final String formatValue(Set value) { if (value.isEmpty()) { return "[]"; } @@ -137,7 +133,7 @@ public class ScalarTypeJsonSet { } @Override - public Set parse(String value) { + public final Set parse(String value) { try { return convertList(EJson.parseList(value)); } catch (IOException e) { @@ -146,12 +142,12 @@ public class ScalarTypeJsonSet { } @Override - public Set jsonRead(JsonParser parser) throws IOException { + public final Set jsonRead(JsonParser parser) throws IOException { return convertList(EJson.parseList(parser, parser.getCurrentToken())); } @Override - public void jsonWrite(JsonGenerator writer, Set value) throws IOException { + public final void jsonWrite(JsonGenerator writer, Set value) throws IOException { EJson.write(value, writer); } @@ -174,12 +170,12 @@ public class ScalarTypeJsonSet { } @Override - protected void bindRawJson(DataBinder binder, String rawJson) throws SQLException { + protected final void bindRawJson(DataBinder binder, String rawJson) throws SQLException { binder.setObject(PostgresHelper.asObject(pgType, rawJson)); } @Override - protected void bindNull(DataBinder binder) throws SQLException { + protected final void bindNull(DataBinder binder) throws SQLException { binder.setObject(PostgresHelper.asObject(pgType, nullable ? null : "[]")); } } From 587b2e3075f359941d72fa67eb2e3676b5eba23c Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 15 Aug 2021 14:09:44 +1200 Subject: [PATCH 089/120] #2310 Tidy to only cast once --- .../server/deploy/BeanPropertyJsonMapper.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java index f1b77f4bd..bb234664f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyJsonMapper.java @@ -19,7 +19,7 @@ import java.util.Objects; /** * Handle json property with MutationDetection of SOURCE or HASH only. */ -public class BeanPropertyJsonMapper extends BeanPropertyJsonBasic { +public final class BeanPropertyJsonMapper extends BeanPropertyJsonBasic { private final boolean sourceDetection; @@ -105,14 +105,15 @@ public class BeanPropertyJsonMapper extends BeanPropertyJsonBasic { throw new PersistenceException("Error readSet on " + descriptor + "." + name, e); } } - + @Override public void setCacheDataValue(EntityBean bean, Object cacheData, PersistenceContext context) { if (cacheData instanceof String) { // parse back from string to support optimisation of java object serialisation - final MutableValueInfo hash = createMutableInfo((String)cacheData); + final String jsonContent = (String) cacheData; + final MutableValueInfo hash = createMutableInfo(jsonContent); bean._ebean_getIntercept().mutableInfo(propertyIndex, hash); - cacheData = scalarType.parse((String) cacheData); + cacheData = scalarType.parse(jsonContent); } setValue(bean, cacheData); } From ebc0fabbdb05fff1db1e05e1d883cbedc4ed8fcf Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 15 Aug 2021 14:15:03 +1200 Subject: [PATCH 090/120] #2311 - Fix BindPadding for empty list --- .../src/main/java/io/ebeaninternal/server/core/BindPadding.java | 2 +- .../test/java/io/ebeaninternal/server/core/BindPaddingTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/BindPadding.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/BindPadding.java index 75963723e..8659fabfd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/BindPadding.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/BindPadding.java @@ -33,7 +33,7 @@ public final class BindPadding { * Extra padding on binding id's in order to get better hit ratio on DB prepared statements / query plans. */ static int padding(int size) { - if (size == 1) { + if (size <= 1) { return 0; } if (size <= 5) { diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/core/BindPaddingTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/core/BindPaddingTest.java index d0363d2c6..483963fcc 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/core/BindPaddingTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/core/BindPaddingTest.java @@ -29,7 +29,7 @@ public class BindPaddingTest { @Test public void padding() { - + assertEquals(0, BindPadding.padding(0)); assertEquals(0, BindPadding.padding(1)); assertEquals(3, BindPadding.padding(2)); assertEquals(2, BindPadding.padding(3)); From 82c12b1565adde4339602a5a37e1025b11424a25 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 15 Aug 2021 14:50:43 +1200 Subject: [PATCH 091/120] #2312 - Refactor internals - make more classes final in persist packages --- .../server/persist/BatchDepthComparator.java | 2 +- .../server/persist/BatchDepthOrder.java | 4 ++-- .../server/persist/BatchedBeanHolder.java | 2 +- .../ebeaninternal/server/persist/BatchedPstmt.java | 2 +- .../server/persist/BatchedPstmtHolder.java | 2 +- .../io/ebeaninternal/server/persist/Binder.java | 2 +- .../server/persist/DeleteIdRequest.java | 2 +- .../server/persist/DeleteUnloadedForeignKeys.java | 2 +- .../io/ebeaninternal/server/persist/DmlUtil.java | 2 +- .../server/persist/ExeCallableSql.java | 10 +--------- .../ebeaninternal/server/persist/ExeOrmUpdate.java | 10 +--------- .../ebeaninternal/server/persist/ExeUpdateSql.java | 14 +------------- .../ebeaninternal/server/persist/MergeContext.java | 2 +- .../ebeaninternal/server/persist/MergeHandler.java | 10 +--------- .../io/ebeaninternal/server/persist/MergeNode.java | 13 +++++-------- .../server/persist/MergeNodeAssocManyToMany.java | 8 +------- .../server/persist/MergeNodeAssocOne.java | 3 +-- .../server/persist/MergeNodeAssocOneToMany.java | 5 +---- .../ebeaninternal/server/persist/MergeRequest.java | 3 +-- .../server/persist/MultiValueWrapper.java | 2 +- .../ebeaninternal/server/persist/PstmtFactory.java | 5 +---- .../ebeaninternal/server/persist/SaveManyBase.java | 8 ++++---- .../server/persist/SaveManyBeans.java | 2 +- .../server/persist/SaveManyElementCollection.java | 2 +- .../persist/SaveManyElementCollectionMap.java | 2 +- .../ebeaninternal/server/persist/TrimLogSql.java | 2 +- .../ebeaninternal/server/persist/dml/BaseMeta.java | 4 +--- .../server/persist/dml/DeleteHandler.java | 2 +- .../server/persist/dml/DeleteMeta.java | 1 - .../server/persist/dml/DmlBeanPersister.java | 2 +- .../persist/dml/DmlBeanPersisterFactory.java | 2 +- .../server/persist/dml/DocStoreBeanPersister.java | 2 +- .../server/persist/dml/GenerateDmlRequest.java | 12 ++---------- .../server/persist/dml/GeneratedProperties.java | 2 +- .../persist/dml/GeneratedPropertyCollector.java | 2 +- .../server/persist/dml/InsertHandler.java | 2 +- .../server/persist/dml/MetaFactory.java | 2 +- .../server/persist/dml/UpdateHandler.java | 2 +- .../server/persist/dml/UpdatePlan.java | 2 +- .../server/persist/dmlbind/BindableAssocOne.java | 9 ++++----- .../persist/dmlbind/BindableAssocTenant.java | 3 +-- .../persist/dmlbind/BindableDiscriminator.java | 2 +- .../server/persist/dmlbind/BindableEmbedded.java | 6 +++--- .../persist/dmlbind/BindableEncryptedProperty.java | 4 ++-- .../server/persist/dmlbind/BindableIdEmpty.java | 2 +- .../server/persist/dmlbind/BindableIdScalar.java | 4 ++-- .../server/persist/dmlbind/BindableList.java | 2 +- .../persist/dmlbind/BindableOrderColumn.java | 3 +-- .../server/persist/dmlbind/BindableProperty.java | 11 +++++------ .../dmlbind/BindablePropertyJsonInsert.java | 2 +- .../dmlbind/BindablePropertyJsonUpdate.java | 2 +- .../persist/dmlbind/BindablePropertyVersion.java | 4 ++-- .../persist/dmlbind/BindableUnidirectional.java | 9 +-------- .../server/persist/dmlbind/FactoryAssocOnes.java | 6 +----- .../persist/dmlbind/FactoryBaseProperties.java | 4 +--- .../server/persist/dmlbind/FactoryEmbedded.java | 3 +-- .../server/persist/dmlbind/FactoryId.java | 7 +------ .../server/persist/dmlbind/FactoryProperty.java | 2 +- .../server/persist/dmlbind/FactoryVersion.java | 9 +-------- .../persist/dmlbind/MatchedImportedEmbedded.java | 4 +--- .../persist/dmlbind/MatchedImportedFactory.java | 14 +++----------- .../persist/dmlbind/MatchedImportedScalar.java | 4 +--- .../server/persist/platform/MultiValueBind.java | 1 - .../persist/platform/PostgresMultiValueBind.java | 2 +- 64 files changed, 85 insertions(+), 192 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchDepthComparator.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchDepthComparator.java index 7606599d9..66756b4a1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchDepthComparator.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchDepthComparator.java @@ -12,7 +12,7 @@ import java.util.Comparator; * keys from inserts. These values are required to persist the 'detail' beans. *

*/ -class BatchDepthComparator implements Comparator, Serializable { +final class BatchDepthComparator implements Comparator, Serializable { private static final long serialVersionUID = 264611821665757991L; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchDepthOrder.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchDepthOrder.java index 3817f43bd..bb0b4bcfa 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchDepthOrder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchDepthOrder.java @@ -6,7 +6,7 @@ import java.util.Map; /** * Helper to determine batch execution order for BatchedBeanHolders. */ -class BatchDepthOrder { +final class BatchDepthOrder { private final Map map = new HashMap<>(); @@ -22,7 +22,7 @@ class BatchDepthOrder { map.clear(); } - private static class Counter { + private static final class Counter { int count; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedBeanHolder.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedBeanHolder.java index db43c32d0..db6d85a35 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedBeanHolder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedBeanHolder.java @@ -18,7 +18,7 @@ import java.util.ArrayList; * executed. The lowest depth is executed first. *

*/ -class BatchedBeanHolder { +final class BatchedBeanHolder { /** * The owning queue. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmt.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmt.java index 0a764e35b..9afd4d6e8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmt.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmt.java @@ -20,7 +20,7 @@ import java.util.List; * This can hold CallableStatements as well. *

*/ -public class BatchedPstmt implements SpiProfileTransactionEvent { +public final class BatchedPstmt implements SpiProfileTransactionEvent { private static final Logger log = LoggerFactory.getLogger(BatchedPstmt.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmtHolder.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmtHolder.java index 4bd892bd4..50ed43900 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmtHolder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/BatchedPstmtHolder.java @@ -15,7 +15,7 @@ import java.util.Map; * statements of a single 'depth' at any given time. *

*/ -public class BatchedPstmtHolder { +public final class BatchedPstmtHolder { /** * A Map of the statements using a String key. This is used so that the same diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/Binder.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/Binder.java index 600a7e21a..bec0223d0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/Binder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/Binder.java @@ -31,7 +31,7 @@ import java.util.List; /** * Binds bean values to a PreparedStatement. */ -public class Binder { +public final class Binder { private static final Logger logger = LoggerFactory.getLogger(Binder.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DeleteIdRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DeleteIdRequest.java index e086e2630..760d9eda3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DeleteIdRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DeleteIdRequest.java @@ -5,7 +5,7 @@ import io.ebean.Transaction; import io.ebean.event.BeanDeleteIdRequest; import io.ebeaninternal.api.SpiEbeanServer; -class DeleteIdRequest implements BeanDeleteIdRequest { +final class DeleteIdRequest implements BeanDeleteIdRequest { private final EbeanServer server; private final Transaction transaction; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DeleteUnloadedForeignKeys.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DeleteUnloadedForeignKeys.java index c3065b779..1c258b5bb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DeleteUnloadedForeignKeys.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DeleteUnloadedForeignKeys.java @@ -21,7 +21,7 @@ import java.util.List; * helps fetch the foreign keys and delete the appropriate rows. *

*/ -class DeleteUnloadedForeignKeys { +final class DeleteUnloadedForeignKeys { private final List> propList = new ArrayList<>(4); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DmlUtil.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DmlUtil.java index 46ce61d33..c7693f6e8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/DmlUtil.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/DmlUtil.java @@ -4,7 +4,7 @@ package io.ebeaninternal.server.persist; /** * Utility object with helper methods for DML. */ -public class DmlUtil { +public final class DmlUtil { /** * Return true if the value is null or a Numeric 0 (for primitive int's and long's) or Option empty. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeCallableSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeCallableSql.java index 2c01fcd31..fc2c1e0e5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeCallableSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeCallableSql.java @@ -13,10 +13,9 @@ import java.sql.SQLException; /** * Handles the execution of CallableSql requests. */ -class ExeCallableSql { +final class ExeCallableSql { private final Binder binder; - private final PstmtFactory pstmtFactory; ExeCallableSql(Binder binder) { @@ -28,9 +27,7 @@ class ExeCallableSql { * execute the CallableSql requests. */ public int execute(PersistRequestCallableSql request) { - boolean batchThisRequest = request.isBatchThisRequest(); - CallableStatement cstmt = null; try { cstmt = bindStmt(request, batchThisRequest); @@ -58,18 +55,15 @@ class ExeCallableSql { private CallableStatement bindStmt(PersistRequestCallableSql request, boolean batchThisRequest) throws SQLException { - request.startBind(batchThisRequest); SpiCallableSql callableSql = request.getCallableSql(); SpiTransaction t = request.getTransaction(); String sql = callableSql.getSql(); - BindParams bindParams = callableSql.getBindParams(); // process named parameters if required sql = BindParamsParser.parse(bindParams, sql); - boolean logSql = request.isLogSql(); CallableStatement cstmt; @@ -90,9 +84,7 @@ class ExeCallableSql { if (!bindParams.isEmpty()) { bindLog = binder.bind(bindParams, cstmt, t.getInternalConnection()); } - request.setBindLog(bindLog); - // required to read OUT params later request.setBound(bindParams, cstmt); return cstmt; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeOrmUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeOrmUpdate.java index d79a4d66f..ee9ffad23 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeOrmUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeOrmUpdate.java @@ -15,15 +15,11 @@ import java.sql.SQLException; /** * Executes the UpdateSql requests. */ -class ExeOrmUpdate { +final class ExeOrmUpdate { private final Binder binder; - private final PstmtFactory pstmtFactory; - /** - * Create with a given binder. - */ ExeOrmUpdate(Binder binder) { this.pstmtFactory = new PstmtFactory(); this.binder = binder; @@ -33,9 +29,7 @@ class ExeOrmUpdate { * Execute the orm update request. */ public int execute(PersistRequestOrmUpdate request) { - boolean batchThisRequest = request.isBatchThisRequest(); - PreparedStatement pstmt = null; try { pstmt = bindStmt(request, batchThisRequest); @@ -68,13 +62,11 @@ class ExeOrmUpdate { * Convert bean and property names to db table and columns. */ private String translate(PersistRequestOrmUpdate request, String sql) { - BeanDescriptor descriptor = request.getBeanDescriptor(); return descriptor.convertOrmUpdateToSql(sql); } private PreparedStatement bindStmt(PersistRequestOrmUpdate request, boolean batchThisRequest) throws SQLException { - request.startBind(batchThisRequest); SpiUpdate ormUpdate = request.getOrmUpdate(); SpiTransaction t = request.getTransaction(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeUpdateSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeUpdateSql.java index cea7560c9..75627671f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeUpdateSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/ExeUpdateSql.java @@ -16,15 +16,11 @@ import java.sql.SQLException; /** * Executes the UpdateSql requests. */ -class ExeUpdateSql { +final class ExeUpdateSql { private final Binder binder; - private final PstmtFactory pstmtFactory; - /** - * Create with a given binder. - */ ExeUpdateSql(Binder binder) { this.binder = binder; this.pstmtFactory = new PstmtFactory(); @@ -34,14 +30,10 @@ class ExeUpdateSql { * Execute the UpdateSql request. */ public int execute(PersistRequestUpdateSql request) { - boolean batchThisRequest = request.isBatchThisRequest(); - PreparedStatement pstmt = null; try { - pstmt = bindStmt(request, batchThisRequest); - if (batchThisRequest) { pstmt.addBatch(); // return -1 to indicate batch mode @@ -66,7 +58,6 @@ class ExeUpdateSql { } private void readGeneratedKeys(PreparedStatement stmt, PersistRequestUpdateSql request) { - ResultSet resultSet = null; try { resultSet = stmt.getGeneratedKeys(); @@ -82,7 +73,6 @@ class ExeUpdateSql { } private PreparedStatement bindStmt(PersistRequestUpdateSql request, boolean batchThisRequest) throws SQLException { - request.startBind(batchThisRequest); SpiSqlUpdate updateSql = request.getUpdateSql(); SpiTransaction t = request.getTransaction(); @@ -121,7 +111,6 @@ class ExeUpdateSql { private void determineType(String word1, String word2, String word3, PersistRequestUpdateSql request) { - if (word1.equalsIgnoreCase("UPDATE")) { request.setType(SqlType.SQL_UPDATE, word2); @@ -137,7 +126,6 @@ class ExeUpdateSql { } private void parseUpdate(String sql, PersistRequestUpdateSql request) { - int[] pos = new int[3]; int spaceCount = 0; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeContext.java index bdd6ce855..e3cb0d5e2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeContext.java @@ -10,7 +10,7 @@ import java.util.List; /** * Context used for merge processing. */ -class MergeContext { +final class MergeContext { private final SpiEbeanServer server; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeHandler.java index b2d53ba40..3e09a44f9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeHandler.java @@ -24,7 +24,7 @@ import java.util.regex.Pattern; /** * Drives the merge processing. */ -class MergeHandler { +final class MergeHandler { private static final Pattern PATH_SPLIT = Pattern.compile("\\."); @@ -33,10 +33,8 @@ class MergeHandler { private final EntityBean bean; private final MergeOptions options; private final SpiTransaction transaction; - private final Map nodes = new LinkedHashMap<>(); - MergeHandler(SpiEbeanServer server, BeanDescriptor desc, EntityBean bean, MergeOptions options, SpiTransaction transaction) { this.server = server; this.desc = desc; @@ -49,7 +47,6 @@ class MergeHandler { * Fetch the Ids for the graph and use them to determine inserts, updates and deletes for the merge paths. */ List merge() { - Set paths = options.paths(); if (desc.isIdGeneratedValue() && paths.isEmpty() && !options.isClientGeneratedIds()) { // just do a single insert or update based on Id value present @@ -76,7 +73,6 @@ class MergeHandler { for (MergeNode value : nodes.values()) { value.merge(request); } - return context.getDeletedBeans(); } @@ -86,9 +82,7 @@ class MergeHandler { * We use the Id values to determine what are inserts, updates and deletes as part of the merge. */ private EntityBean fetchOutline(Set paths) { - Query query = server.find(desc.getBeanType()); - query.setBeanCacheMode(CacheMode.OFF); query.setPersistenceContextScope(PersistenceContextScope.QUERY); query.setId(desc.getId(bean)); @@ -126,14 +120,12 @@ class MergeHandler { } private MergeNode addRootLevelNode(String rootPath) { - MergeNode node = createMergeNode(rootPath, desc, rootPath); nodes.put(rootPath, node); return node; } static MergeNode createMergeNode(String fullPath, BeanDescriptor targetDesc, String path) { - BeanProperty prop = targetDesc.getBeanProperty(path); if (!(prop instanceof BeanPropertyAssoc)) { throw new PersistenceException("merge path [" + path + "] is not a ToMany or ToOne property of " + targetDesc.getFullName()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNode.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNode.java index fa2dc398e..cc5ebeaba 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNode.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNode.java @@ -33,7 +33,7 @@ abstract class MergeNode { /** * Add a child node given the fullPath and relative path. */ - MergeNode addChild(String fullPath, String path) { + final MergeNode addChild(String fullPath, String path) { MergeNode childNode = MergeHandler.createMergeNode(fullPath, targetDescriptor, path); if (children == null) { children = new LinkedHashMap<>(); @@ -45,7 +45,7 @@ abstract class MergeNode { /** * Return the node given the relative path. */ - MergeNode get(String path) { + final MergeNode get(String path) { if (children != null) { return children.get(path); } @@ -55,8 +55,7 @@ abstract class MergeNode { /** * Return the outline beans as a map keyed by Id values. */ - Map toMap(Collection outlines) { - + final Map toMap(Collection outlines) { Map outlineMap = new HashMap<>(); if (outlines != null) { for (Object out : outlines) { @@ -71,8 +70,7 @@ abstract class MergeNode { /** * Add to the query to fetch the Ids values for the foreign keys basically. */ - void addSelectId(Query query) { - + final void addSelectId(Query query) { BeanProperty idProperty = targetDescriptor.getIdProperty(); query.fetch(fullPath, idProperty.getName()); } @@ -80,8 +78,7 @@ abstract class MergeNode { /** * Cascade the merge processing if this has child nodes. */ - void cascade(EntityBean entityBean, EntityBean outlineBean, MergeRequest request) { - + final void cascade(EntityBean entityBean, EntityBean outlineBean, MergeRequest request) { if (children != null && !children.isEmpty()) { MergeRequest sub = request.sub(entityBean, outlineBean); for (MergeNode node : children.values()) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocManyToMany.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocManyToMany.java index 7fd74e8a9..02acdf3f9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocManyToMany.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocManyToMany.java @@ -15,7 +15,7 @@ import java.util.Map; /** * Node for processing merge on ManyToMany properties. */ -class MergeNodeAssocManyToMany extends MergeNode { +final class MergeNodeAssocManyToMany extends MergeNode { private final BeanPropertyAssocMany many; @@ -26,14 +26,11 @@ class MergeNodeAssocManyToMany extends MergeNode { @Override public void merge(MergeRequest request) { - EntityBean parentBean = request.getBean(); - Collection beans = many.getRawCollection(parentBean); Collection outlines = many.getRawCollection(request.getOutline()); Map outlineIds = toMap(outlines); - List additions = new ArrayList<>(); if (beans != null) { for (Object bean : beans) { @@ -57,7 +54,6 @@ class MergeNodeAssocManyToMany extends MergeNode { if (!deletions.isEmpty()) { transaction.flush(); - SqlUpdate delete = intersectionTable.delete(server, false); for (EntityBean deletion : deletions) { many.intersectionBind(delete, parentBean, deletion); @@ -68,7 +64,6 @@ class MergeNodeAssocManyToMany extends MergeNode { if (!additions.isEmpty()) { transaction.flush(); - SqlUpdate insert = intersectionTable.insert(server, false); for (EntityBean addition : additions) { many.intersectionBind(insert, parentBean, addition); @@ -76,7 +71,6 @@ class MergeNodeAssocManyToMany extends MergeNode { } insert.execute(); } - many.resetMany(parentBean); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocOne.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocOne.java index 90f44e07f..68438bf40 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocOne.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocOne.java @@ -8,7 +8,7 @@ import java.util.Objects; /** * Node for processing merge on ToOne properties. */ -class MergeNodeAssocOne extends MergeNode { +final class MergeNodeAssocOne extends MergeNode { private final BeanPropertyAssocOne one; @@ -19,7 +19,6 @@ class MergeNodeAssocOne extends MergeNode { @Override public void merge(MergeRequest request) { - EntityBean entityBean = getEntityBean(request.getBean()); if (entityBean == null) { checkOrphanRemoval(request); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocOneToMany.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocOneToMany.java index a75ea26fb..8372c955d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocOneToMany.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeNodeAssocOneToMany.java @@ -9,7 +9,7 @@ import java.util.Map; /** * Node for processing merge on ToMany properties. */ -class MergeNodeAssocOneToMany extends MergeNode { +final class MergeNodeAssocOneToMany extends MergeNode { private final BeanPropertyAssocMany many; @@ -20,12 +20,10 @@ class MergeNodeAssocOneToMany extends MergeNode { @Override public void merge(MergeRequest request) { - Collection beans = many.getRawCollection(request.getBean()); Collection outlines = many.getRawCollection(request.getOutline()); Map outlineIds = toMap(outlines); - if (beans != null) { for (Object bean : beans) { EntityBean entityBean = (EntityBean) bean; @@ -40,7 +38,6 @@ class MergeNodeAssocOneToMany extends MergeNode { } } } - // any remaining are considered deletes for (EntityBean outlineBean : outlineIds.values()) { request.addDelete(outlineBean); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeRequest.java index 1826e749e..d893fd999 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MergeRequest.java @@ -7,11 +7,10 @@ import io.ebeaninternal.api.SpiTransaction; /** * Request object used for processing the merge. */ -class MergeRequest { +final class MergeRequest { private final EntityBean bean; private final EntityBean outline; - private final MergeContext context; MergeRequest(MergeContext context, EntityBean bean, EntityBean outline) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MultiValueWrapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MultiValueWrapper.java index 36104822a..5e23a66cd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/MultiValueWrapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/MultiValueWrapper.java @@ -6,7 +6,7 @@ import java.util.Collection; * Wraps the multi values that are used for "property in (...)" queries * @author Roland Praml, FOCONIS AG */ -public class MultiValueWrapper { +public final class MultiValueWrapper { private final Collection values; private final Class type; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/PstmtFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/PstmtFactory.java index 14b24dd3b..fb47147da 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/PstmtFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/PstmtFactory.java @@ -15,10 +15,7 @@ import java.sql.Statement; * getGeneratedKeys. *

*/ -class PstmtFactory { - - PstmtFactory() { - } +final class PstmtFactory { /** * Get a callable statement without any batching. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBase.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBase.java index f305e3244..a31cee3f2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBase.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBase.java @@ -46,20 +46,20 @@ abstract class SaveManyBase implements SaveMany { */ abstract void save(); - void preElementCollectionUpdate() { + final void preElementCollectionUpdate() { if (!insertedParent) { request.preElementCollectionUpdate(); persister.addToFlushQueue(many.deleteByParentId(request.getBeanId(), null), transaction, 1); } } - void resetModifyState() { + final void resetModifyState() { if (value instanceof BeanCollection) { modifyListenReset((BeanCollection) value); } } - void modifyListenReset(BeanCollection c) { + final void modifyListenReset(BeanCollection c) { if (insertedParent) { // after insert set the modify listening mode for private owned etc c.setModifyListening(many.getModifyListenMode()); @@ -67,7 +67,7 @@ abstract class SaveManyBase implements SaveMany { c.modifyReset(); } - void postElementCollectionUpdate() { + final void postElementCollectionUpdate() { if (!insertedParent) { if (request.isNotifyCache()) { try { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java index 1f1da9fc0..33edf8dd8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyBeans.java @@ -26,7 +26,7 @@ import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; /** * Saves the details for a OneToMany or ManyToMany relationship (entity beans). */ -public class SaveManyBeans extends SaveManyBase { +public final class SaveManyBeans extends SaveManyBase { private static final Logger log = LoggerFactory.getLogger(SaveManyBeans.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyElementCollection.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyElementCollection.java index 53f638114..8b577da93 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyElementCollection.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyElementCollection.java @@ -11,7 +11,7 @@ import java.util.Collection; /** * Save details for a simple scalar element collection. */ -class SaveManyElementCollection extends SaveManyBase { +final class SaveManyElementCollection extends SaveManyBase { private Collection collection; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyElementCollectionMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyElementCollectionMap.java index 60dd2e01d..2941a1499 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyElementCollectionMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/SaveManyElementCollectionMap.java @@ -12,7 +12,7 @@ import java.util.Set; /** * Save details for a simple scalar map element collection. */ -class SaveManyElementCollectionMap extends SaveManyBase { +final class SaveManyElementCollectionMap extends SaveManyBase { private Set> entries; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/TrimLogSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/TrimLogSql.java index 1ab6349a0..f38490420 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/TrimLogSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/TrimLogSql.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.persist; /** * Utility to improve logging of raw SQL that contains new line characters. */ -public class TrimLogSql { +public final class TrimLogSql { /** * Replace new line chars for nicer logging of multi-line sql strings. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/BaseMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/BaseMeta.java index d7ed5c90c..872119060 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/BaseMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/BaseMeta.java @@ -16,19 +16,17 @@ class BaseMeta { this.tenantId = tenantId; } - String appendWhere(GenerateDmlRequest request, ConcurrencyMode conMode) { + final String appendWhere(GenerateDmlRequest request, ConcurrencyMode conMode) { request.setWhereIdMode(); id.dmlAppend(request); if (tenantId != null) { tenantId.dmlAppend(request); } - if (ConcurrencyMode.VERSION == conMode) { if (version != null) { version.dmlAppend(request); } } - return request.toString(); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteHandler.java index 9320a49fa..846e88f80 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteHandler.java @@ -10,7 +10,7 @@ import java.sql.SQLException; /** * Delete bean handler. */ -public class DeleteHandler extends DmlHandler { +final class DeleteHandler extends DmlHandler { private final DeleteMeta meta; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteMeta.java index ccb196947..7baac04ab 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DeleteMeta.java @@ -30,7 +30,6 @@ final class DeleteMeta extends BaseMeta { String draftTableName = desc.getDraftTable(); this.sqlDraftNone = genSql(ConcurrencyMode.NONE, draftTableName); this.sqlDraftVersion = genSql(ConcurrencyMode.VERSION, draftTableName); - } else { this.sqlDraftNone = sqlNone; this.sqlDraftVersion = sqlVersion; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersister.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersister.java index f07d207b8..f9d592cf3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersister.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersister.java @@ -16,7 +16,7 @@ import java.sql.SQLException; * a flat list of Bindable objects. *

*/ -public final class DmlBeanPersister implements BeanPersister { +final class DmlBeanPersister implements BeanPersister { private final DatabasePlatform dbPlatform; private final UpdateMeta updateMeta; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersisterFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersisterFactory.java index 6e349dee1..c9b4cadea 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersisterFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DmlBeanPersisterFactory.java @@ -8,7 +8,7 @@ import io.ebeaninternal.server.persist.BeanPersisterFactory; /** * Factory for creating a DmlBeanPersister for a bean type. */ -public class DmlBeanPersisterFactory implements BeanPersisterFactory { +public final class DmlBeanPersisterFactory implements BeanPersisterFactory { private final DatabasePlatform dbPlatform; private final MetaFactory metaFactory; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DocStoreBeanPersister.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DocStoreBeanPersister.java index 9bbe7bfcd..9b9a9c2cf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DocStoreBeanPersister.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/DocStoreBeanPersister.java @@ -8,7 +8,7 @@ import javax.persistence.PersistenceException; /** * Document store based BeanPersister. */ -class DocStoreBeanPersister implements BeanPersister { +final class DocStoreBeanPersister implements BeanPersister { private final GeneratedProperties generatedProperties; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GenerateDmlRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GenerateDmlRequest.java index 809115563..ab292163d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GenerateDmlRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GenerateDmlRequest.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.persist.dml; /** * Helper to support the generation of DML statements. */ -public class GenerateDmlRequest { +public final class GenerateDmlRequest { private final StringBuilder sb = new StringBuilder(100); private StringBuilder insertBindBuffer; @@ -12,13 +12,7 @@ public class GenerateDmlRequest { private int insertMode; private int bindColumnCount; - /** - * Create from a PersistRequestBean. - */ - public GenerateDmlRequest() { - } - - public GenerateDmlRequest append(String s) { + GenerateDmlRequest append(String s) { sb.append(s); return this; } @@ -30,7 +24,6 @@ public class GenerateDmlRequest { public void appendColumn(String column, String bind) { ++bindColumnCount; - sb.append(prefix); sb.append(column); //sb.append(expr); @@ -43,7 +36,6 @@ public class GenerateDmlRequest { sb.append("="); sb.append(bind); } - if (prefix2 != null) { prefix = prefix2; prefix2 = null; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GeneratedProperties.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GeneratedProperties.java index 5f4090541..44a1d919b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GeneratedProperties.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GeneratedProperties.java @@ -10,7 +10,7 @@ import java.util.List; /** * Executes the generated property (like WhenCreated, WhoCreated etc) for doc store persisting. */ -class GeneratedProperties { +final class GeneratedProperties { /** * Create the GeneratedProperties for the given bean type. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GeneratedPropertyCollector.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GeneratedPropertyCollector.java index 08036e143..33b804a6c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GeneratedPropertyCollector.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/GeneratedPropertyCollector.java @@ -10,7 +10,7 @@ import java.util.List; /** * Collects the generated properties for inserts and updates for a given bean type. */ -class GeneratedPropertyCollector { +final class GeneratedPropertyCollector { private final List preInsert = new ArrayList<>(); private final List preUpdate = new ArrayList<>(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java index d9fb1e8f0..113e6ff39 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/InsertHandler.java @@ -18,7 +18,7 @@ import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; /** * Insert bean handler. */ -public class InsertHandler extends DmlHandler { +public final class InsertHandler extends DmlHandler { private final InsertMeta meta; private final boolean concatenatedKey; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/MetaFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/MetaFactory.java index de7c2bb39..7ad52d87f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/MetaFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/MetaFactory.java @@ -22,7 +22,7 @@ import java.util.List; /** * Factory for creating InsertMeta UpdateMeta and DeleteMeta. */ -class MetaFactory { +final class MetaFactory { /** * Include Lobs in the base statement. Generally true. Oracle9 used to require diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateHandler.java index 8a3e724c8..49f6e1bfb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdateHandler.java @@ -11,7 +11,7 @@ import java.sql.SQLException; /** * Update bean handler. */ -public class UpdateHandler extends DmlHandler { +public final class UpdateHandler extends DmlHandler { private final UpdateMeta meta; private boolean emptySetClause; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdatePlan.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdatePlan.java index 97811b5cf..69527de9b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdatePlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dml/UpdatePlan.java @@ -10,7 +10,7 @@ import java.sql.SQLException; /** * Plan for executing bean updates for a given set of changed properties. */ -class UpdatePlan implements SpiUpdatePlan { +final class UpdatePlan implements SpiUpdatePlan { private final String key; private final ConcurrencyMode mode; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocOne.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocOne.java index 9a9be58fc..8eaa091a0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocOne.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocOne.java @@ -24,30 +24,29 @@ class BindableAssocOne implements Bindable { } @Override - public String toString() { + public final String toString() { return "BindableAssocOne " + assocOne; } @Override - public boolean isDraftOnly() { + public final boolean isDraftOnly() { return assocOne.isDraftOnly(); } @Override - public void addToUpdate(PersistRequestBean request, List list) { + public final void addToUpdate(PersistRequestBean request, List list) { if (request.isAddToUpdate(assocOne)) { list.add(this); } } @Override - public void dmlAppend(GenerateDmlRequest request) { + public final void dmlAppend(GenerateDmlRequest request) { importedId.dmlAppend(request); } @Override public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { - EntityBean assocBean = (EntityBean) assocOne.getValue(bean); registerDeferred(request, bean, assocBean); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocTenant.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocTenant.java index eab3678a5..f3086783c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocTenant.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableAssocTenant.java @@ -5,7 +5,7 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; import java.sql.SQLException; -class BindableAssocTenant extends BindableAssocOne { +final class BindableAssocTenant extends BindableAssocOne { BindableAssocTenant(BeanPropertyAssocOne assocOne) { super(assocOne); @@ -13,7 +13,6 @@ class BindableAssocTenant extends BindableAssocOne { @Override public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { - EntityBean assocBean = (EntityBean) assocOne.getValue(bean); importedId.bind(request, assocBean); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableDiscriminator.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableDiscriminator.java index 1079df8e0..565b85d27 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableDiscriminator.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableDiscriminator.java @@ -12,7 +12,7 @@ import java.util.List; /** * Bindable for inserting a discriminator value. */ -public class BindableDiscriminator implements Bindable { +public final class BindableDiscriminator implements Bindable { private final String columnName; private final Object discValue; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableEmbedded.java index 44b9a201e..cfda5ae6a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableEmbedded.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableEmbedded.java @@ -10,15 +10,15 @@ import java.util.Arrays; import java.util.List; /** - * Bindable for a Embedded bean. + * Bindable for an Embedded bean. */ -public class BindableEmbedded implements Bindable { +final class BindableEmbedded implements Bindable { private final Bindable[] items; private final BeanPropertyAssocOne embProp; - public BindableEmbedded(BeanPropertyAssocOne embProp, List bindList) { + BindableEmbedded(BeanPropertyAssocOne embProp, List bindList) { this.embProp = embProp; this.items = bindList.toArray(new Bindable[0]); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableEncryptedProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableEncryptedProperty.java index b855fef00..3bfd2fa41 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableEncryptedProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableEncryptedProperty.java @@ -12,13 +12,13 @@ import java.util.List; /** * Bindable for a DB encrypted BeanProperty. */ -public class BindableEncryptedProperty implements Bindable { +final class BindableEncryptedProperty implements Bindable { private final BeanProperty prop; private final boolean bindEncryptDataFirst; - public BindableEncryptedProperty(BeanProperty prop, boolean bindEncryptDataFirst) { + BindableEncryptedProperty(BeanProperty prop, boolean bindEncryptDataFirst) { this.prop = prop; this.bindEncryptDataFirst = bindEncryptDataFirst; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdEmpty.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdEmpty.java index 1f970ee25..fa9c73b0b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdEmpty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdEmpty.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.persist.dml.GenerateDmlRequest; import java.util.List; -public class BindableIdEmpty implements BindableId { +final class BindableIdEmpty implements BindableId { @Override public boolean isEmpty() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdScalar.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdScalar.java index 4d0538f4a..518a236b7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdScalar.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableIdScalar.java @@ -12,11 +12,11 @@ import java.util.List; /** * Bindable for a single scalar id property. */ -public final class BindableIdScalar implements BindableId { +final class BindableIdScalar implements BindableId { private final BeanProperty uidProp; - public BindableIdScalar(BeanProperty uidProp) { + BindableIdScalar(BeanProperty uidProp) { this.uidProp = uidProp; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableList.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableList.java index de6957ad1..85894ee53 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableList.java @@ -12,7 +12,7 @@ import java.util.List; /** * List of Bindable items. */ -public class BindableList implements Bindable { +public final class BindableList implements Bindable { private final Bindable[] items; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableOrderColumn.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableOrderColumn.java index ef7046634..7879d192c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableOrderColumn.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableOrderColumn.java @@ -10,7 +10,7 @@ import java.util.List; /** * Bindable for the synthetic order column. */ -public class BindableOrderColumn extends BindableProperty { +public final class BindableOrderColumn extends BindableProperty { public BindableOrderColumn(BeanProperty prop) { super(prop); @@ -29,7 +29,6 @@ public class BindableOrderColumn extends BindableProperty { */ @Override public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { - int sortOrder = bean._ebean_getIntercept().getSortOrder(); request.bind(sortOrder, prop); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableProperty.java index 8716ddf91..8f50fe7b3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableProperty.java @@ -11,21 +11,21 @@ import java.util.List; /** * Bindable for a single BeanProperty. */ -public class BindableProperty implements Bindable { +class BindableProperty implements Bindable { final BeanProperty prop; - public BindableProperty(BeanProperty prop) { + BindableProperty(BeanProperty prop) { this.prop = prop; } @Override - public String toString() { + public final String toString() { return prop.toString(); } @Override - public boolean isDraftOnly() { + public final boolean isDraftOnly() { return prop.isDraftOnly(); } @@ -37,7 +37,7 @@ public class BindableProperty implements Bindable { } @Override - public void dmlAppend(GenerateDmlRequest request) { + public final void dmlAppend(GenerateDmlRequest request) { request.appendColumn(prop.getDbColumn()); } @@ -46,7 +46,6 @@ public class BindableProperty implements Bindable { */ @Override public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { - Object value = null; if (bean != null) { value = prop.getValue(bean); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java index 1cbb7eeca..a6d6d6cb6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonInsert.java @@ -9,7 +9,7 @@ import java.sql.SQLException; /** * For JSON Jackson properties - dirty detection via MD5 of json content. */ -class BindablePropertyJsonInsert extends BindableProperty { +final class BindablePropertyJsonInsert extends BindableProperty { private final int propertyIndex; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java index cfa056a63..7501fd92b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyJsonUpdate.java @@ -8,7 +8,7 @@ import java.sql.SQLException; /** * For JSON Jackson properties - dirty detection via MD5 of json content. */ -class BindablePropertyJsonUpdate extends BindableProperty { +final class BindablePropertyJsonUpdate extends BindableProperty { private final int propertyIndex; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyVersion.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyVersion.java index 5cdea3e8b..db28c3035 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyVersion.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindablePropertyVersion.java @@ -11,11 +11,11 @@ import java.util.List; /** * Bindable for a Version BeanProperty. Obtains value from 'old values'. */ -public class BindablePropertyVersion implements Bindable { +final class BindablePropertyVersion implements Bindable { private final BeanProperty prop; - public BindablePropertyVersion(BeanProperty prop) { + BindablePropertyVersion(BeanProperty prop) { this.prop = prop; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableUnidirectional.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableUnidirectional.java index 4e94b85d2..2ea853644 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableUnidirectional.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/BindableUnidirectional.java @@ -18,19 +18,16 @@ import java.util.List; * parentBean. *

*/ -public class BindableUnidirectional implements Bindable { +public final class BindableUnidirectional implements Bindable { private final BeanPropertyAssocOne unidirectional; - private final ImportedId importedId; - private final BeanDescriptor desc; public BindableUnidirectional(BeanDescriptor desc, BeanPropertyAssocOne unidirectional) { this.desc = desc; this.unidirectional = unidirectional; this.importedId = unidirectional.getImportedId(); - } @Override @@ -54,13 +51,10 @@ public class BindableUnidirectional implements Bindable { importedId.dmlAppend(request); } - @Override public void dmlBind(BindableRequest request, EntityBean bean) throws SQLException { - PersistRequestBean persistRequest = request.getPersistRequest(); Object parentBean = persistRequest.getParentBean(); - if (parentBean == null) { Class localType = desc.getBeanType(); Class targetType = unidirectional.getTargetType(); @@ -69,7 +63,6 @@ public class BindableUnidirectional implements Bindable { msg += "For inserts you must use cascade save on the master bean [" + targetType + "]."; throw new PersistenceException(msg); } - importedId.bind(request, (EntityBean) parentBean); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryAssocOnes.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryAssocOnes.java index bf3b0723d..7c2314bed 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryAssocOnes.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryAssocOnes.java @@ -9,16 +9,12 @@ import java.util.List; /** * A factory that builds Bindable for BeanPropertyAssocOne properties. */ -public class FactoryAssocOnes { - - public FactoryAssocOnes() { - } +public final class FactoryAssocOnes { /** * Add foreign key columns from associated one beans. */ public void create(List list, BeanDescriptor desc, DmlMode mode) { - for (BeanPropertyAssocOne one : desc.propertiesOneImported()) { if (!one.isImportedPrimaryKey()) { switch (mode) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryBaseProperties.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryBaseProperties.java index 43b9bec8d..209f17bbf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryBaseProperties.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryBaseProperties.java @@ -12,11 +12,10 @@ import java.util.List; * This excludes unique embedded and associated properties. *

*/ -public class FactoryBaseProperties { +public final class FactoryBaseProperties { private final FactoryProperty factoryProperty; - public FactoryBaseProperties(boolean bindEncryptDataFirst) { factoryProperty = new FactoryProperty(bindEncryptDataFirst); } @@ -25,7 +24,6 @@ public class FactoryBaseProperties { * Add Bindable for the base properties to the list. */ public void create(List list, BeanDescriptor desc, DmlMode mode, boolean withLobs) { - for (BeanProperty prop : desc.propertiesBaseScalar()) { if (!prop.isImportedPrimaryKey()) { Bindable item = factoryProperty.create(prop, mode, withLobs, false); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryEmbedded.java index 380c7b3a9..cef891682 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryEmbedded.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryEmbedded.java @@ -11,7 +11,7 @@ import java.util.List; /** * A factory that builds Bindable for embedded bean properties. */ -public class FactoryEmbedded { +public final class FactoryEmbedded { private final FactoryProperty factoryProperty; @@ -23,7 +23,6 @@ public class FactoryEmbedded { * Add bindable for the embedded properties to the list. */ public void create(List list, BeanDescriptor desc, DmlMode mode, boolean withLobs) { - for (BeanPropertyAssocOne anEmbedded : desc.propertiesEmbedded()) { BeanProperty[] props = anEmbedded.getProperties(); List bindList = new ArrayList<>(props.length); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryId.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryId.java index d517e051b..398f59ecf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryId.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryId.java @@ -7,23 +7,18 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; /** * Create a Bindable for the ids of a bean type. */ -public class FactoryId { - - public FactoryId() { - } +public final class FactoryId { /** * Add uniqueId properties. */ public BindableId createId(BeanDescriptor desc) { - BeanProperty id = desc.getIdProperty(); if (id == null) { return new BindableIdEmpty(); } if (!id.isEmbedded()) { return new BindableIdScalar(id); - } else { BeanPropertyAssocOne embId = (BeanPropertyAssocOne) id; MatchedImportedProperty[] matches = MatchedImportedFactory.build(embId.getProperties(), desc); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java index d5c59daf3..7de3e79ea 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryProperty.java @@ -12,7 +12,7 @@ import io.ebeaninternal.server.persist.dml.DmlMode; * and BindablePropertyUpdateGenerated as required. *

*/ -class FactoryProperty { +final class FactoryProperty { private final boolean bindEncryptDataFirst; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryVersion.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryVersion.java index abb7f1a20..7c418af31 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryVersion.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/FactoryVersion.java @@ -7,17 +7,12 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; /** * Creates a Bindable to support version concurrency where clauses. */ -public class FactoryVersion { - - - public FactoryVersion() { - } +public final class FactoryVersion { /** * Create a Bindable for the version property(s) for a bean type. */ public Bindable create(BeanDescriptor desc) { - BeanProperty versionProperty = desc.getVersionProperty(); return (versionProperty == null) ? null : new BindablePropertyVersion(versionProperty); } @@ -26,7 +21,6 @@ public class FactoryVersion { * Create a Bindable for the version property(s) for a bean type. */ public Bindable createForDelete(BeanDescriptor desc) { - BeanProperty versionProperty = desc.getVersionProperty(); return (versionProperty == null) ? null : new BindableProperty(versionProperty); } @@ -35,7 +29,6 @@ public class FactoryVersion { * Create a Bindable for TenantId If multi-tenant with partitioning is on this bean type. */ public Bindable createTenantId(BeanDescriptor desc) { - BeanProperty tenant = desc.getTenantProperty(); if (tenant == null) { return null; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedEmbedded.java index 4ce1bb63d..60a32ea19 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedEmbedded.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedEmbedded.java @@ -8,12 +8,10 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; * Matches local embedded id properties to 'matching' properties from a * ManyToOne associated bean that is a 'imported primary key'. */ -class MatchedImportedEmbedded implements MatchedImportedProperty { +final class MatchedImportedEmbedded implements MatchedImportedProperty { private final BeanProperty localProp; - private final BeanPropertyAssocOne assocOne; - private final BeanProperty foreignProp; MatchedImportedEmbedded(BeanProperty localProp, BeanPropertyAssocOne assocOne, BeanProperty foreignProp) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedFactory.java index 714e910dd..e4fa26284 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedFactory.java @@ -4,15 +4,13 @@ import io.ebeaninternal.server.deploy.BeanDescriptor; import io.ebeaninternal.server.deploy.BeanProperty; import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; -class MatchedImportedFactory { +final class MatchedImportedFactory { /** * Create the array of matchedImportedProperty based on the properties and descriptor. */ static MatchedImportedProperty[] build(BeanProperty[] props, BeanDescriptor desc) { - MatchedImportedProperty[] matches = new MatchedImportedProperty[props.length]; - for (int i = 0; i < props.length; i++) { // find matching assoc one property for dbColumn matches[i] = findMatch(props[i], desc); @@ -25,12 +23,9 @@ class MatchedImportedFactory { } private static MatchedImportedProperty findMatch(BeanProperty prop, BeanDescriptor desc) { - // find matching against the local database column String dbColumn = prop.getDbColumn(); - - BeanPropertyAssocOne[] assocOnes = desc.propertiesOne(); - for (BeanPropertyAssocOne assocOne1 : assocOnes) { + for (BeanPropertyAssocOne assocOne1 : desc.propertiesOne()) { if (assocOne1.isImportedPrimaryKey()) { // search using the ImportedId from the assoc one BeanProperty foreignMatch = assocOne1.getImportedId().findMatchImport(dbColumn); @@ -39,14 +34,11 @@ class MatchedImportedFactory { } } } - - BeanProperty[] scalar = desc.propertiesBaseScalar(); - for (BeanProperty beanProperty : scalar) { + for (BeanProperty beanProperty : desc.propertiesBaseScalar()) { if (dbColumn.equals(beanProperty.getDbColumn())) { return new MatchedImportedScalar(prop, beanProperty); } } - // there was no matching assoc one property. // example UserRole bean missing assoc one to User? return null; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedScalar.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedScalar.java index 436ef69a5..de9907863 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedScalar.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/dmlbind/MatchedImportedScalar.java @@ -6,10 +6,9 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Matches local embedded id properties to 'matching' imported primary key scalar properties. */ -class MatchedImportedScalar implements MatchedImportedProperty { +final class MatchedImportedScalar implements MatchedImportedProperty { private final BeanProperty localProp; - private final BeanProperty foreignProp; MatchedImportedScalar(BeanProperty localProp, BeanProperty foreignProp) { @@ -19,7 +18,6 @@ class MatchedImportedScalar implements MatchedImportedProperty { @Override public void populate(EntityBean sourceBean, EntityBean embeddedId) { - Object value = foreignProp.getValue(sourceBean); localProp.setValue(embeddedId, value); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/platform/MultiValueBind.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/platform/MultiValueBind.java index 3559a3a69..1a15b8438 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/platform/MultiValueBind.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/platform/MultiValueBind.java @@ -11,7 +11,6 @@ import java.util.Collection; */ public class MultiValueBind { - @FunctionalInterface public interface BindOne { void bind(Object value) throws SQLException; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/persist/platform/PostgresMultiValueBind.java b/ebean-core/src/main/java/io/ebeaninternal/server/persist/platform/PostgresMultiValueBind.java index f90d5cfb8..f7d86f55e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/persist/platform/PostgresMultiValueBind.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/persist/platform/PostgresMultiValueBind.java @@ -6,7 +6,7 @@ import io.ebean.core.type.ScalarType; /** * Multi value binder that uses Postgres Array. */ -public class PostgresMultiValueBind extends AbstractMultiValueBind { +public final class PostgresMultiValueBind extends AbstractMultiValueBind { @Override public String getInExpression(boolean not, ScalarType type, int size) { From 0688061f5cb2eed9b872ca2d648e9a72335cb55f Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 15 Aug 2021 15:17:19 +1200 Subject: [PATCH 092/120] Speed up TestUuidGenerator --- .../server/idgen/TestUuidGenerator.java | 47 ++++++------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/idgen/TestUuidGenerator.java b/ebean-core/src/test/java/io/ebeaninternal/server/idgen/TestUuidGenerator.java index 0f27c5a89..3623fdd73 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/idgen/TestUuidGenerator.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/idgen/TestUuidGenerator.java @@ -2,39 +2,32 @@ * Licensed Materials - Property of FOCONIS AG * (C) Copyright FOCONIS AG. */ - package io.ebeaninternal.server.idgen; - -import static org.assertj.core.api.Assertions.assertThat; +import io.ebean.config.dbplatform.PlatformIdGenerator; +import org.junit.Test; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; -import org.junit.Test; - -import io.ebean.config.dbplatform.PlatformIdGenerator; - +import static org.assertj.core.api.Assertions.assertThat; /** * Run some simple tests for the UUID generator. * * @author Roland Praml, FOCONIS AG - * */ public class TestUuidGenerator { - -/** - * Worker to generate UUIDs - * - * @author Roland Praml, FOCONIS AG - * - */ + /** + * Worker to generate UUIDs + * + * @author Roland Praml, FOCONIS AG + */ public static class IdTest implements Runnable { - private final Map map; + private final Map map; private final PlatformIdGenerator idGen; private final int ids; private final AtomicBoolean failFlag; @@ -46,12 +39,6 @@ public class TestUuidGenerator { this.failFlag = failFlag; } - public IdTest(PlatformIdGenerator idGen, int ids) { - this.idGen = idGen; - this.ids = ids; - this.map = null; - this.failFlag = null; - } @Override public void run() { //System.out.println("Start " + Thread.currentThread()); @@ -70,7 +57,7 @@ public class TestUuidGenerator { */ @Test public void testUuidV1SingleThread() throws Exception { - testGenerator(1, 1_000_000, UuidV1IdGenerator.getInstance("ebean-test-uuid.state")); + testGenerator(1, 500_000, UuidV1IdGenerator.getInstance("ebean-test-uuid.state")); } /** @@ -78,7 +65,7 @@ public class TestUuidGenerator { */ @Test public void testUuidV1MultiThread() throws Exception { - testGenerator(10, 100_000, UuidV1IdGenerator.getInstance("ebean-test-uuid.state")); + testGenerator(10, 50_000, UuidV1IdGenerator.getInstance("ebean-test-uuid.state")); } /** @@ -86,7 +73,7 @@ public class TestUuidGenerator { */ @Test public void testUuidV1RndMultiThread() throws Exception { - testGenerator(10, 100_000, UuidV1RndIdGenerator.INSTANCE); + testGenerator(10, 50_000, UuidV1RndIdGenerator.INSTANCE); } /** @@ -94,7 +81,7 @@ public class TestUuidGenerator { */ @Test public void testUuidType1RndSingleThread() throws Exception { - testGenerator(1, 1_000_000, UuidV1RndIdGenerator.INSTANCE); + testGenerator(1, 500_000, UuidV1RndIdGenerator.INSTANCE); } /** @@ -102,7 +89,7 @@ public class TestUuidGenerator { */ @Test public void testUuidType4MultiThread() throws Exception { - testGenerator(10, 100_000, UuidV4IdGenerator.INSTANCE); + testGenerator(10, 50_000, UuidV4IdGenerator.INSTANCE); } /** @@ -110,12 +97,9 @@ public class TestUuidGenerator { */ @Test public void testUuidType4SingleThread() throws Exception { - testGenerator(1, 1_000_000, UuidV4IdGenerator.INSTANCE); + testGenerator(1, 500_000, UuidV4IdGenerator.INSTANCE); } - - - private void testGenerator(int threadCount, int count, PlatformIdGenerator generator) throws Exception { System.out.println("Printing 5 consecutive IDs of " + generator); for (int i = 0; i < 5; i++) { @@ -136,6 +120,5 @@ public class TestUuidGenerator { } assertThat(failFlag.get()).isFalse(); assertThat(map.size()).isEqualTo(threadCount * count); - } } From 4109fab0d86ef1ab1b2d5af3b97573a5a02e068f Mon Sep 17 00:00:00 2001 From: rbygrave Date: Sun, 15 Aug 2021 15:22:02 +1200 Subject: [PATCH 093/120] #2313 - Refactor internals - make more classes final in query packages --- .../server/query/BaseFuture.java | 8 +- .../io/ebeaninternal/server/query/CQuery.java | 2 +- .../server/query/CQueryBindCapture.java | 2 +- .../server/query/CQueryBuilder.java | 2 +- .../server/query/CQueryBuilderRawSql.java | 2 +- .../server/query/CQueryCollectionAddNoop.java | 2 +- .../server/query/CQueryDraftSupport.java | 2 +- .../server/query/CQueryEngine.java | 2 +- .../query/CQueryFetchSingleAttribute.java | 2 +- .../server/query/CQueryHistorySupport.java | 2 +- .../server/query/CQueryIteratorSimple.java | 2 +- .../query/CQueryIteratorWithBuffer.java | 2 +- .../server/query/CQueryOrderBy.java | 2 +- .../server/query/CQueryPlan.java | 48 ++++++------ .../server/query/CQueryPlanManager.java | 2 +- .../server/query/CQueryPlanRawSql.java | 3 +- .../server/query/CQueryPlanRequest.java | 4 +- .../server/query/CQueryPlanStats.java | 3 - .../server/query/CQueryPredicates.java | 25 +------ .../server/query/CQueryRowCount.java | 2 +- .../server/query/CQueryUpdate.java | 2 +- .../server/query/CallableQuery.java | 2 - .../server/query/CallableQueryCount.java | 4 +- .../server/query/CallableQueryIds.java | 4 +- .../server/query/CallableQueryList.java | 3 +- .../server/query/DFetchGroup.java | 2 +- .../server/query/DFetchGroupBuilder.java | 2 +- .../server/query/DQueryPlanOutput.java | 2 +- .../server/query/DbOrderByTrim.java | 2 +- .../server/query/DefaultDbSqlContext.java | 2 +- .../server/query/DefaultFetchGroupQuery.java | 2 +- .../server/query/DefaultOrmQueryEngine.java | 2 +- .../query/DefaultRelationalQueryEngine.java | 2 +- .../server/query/DefaultSqlRow.java | 2 +- .../server/query/DtoQueryEngine.java | 2 +- .../server/query/DtoQueryIterator.java | 2 +- .../ebeaninternal/server/query/ExtraJoin.java | 2 +- .../server/query/LimitOffsetPagedList.java | 2 +- .../server/query/OrderVersionDesc.java | 2 +- .../server/query/QueryFutureIds.java | 2 +- .../server/query/QueryFutureList.java | 2 +- .../server/query/QueryFutureRowCount.java | 2 +- .../server/query/QueryPlanLogger.java | 6 +- .../server/query/QueryPlanLoggerExplain.java | 2 +- .../server/query/QueryPlanLoggerOracle.java | 2 +- .../server/query/QueryPlanLoggerPostgres.java | 2 +- .../query/QueryPlanLoggerSqlServer.java | 2 +- .../server/query/RawSqlQueryPlanKey.java | 2 +- .../server/query/SqlBeanLoad.java | 2 +- .../ebeaninternal/server/query/SqlTree.java | 2 +- .../server/query/SqlTreeAlias.java | 2 +- .../server/query/SqlTreeBuilder.java | 22 +----- .../server/query/SqlTreeNodeBean.java | 44 ++++------- .../server/query/SqlTreeNodeExtraJoin.java | 3 +- .../query/SqlTreeNodeFormulaWhereJoin.java | 3 +- .../query/SqlTreeNodeManyWhereJoin.java | 8 +- .../server/query/SqlTreeNodeRoot.java | 2 - .../server/query/SqlTreeProperties.java | 10 +-- .../server/querydefn/AbstractQuery.java | 10 +-- .../server/querydefn/DefaultDtoQuery.java | 17 +---- .../server/querydefn/DefaultOrmQuery.java | 74 +------------------ .../server/querydefn/DefaultOrmUpdate.java | 20 ----- .../querydefn/DefaultRelationalQuery.java | 12 +-- .../server/querydefn/DefaultUpdateQuery.java | 2 +- .../server/querydefn/NaturalKeyBindParam.java | 3 +- .../server/querydefn/ONamedParam.java | 3 +- .../server/querydefn/OrmQueryDetail.java | 2 +- .../querydefn/OrmQueryDetailParser.java | 5 +- .../querydefn/OrmQueryLimitRequest.java | 6 +- .../server/querydefn/OrmQueryPlanKey.java | 2 +- .../server/querydefn/OrmQueryProperties.java | 8 +- .../server/querydefn/OrmQuerySecondary.java | 3 +- .../server/querydefn/OrmUpdateProperties.java | 11 ++- .../server/querydefn/SimpleTextParser.java | 3 +- 74 files changed, 120 insertions(+), 343 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/BaseFuture.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/BaseFuture.java index 93c86fe7b..e71334ea6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/BaseFuture.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/BaseFuture.java @@ -26,22 +26,22 @@ abstract class BaseFuture implements Future { } @Override - public T get() throws InterruptedException, ExecutionException { + public final T get() throws InterruptedException, ExecutionException { return futureTask.get(); } @Override - public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + public final T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return futureTask.get(timeout, unit); } @Override - public boolean isCancelled() { + public final boolean isCancelled() { return futureTask.isCancelled(); } @Override - public boolean isDone() { + public final boolean isDone() { return futureTask.isDone(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java index 7fc636af0..e9d2281d0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java @@ -37,7 +37,7 @@ import java.util.concurrent.locks.ReentrantLock; * The tree structure is flattened into a SqlSelectChain. The SqlSelectChain is * the key object used in reading the flat resultSet back into Objects. */ -public class CQuery implements DbReadContext, CancelableQuery, SpiProfileTransactionEvent { +public final class CQuery implements DbReadContext, CancelableQuery, SpiProfileTransactionEvent { private static final Logger logger = LoggerFactory.getLogger(CQuery.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBindCapture.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBindCapture.java index e3a1a5e54..559dfa0da 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBindCapture.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBindCapture.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.type.bindcapture.BindCapture; import java.util.concurrent.locks.ReentrantLock; -class CQueryBindCapture implements SpiQueryBindCapture { +final class CQueryBindCapture implements SpiQueryBindCapture { private static final double multiplier = 1.5d; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java index 9a4b1d32e..09b465893 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilder.java @@ -40,7 +40,7 @@ import java.util.List; * Generates the SQL SELECT statements taking into account the physical * deployment properties. */ -class CQueryBuilder { +final class CQueryBuilder { private final String columnAliasPrefix; private final SqlLimiter sqlLimiter; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilderRawSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilderRawSql.java index 2bc60d208..d3b4e7ca6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilderRawSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryBuilderRawSql.java @@ -11,7 +11,7 @@ import io.ebeaninternal.server.querydefn.OrmQueryLimitRequest; import io.ebeaninternal.server.rawsql.SpiRawSql; import io.ebeaninternal.server.util.BindParamsParser; -class CQueryBuilderRawSql { +final class CQueryBuilderRawSql { private final SqlLimiter sqlLimiter; private final DatabasePlatform dbPlatform; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryCollectionAddNoop.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryCollectionAddNoop.java index ac4230999..cf8adf097 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryCollectionAddNoop.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryCollectionAddNoop.java @@ -7,7 +7,7 @@ import io.ebean.bean.EntityBean; * A NOOP based CQueryCollectionAdd for use with lazy loading many queries where the * beans loaded into the collection are added to the collection(s) of the parent(s). */ -class CQueryCollectionAddNoop implements CQueryCollectionAdd { +final class CQueryCollectionAddNoop implements CQueryCollectionAdd { /** * Return null as we are not collecting the beans. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryDraftSupport.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryDraftSupport.java index da1e01cac..771ff8145 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryDraftSupport.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryDraftSupport.java @@ -5,7 +5,7 @@ import java.util.Map; /** * Support 'asDraft' queries. */ -class CQueryDraftSupport { +final class CQueryDraftSupport { /** * The mapping of base tables to their matching 'draft' table. 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 03074b43f..b76d0b4e9 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 @@ -33,7 +33,7 @@ import java.util.Map; /** * Handles the Object Relational fetching. */ -public class CQueryEngine { +public final class CQueryEngine { private static final Logger logger = LoggerFactory.getLogger(CQueryEngine.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java index a89cd28fa..41f9e7f4d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java @@ -24,7 +24,7 @@ import java.util.concurrent.locks.ReentrantLock; /** * Base compiled query request for single attribute queries. */ -class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent, CancelableQuery { +final class CQueryFetchSingleAttribute implements SpiProfileTransactionEvent, CancelableQuery { private static final Logger logger = LoggerFactory.getLogger(CQueryFetchSingleAttribute.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryHistorySupport.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryHistorySupport.java index 5f810c6da..e082c97eb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryHistorySupport.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryHistorySupport.java @@ -7,7 +7,7 @@ import java.util.Map; /** * Helper to support history functions. */ -class CQueryHistorySupport { +final class CQueryHistorySupport { /** * The DB specific support. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryIteratorSimple.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryIteratorSimple.java index 17cec9d15..d438ec747 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryIteratorSimple.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryIteratorSimple.java @@ -9,7 +9,7 @@ import java.sql.SQLException; /** * QueryIterator that does not require a buffer for secondary queries. */ -class CQueryIteratorSimple implements QueryIterator { +final class CQueryIteratorSimple implements QueryIterator { private final CQuery cquery; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryIteratorWithBuffer.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryIteratorWithBuffer.java index e2a9bdad2..ad1a924b5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryIteratorWithBuffer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryIteratorWithBuffer.java @@ -11,7 +11,7 @@ import java.util.NoSuchElementException; /** * A QueryIterator that uses a buffer to execute secondary queries periodically. */ -class CQueryIteratorWithBuffer implements QueryIterator { +final class CQueryIteratorWithBuffer implements QueryIterator { private final CQuery cquery; private final int bufferSize; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryOrderBy.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryOrderBy.java index c325255ef..ffb65a039 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryOrderBy.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryOrderBy.java @@ -13,7 +13,7 @@ import java.util.List; /** * Creates the order by expression clause. */ -class CQueryOrderBy { +final class CQueryOrderBy { private final BeanDescriptor desc; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java index de365f253..aef2c1164 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlan.java @@ -164,49 +164,49 @@ public class CQueryPlan implements SpiQueryPlan { } @Override - public Class getBeanType() { + public final Class getBeanType() { return beanType; } @Override - public String getName() { + public final String getName() { return name; } @Override - public String getHash() { + public final String getHash() { return hash; } @Override - public String getSql() { + public final String getSql() { return sql; } @Override - public ProfileLocation getProfileLocation() { + public final ProfileLocation getProfileLocation() { return profileLocation; } - public String getLabel() { + public final String getLabel() { return label; } - public Set getDependentTables() { + public final Set getDependentTables() { return dependentTables; } - public String getLocation() { + public final String getLocation() { return location; } @Override - public void queryPlanInit(long thresholdMicros) { + public final void queryPlanInit(long thresholdMicros) { bindCapture.queryPlanInit(thresholdMicros); } @Override - public DQueryPlanOutput createMeta(String bind, String planString) { + public final DQueryPlanOutput createMeta(String bind, String planString) { return new DQueryPlanOutput(getBeanType(), name, hash, sql, profileLocation, bind, planString); } @@ -217,7 +217,7 @@ public class CQueryPlan implements SpiQueryPlan { /** * Bind keys for encrypted properties if necessary returning the DataBind. */ - DataBind bindEncryptedProperties(PreparedStatement stmt, Connection conn) throws SQLException { + final DataBind bindEncryptedProperties(PreparedStatement stmt, Connection conn) throws SQLException { DataBind dataBind = new DataBind(dataTimeZone, stmt, conn); if (encryptedProps != null) { for (STreeProperty encryptedProp : encryptedProps) { @@ -237,14 +237,14 @@ public class CQueryPlan implements SpiQueryPlan { return dataBind; } - int getAsOfTableCount() { + final int getAsOfTableCount() { return asOfTableCount; } /** * Return a key used in audit logging to identify the query. */ - String getAuditQueryKey() { + final String getAuditQueryKey() { if (auditQueryHash == null) { // volatile object assignment (so happy for multithreaded access) auditQueryHash = calcAuditQueryKey(); @@ -257,29 +257,29 @@ public class CQueryPlan implements SpiQueryPlan { return rawSql ? planKey.getPartialKey() + "_" + hash : planKey.getPartialKey(); } - SqlTree getSqlTree() { + final SqlTree getSqlTree() { return sqlTree; } - public boolean isRawSql() { + public final boolean isRawSql() { return rawSql; } - String getLogWhereSql() { + final String getLogWhereSql() { return logWhereSql; } /** * Reset the query statistics. */ - public void resetStatistics() { + public final void resetStatistics() { stats.reset(); } /** * Register an execution time against this query plan; */ - boolean executionTime(long timeMicros) { + final boolean executionTime(long timeMicros) { stats.add(timeMicros); return bindCapture != null && bindCapture.collectFor(timeMicros); } @@ -287,33 +287,33 @@ public class CQueryPlan implements SpiQueryPlan { /** * Return a copy of the current query statistics. */ - public Snapshot getSnapshot(boolean reset) { + public final Snapshot getSnapshot(boolean reset) { return stats.getSnapshot(reset); } /** * Return the time this query plan was last used. */ - public long getLastQueryTime() { + public final long getLastQueryTime() { return stats.getLastQueryTime(); } - ScalarDataReader getSingleAttributeScalarType() { + final ScalarDataReader getSingleAttributeScalarType() { return sqlTree.getRootNode().getSingleAttributeReader(); } /** * Return true if there are no statistics collected since the last reset. */ - public boolean isEmptyStats() { + public final boolean isEmptyStats() { return stats.isEmpty(); } - TimedMetric createTimedMetric() { + final TimedMetric createTimedMetric() { return MetricFactory.get().createTimedMetric(label); } - void captureBindForQueryPlan(CQueryPredicates predicates, long executionTimeMicros) { + final void captureBindForQueryPlan(CQueryPredicates predicates, long executionTimeMicros) { final long startNanos = System.nanoTime(); try { DataBindCapture capture = bindCapture(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanManager.java index 4ff62f44d..499e801d3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanManager.java @@ -20,7 +20,7 @@ import java.util.concurrent.ConcurrentHashMap; import static java.util.Collections.emptyList; -public class CQueryPlanManager implements QueryPlanManager { +public final class CQueryPlanManager implements QueryPlanManager { private static final Logger log = LoggerFactory.getLogger(CQueryPlanManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRawSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRawSql.java index bab955d84..a23114bf2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRawSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRawSql.java @@ -12,7 +12,7 @@ import java.util.List; /** * RawSql based query plan. */ -class CQueryPlanRawSql extends CQueryPlan { +final class CQueryPlanRawSql extends CQueryPlan { private final int[] rsetIndexPositions; @@ -27,7 +27,6 @@ class CQueryPlanRawSql extends CQueryPlan { } private int[] createIndexPositions(OrmQueryRequest request, SqlTree sqlTree) { - List chain = sqlTree.buildRawSqlSelectChain(); ColumnMapping columnMapping = request.getQuery().getRawSql().getColumnMapping(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRequest.java index 315e7a07d..00b202d57 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanRequest.java @@ -11,7 +11,7 @@ import java.util.List; /** * Captures database query plans. */ -class CQueryPlanRequest { +final class CQueryPlanRequest { private final List plans = new ArrayList<>(); @@ -19,7 +19,7 @@ class CQueryPlanRequest { private final long since; private final int maxCount; private final long maxTime; - private Iterator iterator; + private final Iterator iterator; CQueryPlanRequest(Connection connection, QueryPlanRequest req, Iterator iterator) { this.connection = connection; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java index ffc749eb9..05ad13173 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPlanStats.java @@ -10,11 +10,8 @@ import io.ebean.metric.TimedMetricStats; public final class CQueryPlanStats { private final CQueryPlan queryPlan; - private final TimedMetric timedMetric; - private boolean collected; - private long lastQueryTime; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java index c41f830c6..426b1ed4e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryPredicates.java @@ -37,74 +37,51 @@ import java.util.Set; * named parameters and expression values into the prepared statement. *

*/ -public class CQueryPredicates { +public final class CQueryPredicates { private static final Logger logger = LoggerFactory.getLogger(CQueryPredicates.class); private final Binder binder; - private final OrmQueryRequest request; - private final SpiQuery query; - private final Object idValue; - - /** - * Named bind parameters. - */ private final BindParams bindParams; - - /** - * Bind values from the where expressions. - */ private DefaultExpressionRequest filterMany; - /** * SQL generated from the where expressions. */ private String filterManyExprSql; - /** * Bind values from the where expressions. */ private DefaultExpressionRequest where; - /** * SQL generated from the where expressions. */ private String whereExprSql; - /** * Bind values for having expression. */ private DefaultExpressionRequest having; - /** * SQL generated from the having expression. */ private String havingExprSql; - private String dbHaving; - /** * logicalWhere with property names converted to db columns. */ private String dbWhere; - /** * Filter than can apply to a many fetch join. */ private String dbFilterMany; - private String dbOrderBy; - private String dbUpdateClause; - /** * Includes from where and order by clauses. */ private Set predicateIncludes; - private Set orderByIncludes; CQueryPredicates(Binder binder, OrmQueryRequest request) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java index 0c1df9483..ccfbb3ce6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java @@ -19,7 +19,7 @@ import java.util.concurrent.locks.ReentrantLock; /** * Executes the select row count query. */ -class CQueryRowCount implements SpiProfileTransactionEvent, CancelableQuery { +final class CQueryRowCount implements SpiProfileTransactionEvent, CancelableQuery { private final CQueryPlan queryPlan; private final OrmQueryRequest request; 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 302b1bcf0..e35615a0c 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 @@ -16,7 +16,7 @@ import java.util.concurrent.locks.ReentrantLock; /** * Executes the update query. */ -class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery { +final class CQueryUpdate implements SpiProfileTransactionEvent, CancelableQuery { private final CQueryPlan queryPlan; private final OrmQueryRequest request; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQuery.java index 2a432b732..528984d17 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQuery.java @@ -10,9 +10,7 @@ import io.ebeaninternal.api.SpiQuery; abstract class CallableQuery { final SpiQuery query; - final SpiEbeanServer server; - final Transaction transaction; CallableQuery(SpiEbeanServer server, SpiQuery query, Transaction t) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryCount.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryCount.java index a2076b363..959ce2abd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryCount.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryCount.java @@ -8,10 +8,8 @@ import java.util.concurrent.Callable; /** * Represent the findCount query as a Callable. - * - * @param the entity bean type */ -public class CallableQueryCount extends CallableQuery implements Callable { +public final class CallableQueryCount extends CallableQuery implements Callable { /** * Note that the transaction passed in is always a new transaction solely to diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryIds.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryIds.java index c8ae160f6..c236ccb6d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryIds.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryIds.java @@ -9,10 +9,8 @@ import java.util.concurrent.Callable; /** * Represent the fetch Id's query as a Callable. - * - * @param the entity bean type */ -public class CallableQueryIds extends CallableQuery implements Callable> { +public final class CallableQueryIds extends CallableQuery implements Callable> { public CallableQueryIds(SpiEbeanServer server, SpiQuery query, Transaction t) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryList.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryList.java index b20e75a86..350cd67f0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CallableQueryList.java @@ -12,8 +12,7 @@ import java.util.concurrent.Callable; * * @param the entity bean type */ -public class CallableQueryList extends CallableQuery implements Callable> { - +public final class CallableQueryList extends CallableQuery implements Callable> { public CallableQueryList(SpiEbeanServer server, SpiQuery query, Transaction t) { super(server, query, t); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DFetchGroup.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DFetchGroup.java index 4b17e3461..bc2449d63 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DFetchGroup.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DFetchGroup.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.querydefn.SpiFetchGroup; /** * Default FetchGroup implementation. */ -class DFetchGroup implements SpiFetchGroup { +final class DFetchGroup implements SpiFetchGroup { private final OrmQueryDetail detail; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DFetchGroupBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DFetchGroupBuilder.java index 6553b7ea4..50966a45f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DFetchGroupBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DFetchGroupBuilder.java @@ -9,7 +9,7 @@ import io.ebeaninternal.server.querydefn.SpiFetchGroup; /** * Default implementation of the FetchGroupBuilder. */ -class DFetchGroupBuilder implements FetchGroupBuilder { +final class DFetchGroupBuilder implements FetchGroupBuilder { private static final FetchConfig DEFAULT_FETCH = FetchConfig.ofDefault(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java index 1c1a41d07..642e163e2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DQueryPlanOutput.java @@ -7,7 +7,7 @@ import io.ebeaninternal.api.SpiDbQueryPlan; /** * Captured query plan details. */ -class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { +final class DQueryPlanOutput implements MetaQueryPlan, SpiDbQueryPlan { private final Class beanType; private final String label; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DbOrderByTrim.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DbOrderByTrim.java index 766be909b..72eb81db4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DbOrderByTrim.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DbOrderByTrim.java @@ -2,7 +2,7 @@ package io.ebeaninternal.server.query; import java.util.regex.Pattern; -class DbOrderByTrim { +final class DbOrderByTrim { private static final Pattern orderByTrim = Pattern.compile("(?i) asc\\b| desc\\b|\\b nulls first\\b|\\b nulls last\\b"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultDbSqlContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultDbSqlContext.java index 378647818..dbd9b263e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultDbSqlContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultDbSqlContext.java @@ -8,7 +8,7 @@ import io.ebeaninternal.server.util.ArrayStack; import java.util.ArrayList; import java.util.HashSet; -class DefaultDbSqlContext implements DbSqlContext { +final class DefaultDbSqlContext implements DbSqlContext { private static final String COMMA = ", "; private static final String PERIOD = "."; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java index 9f7cb9b7e..459bba998 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultFetchGroupQuery.java @@ -44,7 +44,7 @@ import java.util.stream.Stream; /** * Implementation of FetchGroup query for use to create FetchGroup via query beans. */ -class DefaultFetchGroupQuery implements SpiFetchGroupQuery, SpiQueryFetch { +final class DefaultFetchGroupQuery implements SpiFetchGroupQuery, SpiQueryFetch { private static final FetchConfig FETCH_CACHE = FetchConfig.ofCache(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultOrmQueryEngine.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultOrmQueryEngine.java index b112c7986..abab7cdf9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultOrmQueryEngine.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultOrmQueryEngine.java @@ -21,7 +21,7 @@ import java.util.List; /** * Main Finder implementation. */ -public class DefaultOrmQueryEngine implements OrmQueryEngine { +public final class DefaultOrmQueryEngine implements OrmQueryEngine { /** * Find using predicates diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultRelationalQueryEngine.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultRelationalQueryEngine.java index 78b9717d9..44b84a6a5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultRelationalQueryEngine.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultRelationalQueryEngine.java @@ -23,7 +23,7 @@ import java.util.function.Predicate; /** * Perform native sql fetches. */ -public class DefaultRelationalQueryEngine implements RelationalQueryEngine { +public final class DefaultRelationalQueryEngine implements RelationalQueryEngine { private final Binder binder; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultSqlRow.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultSqlRow.java index 0ee1e1525..e38d9d7d7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultSqlRow.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DefaultSqlRow.java @@ -29,7 +29,7 @@ import java.util.UUID; * returning the type you expect. *

*/ -public class DefaultSqlRow implements SqlRow { +public final class DefaultSqlRow implements SqlRow { private static final long serialVersionUID = -3120927797041336242L; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DtoQueryEngine.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DtoQueryEngine.java index 526d36dee..39588b733 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DtoQueryEngine.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DtoQueryEngine.java @@ -12,7 +12,7 @@ import java.util.List; import java.util.function.Consumer; import java.util.function.Predicate; -public class DtoQueryEngine { +public final class DtoQueryEngine { private final Binder binder; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/DtoQueryIterator.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/DtoQueryIterator.java index bdf4e2df6..47676c525 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/DtoQueryIterator.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/DtoQueryIterator.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.core.DtoQueryRequest; import javax.persistence.PersistenceException; import java.sql.SQLException; -class DtoQueryIterator implements QueryIterator { +final class DtoQueryIterator implements QueryIterator { private final DtoQueryRequest request; private boolean closed; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/ExtraJoin.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/ExtraJoin.java index c246c651d..6fdeedd43 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/ExtraJoin.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/ExtraJoin.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.query; -public class ExtraJoin { +public final class ExtraJoin { private final STreePropertyAssoc property; private final boolean containsMany; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/LimitOffsetPagedList.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/LimitOffsetPagedList.java index a6f506ef6..cb9f6f560 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/LimitOffsetPagedList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/LimitOffsetPagedList.java @@ -12,7 +12,7 @@ import java.util.concurrent.locks.ReentrantLock; /** * PagedList implementation based on limit offset types of queries. */ -public class LimitOffsetPagedList implements PagedList { +public final class LimitOffsetPagedList implements PagedList { private final transient SpiEbeanServer server; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/OrderVersionDesc.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/OrderVersionDesc.java index e3b99561a..52e661b10 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/OrderVersionDesc.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/OrderVersionDesc.java @@ -9,7 +9,7 @@ import java.util.Comparator; /** * Compare Version beans in descending order with nulls last. */ -class OrderVersionDesc implements Comparator>, Serializable { +final class OrderVersionDesc implements Comparator>, Serializable { static final OrderVersionDesc INSTANCE = new OrderVersionDesc(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureIds.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureIds.java index b330d7d25..ff5acb76c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureIds.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureIds.java @@ -10,7 +10,7 @@ import java.util.concurrent.FutureTask; /** * Default implementation of FutureIds. */ -public class QueryFutureIds extends BaseFuture> implements FutureIds { +public final class QueryFutureIds extends BaseFuture> implements FutureIds { private final CallableQueryIds call; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureList.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureList.java index 2d3999b61..34264ffcf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureList.java @@ -14,7 +14,7 @@ import java.util.concurrent.TimeoutException; /** * Default implementation for FutureList. */ -public class QueryFutureList extends BaseFuture> implements FutureList { +public final class QueryFutureList extends BaseFuture> implements FutureList { private final CallableQueryList call; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureRowCount.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureRowCount.java index 52c7b0fca..832653f1d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureRowCount.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryFutureRowCount.java @@ -8,7 +8,7 @@ import java.util.concurrent.FutureTask; /** * Future implementation for the row count query. */ -public class QueryFutureRowCount extends BaseFuture implements FutureRowCount { +public final class QueryFutureRowCount extends BaseFuture implements FutureRowCount { private final CallableQueryCount call; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLogger.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLogger.java index 53bd01f94..1ab789158 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLogger.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLogger.java @@ -16,7 +16,7 @@ public abstract class QueryPlanLogger { abstract SpiDbQueryPlan collectPlan(Connection conn, SpiQueryPlan plan, BindCapture bind); - SpiDbQueryPlan readQueryPlan(SpiQueryPlan plan, BindCapture bind, ResultSet rset) throws SQLException { + final SpiDbQueryPlan readQueryPlan(SpiQueryPlan plan, BindCapture bind, ResultSet rset) throws SQLException { StringBuilder sb = new StringBuilder(); for (int i = 1; i <= rset.getMetaData().getColumnCount(); i++) { sb.append(rset.getMetaData().getColumnLabel(i)).append("\t"); @@ -27,11 +27,11 @@ public abstract class QueryPlanLogger { return createPlan(plan, bind.toString(), sb.toString()); } - SpiDbQueryPlan createPlan(SpiQueryPlan plan, String bind, String planString) { + final SpiDbQueryPlan createPlan(SpiQueryPlan plan, String bind, String planString) { return plan.createMeta(bind, planString); } - SpiDbQueryPlan readQueryPlanBasic(SpiQueryPlan plan, BindCapture bind, ResultSet rset) throws SQLException { + final SpiDbQueryPlan readQueryPlanBasic(SpiQueryPlan plan, BindCapture bind, ResultSet rset) throws SQLException { StringBuilder sb = new StringBuilder(); readPlanData(sb, rset); return createPlan(plan, bind.toString(), sb.toString().trim()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerExplain.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerExplain.java index 6f89c138a..6319967d9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerExplain.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerExplain.java @@ -12,7 +12,7 @@ import java.sql.SQLException; /** * A QueryPlanLogger that prefixes "EXPLAIN " to the query. This works for Postgres, H2 and MySql. */ -public class QueryPlanLoggerExplain extends QueryPlanLogger { +public final class QueryPlanLoggerExplain extends QueryPlanLogger { @Override public SpiDbQueryPlan collectPlan(Connection conn, SpiQueryPlan plan, BindCapture bind) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerOracle.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerOracle.java index 2d2f4702f..d4ccd81bb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerOracle.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerOracle.java @@ -16,7 +16,7 @@ import java.sql.Statement; * * @author Roland Praml, FOCONIS AG */ -public class QueryPlanLoggerOracle extends QueryPlanLogger { +public final class QueryPlanLoggerOracle extends QueryPlanLogger { @Override public SpiDbQueryPlan collectPlan(Connection conn, SpiQueryPlan plan, BindCapture bind) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerPostgres.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerPostgres.java index 596f33bc0..f52654ba5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerPostgres.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerPostgres.java @@ -12,7 +12,7 @@ import java.sql.SQLException; /** * A QueryPlanLogger for Postgres that prefixes "EXPLAIN ANALYZE" to the query. */ -public class QueryPlanLoggerPostgres extends QueryPlanLogger { +public final class QueryPlanLoggerPostgres extends QueryPlanLogger { @Override public SpiDbQueryPlan collectPlan(Connection conn, SpiQueryPlan plan, BindCapture bind) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerSqlServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerSqlServer.java index 6657448e2..c71072084 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerSqlServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/QueryPlanLoggerSqlServer.java @@ -16,7 +16,7 @@ import java.sql.Statement; * * @author Roland Praml, FOCONIS AG */ -public class QueryPlanLoggerSqlServer extends QueryPlanLogger { +public final class QueryPlanLoggerSqlServer extends QueryPlanLogger { @Override public SpiDbQueryPlan collectPlan(Connection conn, SpiQueryPlan plan, BindCapture bind) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/RawSqlQueryPlanKey.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/RawSqlQueryPlanKey.java index 2a3fce499..b24a57e04 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/RawSqlQueryPlanKey.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/RawSqlQueryPlanKey.java @@ -7,7 +7,7 @@ import java.util.Objects; /** * QueryPlanKey for RawSql queries. */ -class RawSqlQueryPlanKey implements CQueryPlanKey { +final class RawSqlQueryPlanKey implements CQueryPlanKey { private final String sql; private final boolean rawSql; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java index 83c7b2936..cdeb345c0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlBeanLoad.java @@ -13,7 +13,7 @@ import io.ebeaninternal.server.deploy.DbReadContext; * partial objects. *

*/ -public class SqlBeanLoad { +public final class SqlBeanLoad { private final DbReadContext ctx; private final EntityBean bean; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTree.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTree.java index 5f548fd59..27e35c365 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTree.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTree.java @@ -10,7 +10,7 @@ import java.util.Set; /** * Represents the SELECT clause part of the SQL query. */ -class SqlTree { +final class SqlTree { private final SqlTreeNode rootNode; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeAlias.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeAlias.java index 27ec943b4..9d46d07c3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeAlias.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeAlias.java @@ -12,7 +12,7 @@ import java.util.TreeSet; /** * Special Map of the logical property joins to table alias. */ -class SqlTreeAlias { +final class SqlTreeAlias { private final SpiQuery.TemporalMode temporalMode; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java index 65fa4f7f8..43e3a0215 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeBuilder.java @@ -30,44 +30,28 @@ public final class SqlTreeBuilder { private static final Logger logger = LoggerFactory.getLogger(SqlTreeBuilder.class); private final SpiQuery query; - private final STreeType desc; - private final OrmQueryDetail queryDetail; - private final CQueryPredicates predicates; - private final boolean subQuery; - private final boolean distinctOnPlatform; /** * Property if resultSet contains master and detail rows. */ private STreePropertyAssocMany manyProperty; - private final SqlTreeAlias alias; - private final DefaultDbSqlContext ctx; - private final HashSet selectIncludes = new HashSet<>(); - private final ManyWhereJoins manyWhereJoins; - private final TableJoin includeJoin; - private final boolean rawSql; - /** * rawNoId true if the RawSql does not include the @Id property */ private final boolean rawNoId; - private final boolean disableLazyLoad; - private final SpiQuery.TemporalMode temporalMode; - private SqlTreeNode rootNode; - private boolean sqlDistinct; /** @@ -103,9 +87,9 @@ public final class SqlTreeBuilder { this.temporalMode = SpiQuery.TemporalMode.of(query); this.disableLazyLoad = query.isDisableLazyLoading(); this.subQuery = Type.SQ_EXISTS == query.getType() - || Type.SQ_IN == query.getType() - || Type.ID_LIST == query.getType() - || Type.DELETE == query.getType() + || Type.SQ_IN == query.getType() + || Type.ID_LIST == query.getType() + || Type.DELETE == query.getType() || query.isCountDistinct(); this.includeJoin = query.getM2mIncludeJoin(); this.manyWhereJoins = query.getManyWhereJoins(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java index 1c9bff694..83c8362a9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeBean.java @@ -28,58 +28,40 @@ class SqlTreeNodeBean implements SqlTreeNode { private static final SqlTreeNode[] NO_CHILDREN = new SqlTreeNode[0]; final STreeType desc; - final IdBinder idBinder; - /** * The children which will be other SelectBean or SelectProxyBean. */ final SqlTreeNode[] children; - /** * Set to true if this is a partial object fetch. */ private final boolean partialObject; - private final STreeProperty[] properties; - /** * Extra where clause added by Where annotation on associated many. */ private final String extraWhere; - private final STreePropertyAssoc nodeBeanProp; - /** * False if report bean and has no id property. */ final boolean readId; private final boolean readIdNormal; - private final boolean disableLazyLoad; - private final InheritInfo inheritInfo; - final String prefix; - private final Map pathMap; - final STreePropertyAssocMany lazyLoadParent; - private final SpiQuery.TemporalMode temporalMode; - private final boolean temporalVersions; - private final IdBinder lazyLoadParentIdBinder; - String baseTableAlias; - /** * Table alias set if this bean node includes a join to a intersection * table and that table has history support. */ private boolean intersectionAsOfTableAlias; - private final boolean aggregation; /** @@ -131,12 +113,12 @@ class SqlTreeNodeBean implements SqlTreeNode { } @Override - public boolean isSingleProperty() { + public final boolean isSingleProperty() { return properties != null && properties.length == 1 && children.length == 0; } @Override - public ScalarDataReader getSingleAttributeReader() { + public final ScalarDataReader getSingleAttributeReader() { if (properties == null || properties.length == 0) { // if we have no property ask first children (in a distinct select with join) if (children.length == 0) { @@ -172,7 +154,7 @@ class SqlTreeNodeBean implements SqlTreeNode { } @Override - public void buildRawSqlSelectChain(List selectChain) { + public final void buildRawSqlSelectChain(List selectChain) { if (readId) { if (inheritInfo != null) { // discriminator column always proceeds id column @@ -194,7 +176,7 @@ class SqlTreeNodeBean implements SqlTreeNode { /** * Load that takes into account inheritance. */ - private class LoadInherit extends Load { + private final class LoadInherit extends Load { private LoadInherit(DbReadContext ctx, EntityBean parentBean) { super(ctx, parentBean); @@ -437,7 +419,7 @@ class SqlTreeNodeBean implements SqlTreeNode { /** * Perform the load returning the loaded bean. */ - EntityBean perform() throws SQLException { + final EntityBean perform() throws SQLException { initialise(); if (isLazyLoadManyRoot()) { return getContextBean(); @@ -451,7 +433,7 @@ class SqlTreeNodeBean implements SqlTreeNode { * Return true if this bean was already in the context. If already in the * context we need to check if it is already contained in the collection. */ - boolean isContextBean() { + final boolean isContextBean() { return localBean == null; } } @@ -467,12 +449,12 @@ class SqlTreeNodeBean implements SqlTreeNode { /** * Create the loader with or without inheritance. */ - Load createLoad(DbReadContext ctx, EntityBean parentBean) { + final Load createLoad(DbReadContext ctx, EntityBean parentBean) { return (inheritInfo != null) ? new LoadInherit(ctx, parentBean) : new Load(ctx, parentBean); } @Override - public void appendGroupBy(DbSqlContext ctx, boolean subQuery) { + public final void appendGroupBy(DbSqlContext ctx, boolean subQuery) { ctx.pushJoin(prefix); ctx.pushTableAlias(prefix); if (lazyLoadParent != null) { @@ -507,7 +489,7 @@ class SqlTreeNodeBean implements SqlTreeNode { * Append the property columns to the buffer. */ @Override - public void appendSelect(DbSqlContext ctx, boolean subQuery) { + public final void appendSelect(DbSqlContext ctx, boolean subQuery) { ctx.pushJoin(prefix); ctx.pushTableAlias(prefix); if (temporalVersions) { @@ -532,7 +514,7 @@ class SqlTreeNodeBean implements SqlTreeNode { } @Override - public boolean isAggregation() { + public final boolean isAggregation() { if (aggregation) { return true; } @@ -553,14 +535,14 @@ class SqlTreeNodeBean implements SqlTreeNode { } } - void appendSelectId(DbSqlContext ctx, STreeProperty prop) { + final void appendSelectId(DbSqlContext ctx, STreeProperty prop) { if (prop != null) { prop.appendSelect(ctx, false); } } @Override - public void appendWhere(DbSqlContext ctx) { + public final void appendWhere(DbSqlContext ctx) { // Only apply inheritance to root node as any join will already have the inheritance join include - see TableJoin if (inheritInfo != null && nodeBeanProp == null) { if (!inheritInfo.isRoot()) { @@ -618,7 +600,7 @@ class SqlTreeNodeBean implements SqlTreeNode { } @Override - public void addSoftDeletePredicate(SpiQuery query) { + public final void addSoftDeletePredicate(SpiQuery query) { if (desc.isSoftDelete()) { query.addSoftDeletePredicate(desc.getSoftDeletePredicate(baseTableAlias)); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java index 1b31ee08c..ae5e5bf3f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeExtraJoin.java @@ -1,6 +1,5 @@ package io.ebeaninternal.server.query; -import io.ebean.Version; import io.ebean.bean.EntityBean; import io.ebean.core.type.ScalarType; import io.ebean.util.SplitName; @@ -22,7 +21,7 @@ import java.util.Set; * etc in this case we must add an extra join. *

*/ -class SqlTreeNodeExtraJoin implements SqlTreeNode { +final class SqlTreeNodeExtraJoin implements SqlTreeNode { private final STreePropertyAssoc assocBeanProperty; private final SpiQuery.TemporalMode temporalMode; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeFormulaWhereJoin.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeFormulaWhereJoin.java index 20a3037da..faf1ce4f1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeFormulaWhereJoin.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeFormulaWhereJoin.java @@ -1,6 +1,5 @@ package io.ebeaninternal.server.query; -import io.ebean.Version; import io.ebean.bean.EntityBean; import io.ebean.core.type.ScalarType; import io.ebeaninternal.api.SpiQuery; @@ -13,7 +12,7 @@ import java.util.Set; /** * Join to Many (or child of a many) to support where clause predicates on many properties. */ -class SqlTreeNodeFormulaWhereJoin implements SqlTreeNode { +final class SqlTreeNodeFormulaWhereJoin implements SqlTreeNode { private final STreeProperty nodeBeanProp; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyWhereJoin.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyWhereJoin.java index c537c4bf7..c3f534a25 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyWhereJoin.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeManyWhereJoin.java @@ -1,6 +1,5 @@ package io.ebeaninternal.server.query; -import io.ebean.Version; import io.ebean.bean.EntityBean; import io.ebean.core.type.ScalarType; import io.ebean.util.SplitName; @@ -15,21 +14,16 @@ import java.util.Set; /** * Join to Many (or child of a many) to support where clause predicates on many properties. */ -class SqlTreeNodeManyWhereJoin implements SqlTreeNode { +final class SqlTreeNodeManyWhereJoin implements SqlTreeNode { private final String parentPrefix; - private final String prefix; - private final STreePropertyAssoc nodeBeanProp; - private final STreeType target; - /** * The many where join which is either INNER or OUTER. */ private final SqlJoinType manyJoinType; - private final boolean softDelete; SqlTreeNodeManyWhereJoin(String prefix, STreePropertyAssoc prop, SqlJoinType manyJoinType, SpiQuery.TemporalMode temporalMode) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeRoot.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeRoot.java index e52477cf1..a58c51cc5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeRoot.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeNodeRoot.java @@ -18,9 +18,7 @@ import java.util.Set; final class SqlTreeNodeRoot extends SqlTreeNodeBean implements SqlTreeRoot { private final TableJoin includeJoin; - private final boolean sqlDistinct; - private final String baseTable; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeProperties.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeProperties.java index f46ca8088..489341789 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeProperties.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/SqlTreeProperties.java @@ -10,24 +10,16 @@ import java.util.List; /** * The select properties for a node in the SqlTree. */ -public class SqlTreeProperties { +public final class SqlTreeProperties { - /** - * The bean properties in order. - */ private final List propsList = new ArrayList<>(); - /** * Maintain a list of property names to detect embedded bean additions. */ private final LinkedHashSet propNames = new LinkedHashSet<>(); - private boolean allProperties; - private boolean aggregationManyToOne; - private boolean aggregation; - private String aggregationPath; SqlTreeProperties() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/AbstractQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/AbstractQuery.java index 62fd3cdf0..4ad835188 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/AbstractQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/AbstractQuery.java @@ -15,14 +15,12 @@ import io.ebeaninternal.api.SpiCancelableQuery; */ public class AbstractQuery implements SpiCancelableQuery { + private final ReentrantLock lock = new ReentrantLock(); private boolean cancelled; - private CancelableQuery cancelableQuery; - private final ReentrantLock lock = new ReentrantLock(); - @Override - public void cancel() { + public final void cancel() { lock.lock(); try { if (!cancelled) { @@ -37,14 +35,14 @@ public class AbstractQuery implements SpiCancelableQuery { } @Override - public void checkCancelled() { + public final void checkCancelled() { if (cancelled) { throw new PersistenceException("Query was cancelled"); } } @Override - public void setCancelableQuery(CancelableQuery cancelableQuery) { + public final void setCancelableQuery(CancelableQuery cancelableQuery) { lock.lock(); try { checkCancelled(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultDtoQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultDtoQuery.java index c2cb02198..4a72c0057 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultDtoQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultDtoQuery.java @@ -21,35 +21,20 @@ import java.util.stream.Stream; /** * Default implementation of DtoQuery. */ -public class DefaultDtoQuery extends AbstractQuery implements SpiDtoQuery { +public final class DefaultDtoQuery extends AbstractQuery implements SpiDtoQuery { private final SpiEbeanServer server; - private final DtoBeanDescriptor descriptor; - private final SpiQuery ormQuery; - private String sql; - private int firstRow; - private int maxRows; - private int timeout; - private int bufferFetchSizeHint; - private boolean relaxedMode; - private String label; - private ProfileLocation profileLocation; - - /** - * Bind parameters when using the query language. - */ private final BindParams bindParams = new BindParams(); - private Transaction transaction; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java index b5aeec323..65ba6b9a3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java @@ -32,77 +32,47 @@ import java.util.stream.Stream; /** * Default implementation of an Object Relational query. */ -public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { +public final class DefaultOrmQuery extends AbstractQuery implements SpiQuery { private static final String DEFAULT_QUERY_NAME = "default"; - private static final FetchConfig FETCH_CACHE = FetchConfig.ofCache(); - private static final FetchConfig FETCH_QUERY = FetchConfig.ofQuery(); - private static final FetchConfig FETCH_LAZY = FetchConfig.ofLazy(); private final Class beanType; - private final ExpressionFactory expressionFactory; - private final BeanDescriptor rootBeanDescriptor; - private BeanDescriptor beanDescriptor; - private SpiEbeanServer server; - private SpiTransaction transaction; - /** * For lazy loading of ManyToMany we need to add a join to the intersection table. This is that * join to the intersection table. */ private TableJoin m2mIncludeJoin; - private ProfilingListener profilingListener; - private Type type; - private String label; - private Mode mode = Mode.NORMAL; - private Object tenantId; - /** * Holds query in structured form. */ private OrmQueryDetail detail; - private int maxRows; - private int firstRow; - - /** - * Set to true to disable lazy loading on the object graph returned. - */ private boolean disableLazyLoading; - /** * Lazy loading batch size (can override server wide default). */ private int lazyLoadBatchSize; - private OrderBy orderBy; - private String loadMode; - private String loadDescription; - private String generatedSql; - private String lazyLoadProperty; - private String lazyLoadManyPath; - private boolean allowLoadErrors; - /** * Flag set for report/DTO beans when we may choose to explicitly include the Id property. */ @@ -141,97 +111,55 @@ public class DefaultOrmQuery extends AbstractQuery implements SpiQuery { * Bind parameters when using the query language. */ private BindParams bindParams; - private DefaultExpressionList textExpressions; - private DefaultExpressionList whereExpressions; - private DefaultExpressionList havingExpressions; - private boolean asOfBaseTable; - private int asOfTableCount; /** * Set for flashback style 'as of' query. */ private Timestamp asOf; - private TemporalMode temporalMode = TemporalMode.CURRENT; - private Timestamp versionsStart; private Timestamp versionsEnd; - private List softDeletePredicates; - private boolean disableReadAudit; - private int bufferFetchSizeHint; - private boolean usageProfiling = true; - private CacheMode useBeanCache = CacheMode.AUTO; - private CacheMode useQueryCache = CacheMode.OFF; - private Boolean readOnly; - private PersistenceContextScope persistenceContextScope; /** * Allow for explicit on off or null for default. */ private Boolean autoTune; - private LockWait forUpdate; private LockType lockType; - private boolean singleAttribute; - private CountDistinctOrder countDistinctOrder; - - /** - * Set to true if this query has been tuned by autoTune. - */ private boolean autoTuned; - - /** - * Root table alias. For {@link Query#alias(String)} command. - */ private String rootTableAlias; - private String baseTable; - /** * The node of the bean or collection that fired lazy loading. Not null if profiling is on and * this query is for lazy loading. Used to hook back a lazy loading query to the "original" query * point. */ private ObjectGraphNode parentNode; - private BeanPropertyAssocMany lazyLoadForParentsProperty; - - /** - * Hash of final query after AutoTune tuning. - */ private CQueryPlanKey queryPlanKey; - private PersistenceContext persistenceContext; - private ManyWhereJoins manyWhereJoins; - private SpiRawSql rawSql; - private boolean useDocStore; - private String docIndexName; - private OrmUpdateProperties updateProperties; - private String nativeSql; - private boolean orderById; - private ProfileLocation profileLocation; public DefaultOrmQuery(BeanDescriptor desc, SpiEbeanServer server, ExpressionFactory expressionFactory) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmUpdate.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmUpdate.java index 0381df322..88b84fc2f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmUpdate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmUpdate.java @@ -14,41 +14,21 @@ public final class DefaultOrmUpdate implements SpiUpdate, Serializable { private static final long serialVersionUID = -8791423602246515438L; - private transient final EbeanServer server; - private final Class beanType; - - /** - * The name of the update. - */ private final String name; - private String label; - - /** - * The parameters used to bind to the sql. - */ private final BindParams bindParams = new BindParams(); - - /** - * The sql update or delete statement. - */ private final String updateStatement; - /** * Automatically detect the table being modified by this sql. This will * register this information so that eBean invalidates cached objects if * required. */ private boolean notifyCache = true; - private int timeout; - private String generatedSql; - private final String baseTable; - private final OrmUpdateType type; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultRelationalQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultRelationalQuery.java index 6afe54a1f..879d1bdaf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultRelationalQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultRelationalQuery.java @@ -17,27 +17,17 @@ import java.util.function.Predicate; /** * Default implementation of SQuery - SQL Query. */ -public class DefaultRelationalQuery extends AbstractQuery implements SpiSqlQuery { +public final class DefaultRelationalQuery extends AbstractQuery implements SpiSqlQuery { private static final long serialVersionUID = -1098305779779591068L; private final transient SpiEbeanServer server; - private final String query; - private String label; - private int firstRow; - private int maxRows; - private int timeout; - private int bufferFetchSizeHint; - - /** - * Bind parameters when using the query language. - */ private final BindParams bindParams = new BindParams(); /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultUpdateQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultUpdateQuery.java index 897424b8a..c9ed9ca11 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultUpdateQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultUpdateQuery.java @@ -10,7 +10,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Default implementation of UpdateQuery. */ -public class DefaultUpdateQuery implements UpdateQuery { +public final class DefaultUpdateQuery implements UpdateQuery { private final OrmUpdateProperties values = new OrmUpdateProperties(); private final DefaultOrmQuery query; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/NaturalKeyBindParam.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/NaturalKeyBindParam.java index 3655a3ef4..301ec4ef3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/NaturalKeyBindParam.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/NaturalKeyBindParam.java @@ -1,9 +1,8 @@ package io.ebeaninternal.server.querydefn; -public class NaturalKeyBindParam { +public final class NaturalKeyBindParam { private final String name; - private final Object value; public NaturalKeyBindParam(String name, Object value) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/ONamedParam.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/ONamedParam.java index e63526063..f2585a708 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/ONamedParam.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/ONamedParam.java @@ -7,10 +7,9 @@ import javax.persistence.PersistenceException; /** * Named parameter used as placeholder in expressions created by EQL language parsing. */ -class ONamedParam implements SpiNamedParam { +final class ONamedParam implements SpiNamedParam { private final String name; - private Object value; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetail.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetail.java index 2fabfdd79..90f4cbac1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetail.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetail.java @@ -21,7 +21,7 @@ import java.util.*; * Tuning a query is a matter of replacing an instance of this class with one that has been tuned * with select() and join() set. */ -public class OrmQueryDetail implements Serializable { +public final class OrmQueryDetail implements Serializable { private static final long serialVersionUID = -2510486880141461807L; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetailParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetailParser.java index 0314b55b6..744f70ebf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetailParser.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetailParser.java @@ -9,10 +9,9 @@ import javax.persistence.PersistenceException; * replace the OrmQueryDetail leaving the attributes unchanged. *

*/ -public class OrmQueryDetailParser { +public final class OrmQueryDetailParser { private final OrmQueryDetail detail = new OrmQueryDetail(); - private final SimpleTextParser parser; public OrmQueryDetailParser(String oql) { @@ -20,7 +19,6 @@ public class OrmQueryDetailParser { } public OrmQueryDetail parse() throws PersistenceException { - if (parser.isEmpty()) return detail; parser.nextWord(); @@ -68,7 +66,6 @@ public class OrmQueryDetailParser { } private OrmQueryProperties readFindFetch() { - boolean readAlias = false; String props = null; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryLimitRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryLimitRequest.java index 99354bf71..a36889557 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryLimitRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryLimitRequest.java @@ -4,16 +4,12 @@ import io.ebean.config.dbplatform.DatabasePlatform; import io.ebean.config.dbplatform.SqlLimitRequest; import io.ebeaninternal.api.SpiQuery; -public class OrmQueryLimitRequest implements SqlLimitRequest { +public final class OrmQueryLimitRequest implements SqlLimitRequest { private final SpiQuery ormQuery; - private final DatabasePlatform dbPlatform; - private final String sql; - private final String sqlOrderBy; - private final boolean distinct; public OrmQueryLimitRequest(String sql, String sqlOrderBy, SpiQuery ormQuery, DatabasePlatform dbPlatform, boolean distinct) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java index 3a9ac8e33..3ce478c92 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java @@ -8,7 +8,7 @@ import java.util.Objects; /** * Query plan key for ORM queries. */ -class OrmQueryPlanKey implements CQueryPlanKey { +final class OrmQueryPlanKey implements CQueryPlanKey { private final SpiRawSql.Key rawSqlKey; private final int maxRows; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryProperties.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryProperties.java index 0a8b51465..98864e744 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryProperties.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryProperties.java @@ -23,7 +23,7 @@ import java.util.Set; /** * Represents the Properties of an Object Relational query. */ -public class OrmQueryProperties implements Serializable { +public final class OrmQueryProperties implements Serializable { private static final long serialVersionUID = -8785582703966455658L; @@ -35,30 +35,24 @@ public class OrmQueryProperties implements Serializable { private final Set included; private final FetchConfig fetchConfig; private final boolean cache; - /** * Flag set when this fetch path needs to be a query join. */ private boolean markForQueryJoin; - /** * Included bean joins. */ private Set includedBeanJoin; - /** * Add these properties to the select so that the foreign key columns are included in the query. */ private Set secondaryQueryJoins; - private List secondaryChildren; - /** * OrderBy properties that where on the main query but moved here as they relate to this (query join). */ @SuppressWarnings("rawtypes") private OrderBy orderBy; - /** * A filter that can be applied to the fetch of this path in the object graph. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQuerySecondary.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQuerySecondary.java index 738566597..4d2a94b1c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQuerySecondary.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQuerySecondary.java @@ -7,10 +7,9 @@ import java.util.List; /** * The secondary query paths for 'query joins' and 'lazy loading'. */ -class OrmQuerySecondary implements SpiQuerySecondary { +final class OrmQuerySecondary implements SpiQuerySecondary { private final List queryJoins; - private final List lazyJoins; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmUpdateProperties.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmUpdateProperties.java index 930e653f4..5a9d5b392 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmUpdateProperties.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmUpdateProperties.java @@ -13,10 +13,9 @@ import java.util.Set; /** * Set properties for a UpdateQuery. */ -public class OrmUpdateProperties { +public final class OrmUpdateProperties { private static final NullValue NULL_VALUE = new NullValue(); - private static final NoneValue NONE_VALUE = new NoneValue(); /** @@ -41,7 +40,7 @@ public class OrmUpdateProperties { /** * Set property to null. */ - private static class NullValue extends Value { + private static final class NullValue extends Value { @Override public String bindClause() { return "=null"; @@ -51,7 +50,7 @@ public class OrmUpdateProperties { /** * Set property to a simple value. */ - private static class SimpleValue extends Value { + private static final class SimpleValue extends Value { final Object value; final ScalarType scalarType; @@ -85,7 +84,7 @@ public class OrmUpdateProperties { /** * Set using an expression with no bind value. */ - private static class NoneValue extends Value { + private static final class NoneValue extends Value { @Override public String bindClause() { return ""; @@ -95,7 +94,7 @@ public class OrmUpdateProperties { /** * Set using an expression with many bind values. */ - private static class RawArrayValue extends Value { + private static final class RawArrayValue extends Value { final Object[] bindValues; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/SimpleTextParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/SimpleTextParser.java index 849234e8c..0072c8eec 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/SimpleTextParser.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/SimpleTextParser.java @@ -1,11 +1,10 @@ package io.ebeaninternal.server.querydefn; -public class SimpleTextParser { +public final class SimpleTextParser { private final String oql; private final char[] chars; private final int eof; - private int pos; private String word; private String lowerWord; From f3b0e34b673c15feb5ca0c83ea5d665f5c5e3ca1 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 09:16:31 +1200 Subject: [PATCH 094/120] #2315 - Refactor internals - make more classes final in transaction packages --- .../properties/BeanPropertiesReader.java | 3 +- .../server/transaction/BeanPersistIds.java | 4 +- .../transaction/BulkEventListenerMap.java | 6 +- .../transaction/DefaultProfileHandler.java | 2 +- .../transaction/DefaultProfileStream.java | 2 +- .../DefaultTransactionScopeManager.java | 11 +- .../transaction/DocStoreOnlyTransaction.java | 2 +- .../DocStoreTransactionManager.java | 2 +- .../ExternalTransactionScopeManager.java | 2 +- .../ImplicitReadOnlyTransaction.java | 2 +- .../server/transaction/JdbcTransaction.java | 169 +++++++++--------- .../server/transaction/JtaTransaction.java | 2 +- .../transaction/JtaTransactionManager.java | 2 +- .../server/transaction/NoTransaction.java | 4 +- .../transaction/NoopProfileHandler.java | 2 +- .../server/transaction/RemoteTableMod.java | 2 +- .../transaction/RemoteTransactionEvent.java | 2 +- .../transaction/SavepointTransaction.java | 2 +- .../server/transaction/TChangeLogHolder.java | 2 +- .../server/transaction/TableModState.java | 2 +- .../transaction/TransactionFactory.java | 5 +- .../transaction/TransactionFactoryBasic.java | 3 +- .../TransactionFactoryBasicWithRead.java | 5 +- .../TransactionFactoryBuilder.java | 2 +- .../transaction/TransactionFactoryTenant.java | 3 +- .../TransactionFactoryTenantWithRead.java | 5 +- .../transaction/TransactionManager.java | 90 +++++----- .../TransactionManagerOptions.java | 2 +- .../transaction/TransactionProfile.java | 2 +- 29 files changed, 161 insertions(+), 181 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/properties/BeanPropertiesReader.java b/ebean-core/src/main/java/io/ebeaninternal/server/properties/BeanPropertiesReader.java index e00fdf497..a283a42ea 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/properties/BeanPropertiesReader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/properties/BeanPropertiesReader.java @@ -8,10 +8,9 @@ import java.util.Map; /** * Determines the properties on a given bean. */ -public class BeanPropertiesReader { +public final class BeanPropertiesReader { private final Map propertyIndexMap = new HashMap<>(); - private final String[] props; public BeanPropertiesReader(Class clazz) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/BeanPersistIds.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/BeanPersistIds.java index bb1690bfe..280f3c28f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/BeanPersistIds.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/BeanPersistIds.java @@ -28,12 +28,10 @@ import java.util.List; * size of data sent around the network. *

*/ -public class BeanPersistIds implements BinaryWritable { +public final class BeanPersistIds implements BinaryWritable { private final BeanDescriptor beanDescriptor; - private final String descriptorId; - /** * The ids to invalidate from the cache (updates and deletes). */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/BulkEventListenerMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/BulkEventListenerMap.java index 86a6428b7..bcc91909f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/BulkEventListenerMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/BulkEventListenerMap.java @@ -8,12 +8,11 @@ import java.util.HashMap; import java.util.List; import java.util.Set; -public class BulkEventListenerMap { +public final class BulkEventListenerMap { private final HashMap map = new HashMap<>(); public BulkEventListenerMap(List listeners) { - if (listeners != null) { for (BulkTableEventListener l : listeners) { Set tables = l.registeredTables(); @@ -29,7 +28,6 @@ public class BulkEventListenerMap { } public void process(BulkTableEvent event) { - Entry entry = map.get(event.getTableName()); if (entry != null) { entry.process(event); @@ -42,7 +40,7 @@ public class BulkEventListenerMap { entry.add(l); } - private static class Entry { + private static final class Entry { final List listeners = new ArrayList<>(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultProfileHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultProfileHandler.java index 38f5446d2..177e4bc15 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultProfileHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultProfileHandler.java @@ -38,7 +38,7 @@ import static java.time.temporal.ChronoField.YEAR; *

* Uses a sleep backoff on the single threaded consumer that reads the profiles and writes them to files. */ -public class DefaultProfileHandler implements SpiProfileHandler, Plugin { +public final class DefaultProfileHandler implements SpiProfileHandler, Plugin { private static final Logger log = LoggerFactory.getLogger(DefaultProfileHandler.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultProfileStream.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultProfileStream.java index bc2913137..38c38e3d5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultProfileStream.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultProfileStream.java @@ -5,7 +5,7 @@ import io.ebean.ProfileLocation; /** * Default transaction profiling event collection. */ -public class DefaultProfileStream implements ProfileStream { +public final class DefaultProfileStream implements ProfileStream { private final long startNanos; private final StringBuilder buffer; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultTransactionScopeManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultTransactionScopeManager.java index 0cabba365..2ad93d490 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultTransactionScopeManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DefaultTransactionScopeManager.java @@ -9,7 +9,6 @@ import javax.persistence.PersistenceException; */ public class DefaultTransactionScopeManager extends TransactionScopeManager { - private final ThreadLocal local = new ThreadLocal<>(); @Override @@ -18,7 +17,7 @@ public class DefaultTransactionScopeManager extends TransactionScopeManager { } @Override - public SpiTransaction getInScope() { + public final SpiTransaction getInScope() { return local.get(); } @@ -33,7 +32,7 @@ public class DefaultTransactionScopeManager extends TransactionScopeManager { } @Override - public void replace(SpiTransaction trans) { + public final void replace(SpiTransaction trans) { if (trans == null) { throw new IllegalStateException("Setting a null transaction?"); } @@ -41,7 +40,7 @@ public class DefaultTransactionScopeManager extends TransactionScopeManager { } @Override - public void set(SpiTransaction trans) { + public final void set(SpiTransaction trans) { if (trans == null) { throw new IllegalStateException("Setting a null transaction?"); } @@ -50,13 +49,13 @@ public class DefaultTransactionScopeManager extends TransactionScopeManager { } @Override - public void clear() { + public final void clear() { checkForActiveTransaction(); local.remove(); } @Override - public void clearExternal() { + public final void clearExternal() { local.remove(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DocStoreOnlyTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DocStoreOnlyTransaction.java index 43fb216a5..0165fb1e8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DocStoreOnlyTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DocStoreOnlyTransaction.java @@ -5,7 +5,7 @@ import java.sql.Connection; /** * Document store only transaction. */ -public class DocStoreOnlyTransaction extends JdbcTransaction { +public final class DocStoreOnlyTransaction extends JdbcTransaction { /** * Create a new DocStore only Transaction. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DocStoreTransactionManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DocStoreTransactionManager.java index 364e46841..d23476c25 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DocStoreTransactionManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/DocStoreTransactionManager.java @@ -9,7 +9,7 @@ import java.sql.Connection; *

* There is no underlying JDBC DataSource etc */ -public class DocStoreTransactionManager extends TransactionManager { +public final class DocStoreTransactionManager extends TransactionManager { /** * Create the TransactionManager diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ExternalTransactionScopeManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ExternalTransactionScopeManager.java index b033e277b..6922e2129 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ExternalTransactionScopeManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ExternalTransactionScopeManager.java @@ -6,7 +6,7 @@ import io.ebeaninternal.api.SpiTransaction; /** * A TransactionScopeManager aware of external transaction managers. */ -public class ExternalTransactionScopeManager extends DefaultTransactionScopeManager { +public final class ExternalTransactionScopeManager extends DefaultTransactionScopeManager { private final ExternalTransactionManager externalManager; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java index e4e36e337..cbb4f7618 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java @@ -27,7 +27,7 @@ import java.util.Map; * persisting features are attempted to be used - which is not expected). *

*/ -class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEventCodes { +final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEventCodes { private static final Logger logger = LoggerFactory.getLogger(ImplicitReadOnlyTransaction.class); 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 f61f03699..d271d1c04 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 @@ -219,56 +219,56 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void setLabel(String label) { + public final void setLabel(String label) { this.label = label; } @Override - public String getLabel() { + public final String getLabel() { return label; } @Override - public long getStartNanoTime() { + public final long getStartNanoTime() { return startNanos; } @Override - public long profileOffset() { + public final long profileOffset() { return (profileStream == null) ? 0 : profileStream.offset(); } @Override - public void profileEvent(SpiProfileTransactionEvent event) { + public final void profileEvent(SpiProfileTransactionEvent event) { if (profileStream != null) { event.profile(); } } @Override - public void setProfileStream(ProfileStream profileStream) { + public final void setProfileStream(ProfileStream profileStream) { this.profileStream = profileStream; } @Override - public ProfileStream profileStream() { + public final ProfileStream profileStream() { return profileStream; } @Override - public void setProfileLocation(ProfileLocation profileLocation) { + public final void setProfileLocation(ProfileLocation profileLocation) { this.profileLocation = profileLocation; } @Override - public ProfileLocation getProfileLocation() { + public final ProfileLocation getProfileLocation() { return profileLocation; } /** * Overridden in AutoCommitJdbcTransaction as that expects to run/operate with autocommit true. */ - void checkAutoCommit(Connection connection) throws SQLException { + final void checkAutoCommit(Connection connection) throws SQLException { if (connection != null) { this.autoCommit = connection.getAutoCommit(); if (this.autoCommit) { @@ -289,34 +289,34 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void setAutoPersistUpdates(boolean autoPersistUpdates) { + public final void setAutoPersistUpdates(boolean autoPersistUpdates) { this.autoPersistUpdates = autoPersistUpdates; this.batchMode = true; } @Override - public boolean isAutoPersistUpdates() { + public final boolean isAutoPersistUpdates() { return autoPersistUpdates; } @Override - public boolean isSkipCacheExplicit() { + public final boolean isSkipCacheExplicit() { return (skipCache != null && !skipCache); } @Override - public boolean isSkipCache() { + public final boolean isSkipCache() { if (skipCache != null) return skipCache; return skipCacheAfterWrite && !queryOnly; } @Override - public void setSkipCache(boolean skipCache) { + public final void setSkipCache(boolean skipCache) { this.skipCache = skipCache; } @Override - public String getLogPrefix() { + public final String getLogPrefix() { return logPrefix; } @@ -330,7 +330,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void addBeanChange(BeanChange beanChange) { + public final void addBeanChange(BeanChange beanChange) { if (changeLogHolder == null) { changeLogHolder = new TChangeLogHolder(this, 100); } @@ -338,14 +338,14 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void sendChangeLog(ChangeSet changesRequest) { + public final void sendChangeLog(ChangeSet changesRequest) { if (manager != null) { manager.sendChangeLog(changesRequest); } } @Override - public void register(TransactionCallback callback) { + public final void register(TransactionCallback callback) { if (callbackList == null) { callbackList = new ArrayList<>(4); } @@ -391,27 +391,27 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public int getDocStoreBatchSize() { + public final int getDocStoreBatchSize() { return docStoreBatchSize; } @Override - public void setDocStoreBatchSize(int docStoreBatchSize) { + public final void setDocStoreBatchSize(int docStoreBatchSize) { this.docStoreBatchSize = docStoreBatchSize; } @Override - public DocStoreMode getDocStoreMode() { + public final DocStoreMode getDocStoreMode() { return docStoreMode; } @Override - public void setDocStoreMode(DocStoreMode docStoreMode) { + public final void setDocStoreMode(DocStoreMode docStoreMode) { this.docStoreMode = docStoreMode; } @Override - public void registerDeferred(PersistDeferredRelationship derived) { + public final void registerDeferred(PersistDeferredRelationship derived) { if (deferredList == null) { deferredList = new ArrayList<>(); } @@ -425,7 +425,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { *

*/ @Override - public void registerDeleteBean(Integer persistingBean) { + public final void registerDeleteBean(Integer persistingBean) { if (deletingBeansHash == null) { deletingBeansHash = new HashSet<>(); } @@ -436,7 +436,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Return true if this is a bean that has already been saved/deleted. */ @Override - public boolean isRegisteredDeleteBean(Integer persistingBean) { + public final boolean isRegisteredDeleteBean(Integer persistingBean) { return deletingBeansHash != null && deletingBeansHash.contains(persistingBean); } @@ -444,7 +444,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Unregister the persisted beans (when persisting at the top level). */ @Override - public void unregisterBeans() { + public final void unregisterBeans() { persistingBeans.clear(); } @@ -453,7 +453,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * register the bean if it is not already. */ @Override - public boolean isRegisteredBean(Object bean) { + public final boolean isRegisteredBean(Object bean) { if (persistingBeans == null) { persistingBeans = new IdentityHashMap<>(); } @@ -465,7 +465,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * This is to stop m2m intersection management via both directions of a m2m. */ @Override - public boolean isSaveAssocManyIntersection(String intersectionTable, String beanName) { + public final boolean isSaveAssocManyIntersection(String intersectionTable, String beanName) { if (m2mIntersectionSave == null) { // first attempt so yes allow this m2m intersection direction m2mIntersectionSave = new HashMap<>(); @@ -500,7 +500,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * @param diff the amount to add or subtract from the depth. */ @Override - public void depth(int diff) { + public final void depth(int diff) { depth += diff; } @@ -508,12 +508,12 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Return the current depth. */ @Override - public int depth() { + public final int depth() { return depth; } @Override - public void markNotQueryOnly() { + public final void markNotQueryOnly() { this.queryOnly = false; } @@ -543,17 +543,17 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties) { + public final void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties) { this.updateAllLoadedProperties = updateAllLoadedProperties; } @Override - public Boolean isUpdateAllLoadedProperties() { + public final Boolean isUpdateAllLoadedProperties() { return updateAllLoadedProperties; } @Override - public void setBatchMode(boolean batchMode) { + public final void setBatchMode(boolean batchMode) { if (!isActive()) { throw new IllegalStateException(illegalStateMessage); } @@ -561,12 +561,12 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public boolean isBatchMode() { + public final boolean isBatchMode() { return batchMode; } @Override - public void setBatchOnCascade(boolean batchMode) { + public final void setBatchOnCascade(boolean batchMode) { if (!isActive()) { throw new IllegalStateException(illegalStateMessage); } @@ -574,17 +574,17 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public boolean isBatchOnCascade() { + public final boolean isBatchOnCascade() { return batchOnCascadeMode; } @Override - public Boolean getBatchGetGeneratedKeys() { + public final Boolean getBatchGetGeneratedKeys() { return batchGetGeneratedKeys; } @Override - public void setGetGeneratedKeys(boolean getGeneratedKeys) { + public final void setGetGeneratedKeys(boolean getGeneratedKeys) { this.batchGetGeneratedKeys = getGeneratedKeys; if (batchControl != null) { batchControl.setGetGeneratedKeys(getGeneratedKeys); @@ -592,7 +592,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void setFlushOnMixed(boolean batchFlushOnMixed) { + public final void setFlushOnMixed(boolean batchFlushOnMixed) { this.batchFlushOnMixed = batchFlushOnMixed; if (batchControl != null) { batchControl.setBatchFlushOnMixed(batchFlushOnMixed); @@ -606,12 +606,12 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { *

*/ @Override - public int getBatchSize() { + public final int getBatchSize() { return batchSize; } @Override - public void setBatchSize(int batchSize) { + public final void setBatchSize(int batchSize) { this.batchSize = batchSize; if (batchControl != null) { batchControl.setBatchSize(batchSize); @@ -619,12 +619,12 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public boolean isFlushOnQuery() { + public final boolean isFlushOnQuery() { return batchFlushOnQuery; } @Override - public void setFlushOnQuery(boolean batchFlushOnQuery) { + public final void setFlushOnQuery(boolean batchFlushOnQuery) { this.batchFlushOnQuery = batchFlushOnQuery; } @@ -633,12 +633,12 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * this request should be executed immediately. */ @Override - public boolean isBatchThisRequest() { + public final boolean isBatchThisRequest() { return batchMode; } @Override - public void checkBatchEscalationOnCollection() { + public final void checkBatchEscalationOnCollection() { if (!batchMode && batchOnCascadeMode) { batchMode = true; batchOnCascadeSet = true; @@ -646,7 +646,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void flushBatchOnCollection() { + public final void flushBatchOnCollection() { if (batchOnCascadeSet) { batchFlushReset(); // restore the previous batch mode of NONE @@ -675,7 +675,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public PersistenceException translate(String message, SQLException cause) { + public final PersistenceException translate(String message, SQLException cause) { if (manager != null) { return manager.translate(message, cause); } @@ -686,14 +686,14 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Flush after completing persist cascade. */ @Override - public void flushBatchOnCascade() { + public final void flushBatchOnCascade() { batchFlushReset(); // restore the previous batch mode batchMode = oldBatchMode; } @Override - public void flushBatchOnRollback() { + public final void flushBatchOnRollback() { internalBatchClear(); // restore the previous batch mode batchMode = oldBatchMode; @@ -709,13 +709,11 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public boolean checkBatchEscalationOnCascade(PersistRequestBean request) { - + public final boolean checkBatchEscalationOnCascade(PersistRequestBean request) { if (batchMode) { // already batching (at top level) return false; } - if (batchOnCascadeMode) { // escalate up to batch mode for this request (and cascade) oldBatchMode = false; @@ -725,13 +723,12 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { request.setSkipBatchForTopLevel(); return true; } - batchFlushReset(); return false; } @Override - public BatchControl getBatchControl() { + public final BatchControl getBatchControl() { return batchControl; } @@ -740,7 +737,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * on the first persist request. */ @Override - public void setBatchControl(BatchControl batchControl) { + public final void setBatchControl(BatchControl batchControl) { queryOnly = false; this.batchControl = batchControl; // in case these parameters have already been set @@ -763,7 +760,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { *

*/ @Override - public void flush() { + public final void flush() { if (!isActive()) { throw new IllegalStateException(illegalStateMessage); } @@ -771,7 +768,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void flushBatch() { + public final void flushBatch() { flush(); } @@ -797,7 +794,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Return the persistence context associated with this transaction. */ @Override - public SpiPersistenceContext getPersistenceContext() { + public final SpiPersistenceContext getPersistenceContext() { return persistenceContext; } @@ -809,7 +806,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * then set it back later to a second transaction. */ @Override - public void setPersistenceContext(SpiPersistenceContext context) { + public final void setPersistenceContext(SpiPersistenceContext context) { if (!isActive()) { throw new IllegalStateException(illegalStateMessage); } @@ -820,7 +817,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Return the underlying TransactionEvent. */ @Override - public TransactionEvent getEvent() { + public final TransactionEvent getEvent() { queryOnly = false; if (event == null) { event = new TransactionEvent(); @@ -832,27 +829,27 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Return true if this was an explicitly created transaction. */ @Override - public boolean isExplicit() { + public final boolean isExplicit() { return explicit; } @Override - public boolean isLogSql() { + public final boolean isLogSql() { return logSql; } @Override - public boolean isLogSummary() { + public final boolean isLogSummary() { return logSummary; } @Override - public void logSql(String msg) { + public final void logSql(String msg) { manager.log().sql().debug(Str.add(logPrefix, msg)); } @Override - public void logSummary(String msg) { + public final void logSummary(String msg) { manager.log().sum().debug(Str.add(logPrefix, msg)); } @@ -860,17 +857,17 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Return the transaction id. */ @Override - public String getId() { + public final String getId() { return id; } @Override - public void setTenantId(Object tenantId) { + public final void setTenantId(Object tenantId) { this.tenantId = tenantId; } @Override - public Object getTenantId() { + public final Object getTenantId() { return tenantId; } @@ -926,7 +923,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { /** * Notify the transaction manager. */ - void notifyCommit() { + final void notifyCommit() { if (manager != null) { if (queryOnly) { manager.notifyOfQueryOnly(this); @@ -1000,13 +997,13 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void postCommit() { + public final void postCommit() { firePostCommit(); notifyCommit(); } @Override - public void preCommit() { + public final void preCommit() { internalBatchFlush(); firePreCommit(); } @@ -1081,7 +1078,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { /** * Notify the transaction manager. */ - void notifyRollback(Throwable cause) { + final void notifyRollback(Throwable cause) { if (manager != null) { if (queryOnly) { manager.notifyOfQueryOnly(this); @@ -1095,7 +1092,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Return true if the transaction is marked as rollback only. */ @Override - public boolean isRollbackOnly() { + public final boolean isRollbackOnly() { return rollbackOnly; } @@ -1103,17 +1100,17 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Mark the transaction as rollback only. */ @Override - public void setRollbackOnly() { + public final void setRollbackOnly() { this.rollbackOnly = true; } @Override - public boolean isNestedUseSavepoint() { + public final boolean isNestedUseSavepoint() { return nestedUseSavepoint; } @Override - public void setNestedUseSavepoint() { + public final void setNestedUseSavepoint() { this.nestedUseSavepoint = true; } @@ -1159,7 +1156,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void postRollback(Throwable cause) { + public final void postRollback(Throwable cause) { firePostRollback(); notifyRollback(cause); } @@ -1183,22 +1180,22 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public boolean isPersistCascade() { + public final boolean isPersistCascade() { return persistCascade; } @Override - public void setPersistCascade(boolean persistCascade) { + public final void setPersistCascade(boolean persistCascade) { this.persistCascade = persistCascade; } @Override - public void addModification(String tableName, boolean inserts, boolean updates, boolean deletes) { + public final void addModification(String tableName, boolean inserts, boolean updates, boolean deletes) { getEvent().add(tableName, inserts, updates, deletes); } @Override - public DocStoreTransaction getDocStoreTransaction() { + public final DocStoreTransaction getDocStoreTransaction() { if (docStoreTxn == null) { queryOnly = false; docStoreTxn = manager.createDocStoreTransaction(docStoreBatchSize); @@ -1207,7 +1204,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public void putUserObject(String name, Object value) { + public final void putUserObject(String name, Object value) { if (userObjects == null) { userObjects = new HashMap<>(); } @@ -1215,7 +1212,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { } @Override - public Object getUserObject(String name) { + public final Object getUserObject(String name) { if (userObjects == null) { return null; } @@ -1226,7 +1223,7 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes { * Alias for end(), which enables this class to be used in try-with-resources. */ @Override - public void close() { + public final void close() { end(); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransaction.java index e0c33a193..cfd76c581 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransaction.java @@ -9,7 +9,7 @@ import java.sql.SQLException; /** * Jta based transaction. */ -public class JtaTransaction extends JdbcTransaction { +public final class JtaTransaction extends JdbcTransaction { private final UserTransaction userTransaction; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransactionManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransactionManager.java index cc9e8cdc8..2168a287b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransactionManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransactionManager.java @@ -18,7 +18,7 @@ import javax.transaction.UserTransaction; /** * Hook into external JTA transaction manager. */ -public class JtaTransactionManager implements ExternalTransactionManager { +public final class JtaTransactionManager implements ExternalTransactionManager { private static final Logger logger = LoggerFactory.getLogger(JtaTransactionManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java index d435e93fd..0ed17e94f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java @@ -19,9 +19,9 @@ import java.sql.Connection; import java.sql.SQLException; /** - * Place holder for use with SUPPORTS and NEVER transactional when there really isn't a transaction. + * Placeholder for use with SUPPORTS and NEVER transactional when there really isn't a transaction. */ -class NoTransaction implements SpiTransaction { +final class NoTransaction implements SpiTransaction { static final NoTransaction INSTANCE = new NoTransaction(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoopProfileHandler.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoopProfileHandler.java index 636ad7c6a..a994987c5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoopProfileHandler.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoopProfileHandler.java @@ -6,7 +6,7 @@ import io.ebeaninternal.api.SpiProfileHandler; /** * A do nothing SpiProfileHandler. */ -public class NoopProfileHandler implements SpiProfileHandler { +public final class NoopProfileHandler implements SpiProfileHandler { @Override public void collectTransactionProfile(TransactionProfile transactionProfile) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/RemoteTableMod.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/RemoteTableMod.java index f963aad71..a3b97ec2a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/RemoteTableMod.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/RemoteTableMod.java @@ -9,7 +9,7 @@ import java.io.IOException; import java.util.LinkedHashSet; import java.util.Set; -public class RemoteTableMod implements BinaryWritable { +public final class RemoteTableMod implements BinaryWritable { private final long timestamp; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/RemoteTransactionEvent.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/RemoteTransactionEvent.java index 50480c043..8a9041eef 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/RemoteTransactionEvent.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/RemoteTransactionEvent.java @@ -14,7 +14,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -public class RemoteTransactionEvent implements Runnable, BinaryWritable { +public final class RemoteTransactionEvent implements Runnable, BinaryWritable { private final List beanPersistList = new ArrayList<>(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/SavepointTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/SavepointTransaction.java index dafaa05b5..aa4bc978e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/SavepointTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/SavepointTransaction.java @@ -12,7 +12,7 @@ import java.sql.Savepoint; /** * A nested transaction that represents a Savepoint. */ -class SavepointTransaction extends SpiTransactionProxy { +final class SavepointTransaction extends SpiTransactionProxy { private static final int STATE_COMMITTED = 1; private static final int STATE_ROLLED_BACK = 2; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TChangeLogHolder.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TChangeLogHolder.java index 961247bd9..b2a7269d0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TChangeLogHolder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TChangeLogHolder.java @@ -11,7 +11,7 @@ import java.util.UUID; * Holder of the changes handling the case when we send the changes * prior to commit or rollback as we hit the allowed 'batch size'. */ -public class TChangeLogHolder { +public final class TChangeLogHolder { /** * The owning transaction. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TableModState.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TableModState.java index e16fa6d81..d3793a8e4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TableModState.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TableModState.java @@ -17,7 +17,7 @@ import java.util.concurrent.ConcurrentHashMap; * This information is used to validate entries in the L2 query caches. *

*/ -public class TableModState implements QueryCacheEntryValidate, ServerCacheNotify { +public final class TableModState implements QueryCacheEntryValidate, ServerCacheNotify { private static final Logger log = LoggerFactory.getLogger("io.ebean.cache.TABLEMOD"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactory.java index 9a8684982..687741654 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactory.java @@ -33,8 +33,7 @@ abstract class TransactionFactory { /** * Set the Transaction Isolation level if required. */ - SpiTransaction setIsolationLevel(SpiTransaction t, boolean explicit, int isolationLevel) { - + final SpiTransaction setIsolationLevel(SpiTransaction t, boolean explicit, int isolationLevel) { if (isolationLevel > -1) { Connection connection = t.getConnection(); try { @@ -44,11 +43,9 @@ abstract class TransactionFactory { throw new PersistenceException(e); } } - if (explicit && manager.log().txn().isTrace()) { manager.log().txn().trace(t.getLogPrefix() + "Begin"); } - return t; } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBasic.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBasic.java index 1fd2f9e69..a190cf64e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBasic.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBasic.java @@ -22,7 +22,6 @@ class TransactionFactoryBasic extends TransactionFactory { @Override public SpiTransaction createReadOnlyTransaction(Object tenantId) { - Connection connection = null; try { connection = dataSource.getConnection(); @@ -37,7 +36,7 @@ class TransactionFactoryBasic extends TransactionFactory { } @Override - public SpiTransaction createTransaction(boolean explicit, int isolationLevel) { + public final SpiTransaction createTransaction(boolean explicit, int isolationLevel) { Connection connection = null; try { connection = dataSource.getConnection(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBasicWithRead.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBasicWithRead.java index c942ed31e..d84361480 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBasicWithRead.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBasicWithRead.java @@ -16,7 +16,7 @@ import java.sql.SQLException; * - Skip explicit commit (as we use AutoCommit instead) *

*/ -class TransactionFactoryBasicWithRead extends TransactionFactoryBasic { +final class TransactionFactoryBasicWithRead extends TransactionFactoryBasic { private final DataSource readOnlyDataSource; @@ -27,16 +27,13 @@ class TransactionFactoryBasicWithRead extends TransactionFactoryBasic { @Override public SpiTransaction createReadOnlyTransaction(Object tenantId) { - Connection connection = null; try { connection = readOnlyDataSource.getConnection(); return new ImplicitReadOnlyTransaction(manager, connection); - } catch (PersistenceException ex) { JdbcClose.close(connection); throw ex; - } catch (SQLException ex) { throw new PersistenceException(ex); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBuilder.java index 590fcec63..b2b7e875f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryBuilder.java @@ -5,7 +5,7 @@ import io.ebean.config.CurrentTenantProvider; /** * Helper to build and return the appropriate TransactionFactory. */ -class TransactionFactoryBuilder { +final class TransactionFactoryBuilder { /** * Build and return based on multi-tenancy and read only DataSource. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryTenant.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryTenant.java index fd70cd47a..64c9c9511 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryTenant.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryTenant.java @@ -29,8 +29,7 @@ class TransactionFactoryTenant extends TransactionFactory { } @Override - public SpiTransaction createTransaction(boolean explicit, int isolationLevel) { - + public final SpiTransaction createTransaction(boolean explicit, int isolationLevel) { SpiTransaction t = create(explicit, null); return setIsolationLevel(t, explicit, isolationLevel); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryTenantWithRead.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryTenantWithRead.java index 1aa190770..cb9f8c9c4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryTenantWithRead.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionFactoryTenantWithRead.java @@ -16,7 +16,7 @@ import java.sql.SQLException; * - Skip explicit commit (as we use AutoCommit instead) *

*/ -class TransactionFactoryTenantWithRead extends TransactionFactoryTenant { +final class TransactionFactoryTenantWithRead extends TransactionFactoryTenant { TransactionFactoryTenantWithRead(TransactionManager manager, DataSourceSupplier dataSourceSupplier, CurrentTenantProvider tenantProvider) { super(manager, dataSourceSupplier, tenantProvider); @@ -24,7 +24,6 @@ class TransactionFactoryTenantWithRead extends TransactionFactoryTenant { @Override public SpiTransaction createReadOnlyTransaction(Object tenantId) { - Connection connection = null; try { if (tenantId == null) { @@ -33,11 +32,9 @@ class TransactionFactoryTenantWithRead extends TransactionFactoryTenant { } connection = dataSourceSupplier.getReadOnlyConnection(tenantId); return new ImplicitReadOnlyTransaction(manager, connection, tenantId); - } catch (PersistenceException ex) { JdbcClose.close(connection); throw ex; - } catch (SQLException ex) { throw new PersistenceException(ex); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionManager.java index e3fbdd425..37a53f680 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionManager.java @@ -201,14 +201,14 @@ public class TransactionManager implements SpiTransactionManager { /** * Return the scope manager. */ - public TransactionScopeManager scope() { + public final TransactionScopeManager scope() { return scopeManager; } /** * Set the transaction onto the scope. */ - public void set(SpiTransaction txn) { + public final void set(SpiTransaction txn) { scopeManager.set(txn); } @@ -216,7 +216,7 @@ public class TransactionManager implements SpiTransactionManager { * Return the current active transaction. */ @Override - public SpiTransaction getActive() { + public final SpiTransaction getActive() { return scopeManager.getActive(); } @@ -230,18 +230,18 @@ public class TransactionManager implements SpiTransactionManager { /** * Return the current transaction from thread local scope. Note that it may be inactive. */ - public SpiTransaction getInScope() { + public final SpiTransaction getInScope() { return scopeManager.getInScope(); } /** * Translate the SQLException into a specific exception if possible based on the DB platform. */ - public PersistenceException translate(String message, SQLException cause) { + public final PersistenceException translate(String message, SQLException cause) { return databasePlatform.translate(message, cause); } - public void shutdown(boolean shutdownDataSource, boolean deregisterDriver) { + public final void shutdown(boolean shutdownDataSource, boolean deregisterDriver) { if (shutdownDataSource) { dataSourceSupplier.shutdown(deregisterDriver); } @@ -250,39 +250,39 @@ public class TransactionManager implements SpiTransactionManager { /** * Return true if the DB platform supports SavepointId(). */ - boolean isSupportsSavepointId() { + final boolean isSupportsSavepointId() { return supportsSavepointId; } - boolean isDocStoreActive() { + final boolean isDocStoreActive() { return docStoreActive; } - DocStoreTransaction createDocStoreTransaction(int docStoreBatchSize) { + final DocStoreTransaction createDocStoreTransaction(int docStoreBatchSize) { return docStoreUpdateProcessor.createTransaction(docStoreBatchSize); } - boolean isSkipCacheAfterWrite() { + final boolean isSkipCacheAfterWrite() { return skipCacheAfterWrite; } - public BeanDescriptorManager getBeanDescriptorManager() { + public final BeanDescriptorManager getBeanDescriptorManager() { return beanDescriptorManager; } - BulkEventListenerMap getBulkEventListenerMap() { + final BulkEventListenerMap getBulkEventListenerMap() { return bulkEventListenerMap; } - boolean isAutoPersistUpdates() { + final boolean isAutoPersistUpdates() { return autoPersistUpdates; } - boolean isPersistBatch() { + final boolean isPersistBatch() { return persistBatch; } - boolean isPersistBatchOnCascade() { + final boolean isPersistBatchOnCascade() { return persistBatchOnCascade; } @@ -296,7 +296,7 @@ public class TransactionManager implements SpiTransactionManager { * If the Isolation level is higher (say SERIALIZABLE) then Connections used * just for queries do need to be committed or rollback after the query. */ - OnQueryOnly initOnQueryOnly(OnQueryOnly dbPlatformOnQueryOnly) { + final OnQueryOnly initOnQueryOnly(OnQueryOnly dbPlatformOnQueryOnly) { // first check for a system property 'override' String systemPropertyValue = System.getProperty("ebean.transaction.onqueryonly"); if (systemPropertyValue != null) { @@ -306,29 +306,29 @@ public class TransactionManager implements SpiTransactionManager { return dbPlatformOnQueryOnly == null ? OnQueryOnly.COMMIT : dbPlatformOnQueryOnly; } - public String getServerName() { + public final String getServerName() { return serverName; } @Override - public Connection getQueryPlanConnection() throws SQLException { + public final Connection getQueryPlanConnection() throws SQLException { return dataSourceSupplier.getConnection(null); } @Override - public DataSource getDataSource() { + public final DataSource getDataSource() { return dataSourceSupplier.getDataSource(); } @Override - public DataSource getReadOnlyDataSource() { + public final DataSource getReadOnlyDataSource() { return dataSourceSupplier.getReadOnlyDataSource(); } /** * Defines the type of behavior to use when closing a transaction that was used to query data only. */ - OnQueryOnly getOnQueryOnly() { + final OnQueryOnly getOnQueryOnly() { return onQueryOnly; } @@ -390,7 +390,7 @@ public class TransactionManager implements SpiTransactionManager { * Process a local rolled back transaction. */ @Override - public void notifyOfRollback(SpiTransaction transaction, Throwable cause) { + public final void notifyOfRollback(SpiTransaction transaction, Throwable cause) { try { if (txnLogger.isDebug()) { String msg = transaction.getLogPrefix() + "Rollback"; @@ -408,7 +408,7 @@ public class TransactionManager implements SpiTransactionManager { * Query only transaction in read committed isolation. */ @Override - public void notifyOfQueryOnly(SpiTransaction transaction) { + public final void notifyOfQueryOnly(SpiTransaction transaction) { // Nothing that interesting here if (txnLogger.isTrace()) { txnLogger.trace(transaction.getLogPrefix() + "Commit - query only"); @@ -442,7 +442,7 @@ public class TransactionManager implements SpiTransactionManager { * Process a local committed transaction. */ @Override - public void notifyOfCommit(SpiTransaction transaction) { + public final void notifyOfCommit(SpiTransaction transaction) { try { if (txnLogger.isDebug()) { txnLogger.debug(transaction.getLogPrefix() + "Commit"); @@ -455,7 +455,7 @@ public class TransactionManager implements SpiTransactionManager { } } - public void externalModification(TransactionEventTable tableEvent) { + public final void externalModification(TransactionEventTable tableEvent) { SpiTransaction t = getActive(); if (t != null) { t.getEvent().add(tableEvent); @@ -476,7 +476,7 @@ public class TransactionManager implements SpiTransactionManager { /** * Notify local BeanPersistListeners etc of events from another server in the cluster. */ - public void remoteTransactionEvent(RemoteTransactionEvent remoteEvent) { + public final void remoteTransactionEvent(RemoteTransactionEvent remoteEvent) { if (clusterLogger.isDebugEnabled()) { clusterLogger.debug("processing {}", remoteEvent); } @@ -506,14 +506,14 @@ public class TransactionManager implements SpiTransactionManager { /** * Process the docstore / ElasticSearch updates. */ - void processDocStoreUpdates(DocStoreUpdates docStoreUpdates, int bulkBatchSize) { + final void processDocStoreUpdates(DocStoreUpdates docStoreUpdates, int bulkBatchSize) { docStoreUpdateProcessor.process(docStoreUpdates, bulkBatchSize); } /** * Prepare and then send/log the changeSet. */ - void sendChangeLog(final ChangeSet changeSet) { + final void sendChangeLog(final ChangeSet changeSet) { // can set userId, userIpAddress & userContext if desired if (changeLogPrepare.prepare(changeSet)) { if (changeLogAsync) { @@ -528,7 +528,7 @@ public class TransactionManager implements SpiTransactionManager { /** * Invalidate the query caches for entities based on views. */ - void processTouchedTables(Set touchedTables) { + final void processTouchedTables(Set touchedTables) { tableModState.touch(touchedTables); if (viewInvalidation) { beanDescriptorManager.processViewInvalidation(touchedTables); @@ -539,32 +539,32 @@ public class TransactionManager implements SpiTransactionManager { /** * Process the collected transaction profiling information. */ - void profileCollect(TransactionProfile transactionProfile) { + final void profileCollect(TransactionProfile transactionProfile) { profileHandler.collectTransactionProfile(transactionProfile); } /** * Collect execution time for an explicit transaction. */ - void collectMetric(long exeMicros) { + final void collectMetric(long exeMicros) { txnMain.add(exeMicros); } /** * Collect execution time for implicit read only transaction. */ - void collectMetricReadOnly(long exeMicros) { + final void collectMetricReadOnly(long exeMicros) { txnReadOnly.add(exeMicros); } /** * Collect execution time for a named transaction. */ - void collectMetricNamed(long exeMicros, String label) { + final void collectMetricNamed(long exeMicros, String label) { txnNamed.add(label, exeMicros); } - public void visitMetrics(MetricVisitor visitor) { + public final void visitMetrics(MetricVisitor visitor) { txnMain.visit(visitor); txnReadOnly.visit(visitor); txnNamed.visit(visitor); @@ -576,14 +576,14 @@ public class TransactionManager implements SpiTransactionManager { /** * Clear an implicit transaction from thread local scope. */ - public void clearServerTransaction() { + public final void clearServerTransaction() { scopeManager.clear(); } /** * Begin an implicit transaction. */ - public SpiTransaction beginServerTransaction() { + public final SpiTransaction beginServerTransaction() { SpiTransaction t = createTransaction(false, -1); scopeManager.set(t); return t; @@ -592,7 +592,7 @@ public class TransactionManager implements SpiTransactionManager { /** * Exit a scoped transaction (that can be inactive - already committed etc). */ - public void exitScopedTransaction(Object returnOrThrowable, int opCode) { + public final void exitScopedTransaction(Object returnOrThrowable, int opCode) { SpiTransaction st = getInScope(); if (st instanceof ScopedTransaction) { // can be null for Supports as that can start as a 'No Transaction' and then @@ -602,7 +602,7 @@ public class TransactionManager implements SpiTransactionManager { } @Override - public void externalRemoveTransaction() { + public final void externalRemoveTransaction() { scopeManager.clearExternal(); } @@ -611,7 +611,7 @@ public class TransactionManager implements SpiTransactionManager { * (e.g. Spring managed transaction). */ @Override - public ScopedTransaction externalBeginTransaction(SpiTransaction transaction, TxScope txScope) { + public final ScopedTransaction externalBeginTransaction(SpiTransaction transaction, TxScope txScope) { ScopedTransaction scopedTxn = new ScopedTransaction(scopeManager); scopedTxn.push(new ScopeTrans(rollbackOnChecked, false, transaction, txScope)); scopeManager.replace(scopedTxn); @@ -621,7 +621,7 @@ public class TransactionManager implements SpiTransactionManager { /** * Begin a scoped transaction. */ - public ScopedTransaction beginScopedTransaction(TxScope txScope) { + public final ScopedTransaction beginScopedTransaction(TxScope txScope) { txScope = initTxScope(txScope); ScopedTransaction txnContainer = getActiveScoped(); @@ -742,26 +742,26 @@ public class TransactionManager implements SpiTransactionManager { /** * Return true if Transaction debug is on. */ - public boolean isTxnDebug() { + public final boolean isTxnDebug() { return txnDebug; } - public SpiLogManager log() { + public final SpiLogManager log() { return logManager; } - public boolean isLogSql() { + public final boolean isLogSql() { return logManager.sql().isDebug(); } - public boolean isLogSummary() { + public final boolean isLogSummary() { return logManager.sum().isDebug(); } /** * Experimental - find dirty beans in the persistence context and persist them. */ - public void flushTransparent(SpiPersistenceContext persistenceContext, SpiTransaction transaction) { + public final void flushTransparent(SpiPersistenceContext persistenceContext, SpiTransaction transaction) { List dirtyBeans = persistenceContext.dirtyBeans(beanDescriptorManager); if (!dirtyBeans.isEmpty()) { server.updateAll(dirtyBeans, transaction); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionManagerOptions.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionManagerOptions.java index 5d0c87794..b7d54b37e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionManagerOptions.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionManagerOptions.java @@ -14,7 +14,7 @@ import io.ebeanservice.docstore.api.DocStoreUpdateProcessor; /** * Objects supplied for constructing the TransactionManager. */ -public class TransactionManagerOptions { +public final class TransactionManagerOptions { final SpiServer server; final boolean notifyL2CacheInForeground; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionProfile.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionProfile.java index 2c7006eba..cb749cd54 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionProfile.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/TransactionProfile.java @@ -5,7 +5,7 @@ import io.ebean.ProfileLocation; /** * Profiling information for a single transaction that has completed. */ -public class TransactionProfile { +public final class TransactionProfile { private final ProfileLocation location; private final String label; From 885ba0fdd2f4b19d628587a7380c491154a15358 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 09:18:31 +1200 Subject: [PATCH 095/120] Set autoReleaseAfterClose true --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dc3426809..1cebb8daa 100644 --- a/pom.xml +++ b/pom.xml @@ -38,7 +38,7 @@ - false + true 7.0 2.12.1 From 3c6d17c9a5fe6aeae200bf5784d9a75dbc80bd9e Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 09:23:11 +1200 Subject: [PATCH 096/120] [maven-release-plugin] prepare release ebean-parent-12.11.1 --- ebean-api/pom.xml | 2 +- ebean-autotune/pom.xml | 6 +++--- ebean-bom/pom.xml | 30 +++++++++++++++--------------- ebean-core-type/pom.xml | 4 ++-- ebean-core/pom.xml | 10 +++++----- ebean-ddl-generator/pom.xml | 6 +++--- ebean-externalmapping-api/pom.xml | 2 +- ebean-externalmapping-xml/pom.xml | 10 +++++----- ebean-postgis/pom.xml | 6 +++--- ebean-querybean/pom.xml | 10 +++++----- ebean-redis/pom.xml | 12 ++++++------ ebean-test/pom.xml | 6 +++--- ebean/pom.xml | 8 ++++---- kotlin-querybean-generator/pom.xml | 8 ++++---- pom.xml | 4 ++-- querybean-generator/pom.xml | 2 +- 16 files changed, 63 insertions(+), 63 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 72fbfe3ae..0e84c71c9 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean api diff --git a/ebean-autotune/pom.xml b/ebean-autotune/pom.xml index c47f7fe08..5bedfbd89 100644 --- a/ebean-autotune/pom.xml +++ b/ebean-autotune/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.8.0 + ebean-parent-12.11.1 ebean autotune @@ -26,7 +26,7 @@ io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 provided diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index fff064c90..9b651c8a2 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean bom @@ -81,88 +81,88 @@ io.ebean ebean - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-api - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-core-type - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-ddl-generator - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-externalmapping-api - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-externalmapping-xml - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-autotune - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-querybean - 12.11.1-SNAPSHOT + 12.11.1 io.ebean querybean-generator - 12.11.1-SNAPSHOT + 12.11.1 provided io.ebean kotlin-querybean-generator - 12.11.1-SNAPSHOT + 12.11.1 provided io.ebean ebean-test - 12.11.1-SNAPSHOT + 12.11.1 test io.ebean ebean-postgis - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-redis - 12.11.1-SNAPSHOT + 12.11.1 diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml index d8eab3e25..e0d543cfc 100644 --- a/ebean-core-type/pom.xml +++ b/ebean-core-type/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean-core-type @@ -16,7 +16,7 @@ io.ebean ebean-api - 12.11.1-SNAPSHOT + 12.11.1 diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index 5324aec82..cface4b9e 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -3,7 +3,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean-core @@ -15,7 +15,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.8.0 + ebean-parent-12.11.1 @@ -78,19 +78,19 @@ io.ebean ebean-api - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-core-type - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-externalmapping-api - 12.11.1-SNAPSHOT + 12.11.1 diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index f83a8b02e..2e9b2347b 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean ddl generation @@ -28,14 +28,14 @@ io.ebean ebean-core-type - 12.11.1-SNAPSHOT + 12.11.1 provided io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 provided diff --git a/ebean-externalmapping-api/pom.xml b/ebean-externalmapping-api/pom.xml index e506a6841..23962062a 100644 --- a/ebean-externalmapping-api/pom.xml +++ b/ebean-externalmapping-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean external mapping api diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index d0226a553..821436b6b 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.8.0 + ebean-parent-12.11.1 ebean external mapping xml @@ -33,7 +33,7 @@ io.ebean ebean-externalmapping-api - 12.11.1-SNAPSHOT + 12.11.1 @@ -59,14 +59,14 @@ io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 test io.ebean ebean-ddl-generator - 12.11.1-SNAPSHOT + 12.11.1 test diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml index 98b44522d..eb6d6fb4c 100644 --- a/ebean-postgis/pom.xml +++ b/ebean-postgis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean postgis @@ -23,7 +23,7 @@ io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 provided @@ -74,7 +74,7 @@ io.ebean ebean-test - 12.11.1-SNAPSHOT + 12.11.1 test diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml index 059976afa..87c0c3cdf 100644 --- a/ebean-querybean/pom.xml +++ b/ebean-querybean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean querybean @@ -17,7 +17,7 @@ io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 provided @@ -57,21 +57,21 @@ io.ebean ebean-ddl-generator - 12.11.1-SNAPSHOT + 12.11.1 test io.ebean querybean-generator - 12.11.1-SNAPSHOT + 12.11.1 test io.ebean ebean-test - 12.11.1-SNAPSHOT + 12.11.1 test diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index 943ab6985..eb22bf8b8 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean-redis @@ -22,35 +22,35 @@ io.ebean ebean-api - 12.11.1-SNAPSHOT + 12.11.1 provided io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 provided io.ebean ebean-querybean - 12.11.1-SNAPSHOT + 12.11.1 test io.ebean querybean-generator - 12.11.1-SNAPSHOT + 12.11.1 test io.ebean ebean-test - 12.11.1-SNAPSHOT + 12.11.1 test diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 4b9b05272..1d6ee0b9b 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean test @@ -29,14 +29,14 @@ io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 provided io.ebean ebean-ddl-generator - 12.11.1-SNAPSHOT + 12.11.1 diff --git a/ebean/pom.xml b/ebean/pom.xml index db01d91a1..892b73af6 100644 --- a/ebean/pom.xml +++ b/ebean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 ebean composite @@ -22,20 +22,20 @@ io.ebean ebean-api - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 io.ebean ebean-querybean - 12.11.1-SNAPSHOT + 12.11.1 diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml index 1b3f9d848..304a5e3e0 100644 --- a/kotlin-querybean-generator/pom.xml +++ b/kotlin-querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 kotlin querybean generator @@ -29,7 +29,7 @@ io.ebean ebean-querybean - 12.11.1-SNAPSHOT + 12.11.1 test @@ -43,7 +43,7 @@ io.ebean ebean-core - 12.11.1-SNAPSHOT + 12.11.1 test @@ -64,7 +64,7 @@ io.ebean ebean-ddl-generator - 12.11.1-SNAPSHOT + 12.11.1 test diff --git a/pom.xml b/pom.xml index 1cebb8daa..8374733c8 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.ebean ebean-parent - 12.11.1-SNAPSHOT + 12.11.1 pom ebean parent @@ -18,7 +18,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.8.0 + ebean-parent-12.11.1 diff --git a/querybean-generator/pom.xml b/querybean-generator/pom.xml index a240e3b8b..238a37f1f 100644 --- a/querybean-generator/pom.xml +++ b/querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1-SNAPSHOT + 12.11.1 querybean generator From f7a0ae8b4a3c28067789ace17bfadfd4f8dab5cb Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 09:23:18 +1200 Subject: [PATCH 097/120] [maven-release-plugin] prepare for next development iteration --- ebean-api/pom.xml | 2 +- ebean-autotune/pom.xml | 6 +++--- ebean-bom/pom.xml | 30 +++++++++++++++--------------- ebean-core-type/pom.xml | 4 ++-- ebean-core/pom.xml | 10 +++++----- ebean-ddl-generator/pom.xml | 6 +++--- ebean-externalmapping-api/pom.xml | 2 +- ebean-externalmapping-xml/pom.xml | 10 +++++----- ebean-postgis/pom.xml | 6 +++--- ebean-querybean/pom.xml | 10 +++++----- ebean-redis/pom.xml | 12 ++++++------ ebean-test/pom.xml | 6 +++--- ebean/pom.xml | 8 ++++---- kotlin-querybean-generator/pom.xml | 8 ++++---- pom.xml | 4 ++-- querybean-generator/pom.xml | 2 +- 16 files changed, 63 insertions(+), 63 deletions(-) diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml index 0e84c71c9..b6adad05d 100644 --- a/ebean-api/pom.xml +++ b/ebean-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean api diff --git a/ebean-autotune/pom.xml b/ebean-autotune/pom.xml index 5bedfbd89..c244053d2 100644 --- a/ebean-autotune/pom.xml +++ b/ebean-autotune/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.11.1 + ebean-parent-12.8.0 ebean autotune @@ -26,7 +26,7 @@ io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT provided diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index 9b651c8a2..cb50c064c 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean bom @@ -81,88 +81,88 @@ io.ebean ebean - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-api - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-core-type - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-ddl-generator - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-externalmapping-api - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-externalmapping-xml - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-autotune - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-querybean - 12.11.1 + 12.11.2-SNAPSHOT io.ebean querybean-generator - 12.11.1 + 12.11.2-SNAPSHOT provided io.ebean kotlin-querybean-generator - 12.11.1 + 12.11.2-SNAPSHOT provided io.ebean ebean-test - 12.11.1 + 12.11.2-SNAPSHOT test io.ebean ebean-postgis - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-redis - 12.11.1 + 12.11.2-SNAPSHOT diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml index e0d543cfc..10c45ea74 100644 --- a/ebean-core-type/pom.xml +++ b/ebean-core-type/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean-core-type @@ -16,7 +16,7 @@ io.ebean ebean-api - 12.11.1 + 12.11.2-SNAPSHOT diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index cface4b9e..bff1574de 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -3,7 +3,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean-core @@ -15,7 +15,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.11.1 + ebean-parent-12.8.0 @@ -78,19 +78,19 @@ io.ebean ebean-api - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-core-type - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-externalmapping-api - 12.11.1 + 12.11.2-SNAPSHOT diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index 2e9b2347b..cbc716413 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean ddl generation @@ -28,14 +28,14 @@ io.ebean ebean-core-type - 12.11.1 + 12.11.2-SNAPSHOT provided io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT provided diff --git a/ebean-externalmapping-api/pom.xml b/ebean-externalmapping-api/pom.xml index 23962062a..c2ea63651 100644 --- a/ebean-externalmapping-api/pom.xml +++ b/ebean-externalmapping-api/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean external mapping api diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml index 821436b6b..b62c33793 100644 --- a/ebean-externalmapping-xml/pom.xml +++ b/ebean-externalmapping-xml/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT @@ -14,7 +14,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.11.1 + ebean-parent-12.8.0 ebean external mapping xml @@ -33,7 +33,7 @@ io.ebean ebean-externalmapping-api - 12.11.1 + 12.11.2-SNAPSHOT @@ -59,14 +59,14 @@ io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT test io.ebean ebean-ddl-generator - 12.11.1 + 12.11.2-SNAPSHOT test diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml index eb6d6fb4c..42b18f4f1 100644 --- a/ebean-postgis/pom.xml +++ b/ebean-postgis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean postgis @@ -23,7 +23,7 @@ io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT provided @@ -74,7 +74,7 @@ io.ebean ebean-test - 12.11.1 + 12.11.2-SNAPSHOT test diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml index 87c0c3cdf..a91cdb4ef 100644 --- a/ebean-querybean/pom.xml +++ b/ebean-querybean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean querybean @@ -17,7 +17,7 @@ io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT provided @@ -57,21 +57,21 @@ io.ebean ebean-ddl-generator - 12.11.1 + 12.11.2-SNAPSHOT test io.ebean querybean-generator - 12.11.1 + 12.11.2-SNAPSHOT test io.ebean ebean-test - 12.11.1 + 12.11.2-SNAPSHOT test diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml index eb22bf8b8..835a05812 100644 --- a/ebean-redis/pom.xml +++ b/ebean-redis/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean-redis @@ -22,35 +22,35 @@ io.ebean ebean-api - 12.11.1 + 12.11.2-SNAPSHOT provided io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT provided io.ebean ebean-querybean - 12.11.1 + 12.11.2-SNAPSHOT test io.ebean querybean-generator - 12.11.1 + 12.11.2-SNAPSHOT test io.ebean ebean-test - 12.11.1 + 12.11.2-SNAPSHOT test diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 1d6ee0b9b..894f7f1b9 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean test @@ -29,14 +29,14 @@ io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT provided io.ebean ebean-ddl-generator - 12.11.1 + 12.11.2-SNAPSHOT diff --git a/ebean/pom.xml b/ebean/pom.xml index 892b73af6..b17e93449 100644 --- a/ebean/pom.xml +++ b/ebean/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT ebean composite @@ -22,20 +22,20 @@ io.ebean ebean-api - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT io.ebean ebean-querybean - 12.11.1 + 12.11.2-SNAPSHOT diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml index 304a5e3e0..7f76d5e09 100644 --- a/kotlin-querybean-generator/pom.xml +++ b/kotlin-querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT kotlin querybean generator @@ -29,7 +29,7 @@ io.ebean ebean-querybean - 12.11.1 + 12.11.2-SNAPSHOT test @@ -43,7 +43,7 @@ io.ebean ebean-core - 12.11.1 + 12.11.2-SNAPSHOT test @@ -64,7 +64,7 @@ io.ebean ebean-ddl-generator - 12.11.1 + 12.11.2-SNAPSHOT test diff --git a/pom.xml b/pom.xml index 8374733c8..bec194354 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ io.ebean ebean-parent - 12.11.1 + 12.11.2-SNAPSHOT pom ebean parent @@ -18,7 +18,7 @@ scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.11.1 + ebean-parent-12.8.0 diff --git a/querybean-generator/pom.xml b/querybean-generator/pom.xml index 238a37f1f..1cf09f8be 100644 --- a/querybean-generator/pom.xml +++ b/querybean-generator/pom.xml @@ -4,7 +4,7 @@ ebean-parent io.ebean - 12.11.1 + 12.11.2-SNAPSHOT querybean generator From f3ec4a78c9d05494c8a035efc8967144090416ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20P=C3=B6hler=20=28JPo=29?= Date: Mon, 29 Mar 2021 13:23:56 +0200 Subject: [PATCH 098/120] FIX: setting json values to null was throwing a NPE when persisting --- .../server/type/ScalarTypeJsonList.java | 3 -- .../server/type/ScalarTypeJsonSet.java | 3 -- .../org/tests/json/TestJsonNullValues.java | 42 +++++++++++++++++++ 3 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 ebean-core/src/test/java/org/tests/json/TestJsonNullValues.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java index 699c7ad0f..d3c700443 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java @@ -122,9 +122,6 @@ class ScalarTypeJsonList { @Override public final String formatValue(List value) { - if (value.isEmpty()) { - return "[]"; - } try { return EJson.write(value); } catch (IOException e) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java index 86a39443e..50cc7f0b3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonSet.java @@ -122,9 +122,6 @@ final class ScalarTypeJsonSet { @Override public final String formatValue(Set value) { - if (value.isEmpty()) { - return "[]"; - } try { return EJson.write(value); } catch (IOException e) { diff --git a/ebean-core/src/test/java/org/tests/json/TestJsonNullValues.java b/ebean-core/src/test/java/org/tests/json/TestJsonNullValues.java new file mode 100644 index 000000000..533116fd1 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/json/TestJsonNullValues.java @@ -0,0 +1,42 @@ +package org.tests.json; + +import io.ebean.BaseTestCase; +import io.ebean.DB; +import org.junit.Test; +import org.tests.model.json.EBasicOldValue; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestJsonNullValues extends BaseTestCase { + + @Test + public void testSetToNull() { + EBasicOldValue bean = new EBasicOldValue(); + DB.save(bean); + bean = DB.find(EBasicOldValue.class, bean.getId()); + + bean.setStringList(null); + bean.setStringSet(null); + bean.setObjectMap(null); + bean.setLongList(null); + bean.setLongSet(null); + bean.setLongMap(null); + bean.setIntList(null); + bean.setIntSet(null); + bean.setIntMap(null); + + DB.save(bean); + bean = DB.find(EBasicOldValue.class, bean.getId()); + + assertThat(bean.getStringList()).isEmpty(); + assertThat(bean.getStringSet()).isEmpty(); + assertThat(bean.getObjectMap()).isEmpty(); + assertThat(bean.getLongList()).isEmpty(); + assertThat(bean.getLongSet()).isEmpty(); + assertThat(bean.getLongMap()).isEmpty(); + assertThat(bean.getIntList()).isEmpty(); + assertThat(bean.getIntSet()).isEmpty(); + assertThat(bean.getIntMap()).isEmpty(); + } + +} From 14262d4c2553a69cc6ff20388f7994f9494b06ff Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 22:19:15 +1200 Subject: [PATCH 099/120] #2317 - Incorrect SQL generated for @IdClass with fetch() on ToMany path --- .../java/org/tests/model/bridge/BDManyId.java | 32 ++++++++++ .../org/tests/model/bridge/BSiteUserD.java | 18 ++++-- .../tests/model/bridge/BSiteUserDMany.java | 64 +++++++++++++++++++ .../tests/model/bridge/TestIdClassScalar.java | 18 ++++++ 4 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 ebean-core/src/test/java/org/tests/model/bridge/BDManyId.java create mode 100644 ebean-core/src/test/java/org/tests/model/bridge/BSiteUserDMany.java diff --git a/ebean-core/src/test/java/org/tests/model/bridge/BDManyId.java b/ebean-core/src/test/java/org/tests/model/bridge/BDManyId.java new file mode 100644 index 000000000..32e5e3af8 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/bridge/BDManyId.java @@ -0,0 +1,32 @@ +package org.tests.model.bridge; + +import javax.persistence.Embeddable; +import java.util.Objects; +import java.util.UUID; + +@Embeddable +public class BDManyId { + + private final UUID siteId; + private final UUID userId; + private final String name; + + public BDManyId(UUID siteId, UUID userId, String name) { + this.siteId = siteId; + this.userId = userId; + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BDManyId bdManyId = (BDManyId) o; + return siteId.equals(bdManyId.siteId) && userId.equals(bdManyId.userId) && name.equals(bdManyId.name); + } + + @Override + public int hashCode() { + return Objects.hash(siteId, userId, name); + } +} diff --git a/ebean-core/src/test/java/org/tests/model/bridge/BSiteUserD.java b/ebean-core/src/test/java/org/tests/model/bridge/BSiteUserD.java index 4ff4513f4..220990cad 100644 --- a/ebean-core/src/test/java/org/tests/model/bridge/BSiteUserD.java +++ b/ebean-core/src/test/java/org/tests/model/bridge/BSiteUserD.java @@ -1,9 +1,7 @@ package org.tests.model.bridge; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; -import javax.persistence.Version; +import javax.persistence.*; +import java.util.List; import java.util.UUID; @Entity @@ -18,6 +16,10 @@ public class BSiteUserD { private BAccessLevel accessLevel; + @OneToMany(cascade = CascadeType.PERSIST) + @JoinColumns({@JoinColumn(name="site_id", referencedColumnName = "site_id"), @JoinColumn(name="user_id", referencedColumnName = "user_id")}) + private List children; + @Version private long version; @@ -58,4 +60,12 @@ public class BSiteUserD { public void setVersion(long version) { this.version = version; } + + public List children() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } } diff --git a/ebean-core/src/test/java/org/tests/model/bridge/BSiteUserDMany.java b/ebean-core/src/test/java/org/tests/model/bridge/BSiteUserDMany.java new file mode 100644 index 000000000..4d7a84f95 --- /dev/null +++ b/ebean-core/src/test/java/org/tests/model/bridge/BSiteUserDMany.java @@ -0,0 +1,64 @@ +package org.tests.model.bridge; + +import javax.persistence.*; +import java.util.UUID; + +@Entity +@IdClass(BDManyId.class) +public class BSiteUserDMany { + + @Id + private UUID siteId; + @Id + private UUID userId; + @Id + String name; + + String many; + + @Version + long version; + + public UUID siteId() { + return siteId; + } + + public BSiteUserDMany siteId(UUID siteId) { + this.siteId = siteId; + return this; + } + + public UUID userId() { + return userId; + } + + public BSiteUserDMany userId(UUID userId) { + this.userId = userId; + return this; + } + + public String name() { + return name; + } + + public BSiteUserDMany name(String name) { + this.name = name; + return this; + } + + public long version() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + public String many() { + return many; + } + + public void setMany(String many) { + this.many = many; + } +} diff --git a/ebean-core/src/test/java/org/tests/model/bridge/TestIdClassScalar.java b/ebean-core/src/test/java/org/tests/model/bridge/TestIdClassScalar.java index a06c7e173..f378dbd29 100644 --- a/ebean-core/src/test/java/org/tests/model/bridge/TestIdClassScalar.java +++ b/ebean-core/src/test/java/org/tests/model/bridge/TestIdClassScalar.java @@ -41,6 +41,24 @@ public class TestIdClassScalar extends BaseTestCase { } + @Test + public void fetchMany() { + UUID siteId = UUID.randomUUID(); + UUID userId = UUID.randomUUID(); + + BSiteUserD access = new BSiteUserD(BAccessLevel.ONE, siteId, userId); + DB.save(access); + + final List found = DB.find(BSiteUserD.class) + .fetch("children") + .where().eq("siteId", siteId) + .findList(); + + assertThat(found).hasSize(1); + + DB.delete(BSiteUserD.class, new BEmbId(siteId, userId)); + } + @Test public void insertBatch() { UUID siteId = UUID.randomUUID(); From 12220d43222463e3745a03cca7ff92435b12518f Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 22:21:49 +1200 Subject: [PATCH 100/120] #2317 - Incorrect SQL generated for @IdClass with fetch() on ToMany path --- .../server/deploy/id/IdBinderEmbedded.java | 66 +++++++++---------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderEmbedded.java index cf2085fa6..2edc359fc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderEmbedded.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderEmbedded.java @@ -26,18 +26,16 @@ import java.util.Map; public final class IdBinderEmbedded implements IdBinder { private final BeanPropertyAssocOne embIdProperty; - private final boolean idInExpandedForm; - + private final boolean idClass; private BeanProperty[] props; - private BeanDescriptor idDesc; - private String idInValueSql; public IdBinderEmbedded(boolean idInExpandedForm, BeanPropertyAssocOne embIdProperty) { this.idInExpandedForm = idInExpandedForm; this.embIdProperty = embIdProperty; + this.idClass = "_idClass".equals(embIdProperty.getName()); } @Override @@ -59,10 +57,7 @@ public final class IdBinderEmbedded implements IdBinder { if (i > 0) { sb.append(" and "); } - sb.append(idDesc.getBaseTableAlias()); - sb.append("."); - sb.append(props[i].getDbColumn()); - sb.append("=?"); + sb.append(idDesc.getBaseTableAlias()).append(".").append(props[i].getDbColumn()).append("=?"); } sb.append(")"); return sb.toString(); @@ -95,7 +90,9 @@ public final class IdBinderEmbedded implements IdBinder { if (pathPrefix != null) { sb.append(pathPrefix).append("."); } - sb.append(embIdProperty.getName()).append("."); + if (!idClass) { + sb.append(embIdProperty.getName()).append("."); + } sb.append(props[i].getName()); if (!ascending) { sb.append(" desc"); @@ -115,7 +112,9 @@ public final class IdBinderEmbedded implements IdBinder { @Override public void buildRawSqlSelectChain(String prefix, List selectChain) { - prefix = SplitName.add(prefix, embIdProperty.getName()); + if (!idClass) { + prefix = SplitName.add(prefix, embIdProperty.getName()); + } for (BeanProperty prop : props) { prop.buildRawSqlSelectChain(prefix, selectChain); } @@ -141,10 +140,11 @@ public final class IdBinderEmbedded implements IdBinder { StringBuilder sb = new StringBuilder(); for (int i = 0; i < props.length; i++) { if (i > 0) { - sb.append(","); + sb.append(", "); + } + if (!idClass) { + sb.append(embIdProperty.getName()).append("."); } - sb.append(embIdProperty.getName()); - sb.append("."); sb.append(props[i].getName()); } return sb.toString(); @@ -173,8 +173,7 @@ public final class IdBinderEmbedded implements IdBinder { if (i > 0) { sb.append(" and "); } - sb.append(props[i].getDbColumn()); - sb.append("=?"); + sb.append(props[i].getDbColumn()).append("=?"); } sb.append(")"); } @@ -200,7 +199,7 @@ public final class IdBinderEmbedded implements IdBinder { if (idInExpandedForm) { sb.append(" or "); } else { - sb.append(","); + sb.append(", "); } } sb.append(idInValueSql); @@ -212,11 +211,11 @@ public final class IdBinderEmbedded implements IdBinder { @Override public Object[] getIdValues(EntityBean bean) { Object val = embIdProperty.getValue(bean); - Object[] bindvalues = new Object[props.length]; + Object[] bindValues = new Object[props.length]; for (int i = 0; i < props.length; i++) { - bindvalues[i] = props[i].getValue((EntityBean) val); + bindValues[i] = props[i].getValue((EntityBean) val); } - return bindvalues; + return bindValues; } @Override @@ -354,11 +353,10 @@ public final class IdBinderEmbedded implements IdBinder { sb.append("("); for (int i = 0; i < props.length; i++) { if (i > 0) { - sb.append(","); + sb.append(", "); } if (prefix != null) { - sb.append(prefix); - sb.append("."); + sb.append(prefix).append("."); } sb.append(props[i].getName()); } @@ -374,13 +372,12 @@ public final class IdBinderEmbedded implements IdBinder { sb.append(" and "); } if (prefix != null) { - sb.append(prefix); - sb.append("."); + sb.append(prefix).append("."); } - sb.append(embIdProperty.getName()); - sb.append("."); - sb.append(props[i].getName()); - sb.append(operator); + if (!idClass) { + sb.append(embIdProperty.getName()).append("."); + } + sb.append(props[i].getName()).append(operator); } return sb.toString(); } @@ -393,11 +390,9 @@ public final class IdBinderEmbedded implements IdBinder { sb.append(" and "); } if (baseTableAlias != null) { - sb.append(baseTableAlias); - sb.append("."); + sb.append(baseTableAlias).append("."); } - sb.append(props[i].getDbColumn()); - sb.append(" = ? "); + sb.append(props[i].getDbColumn()).append("=?"); } return sb.toString(); } @@ -414,8 +409,7 @@ public final class IdBinderEmbedded implements IdBinder { sb.append(","); } if (baseTableAlias != null) { - sb.append(baseTableAlias); - sb.append("."); + sb.append(baseTableAlias).append("."); } sb.append(props[i].getDbColumn()); } @@ -427,9 +421,9 @@ public final class IdBinderEmbedded implements IdBinder { public Object convertId(Object idValue) { if (idValue instanceof String) { final EntityBean embId = idDesc.createEntityBean(); - final String[] rawVals = ((String)idValue).split("\\|"); + final String[] rawValues = ((String)idValue).split("\\|"); for (int i = 0; i < props.length; i++) { - props[i].setValue(embId, props[i].parse(rawVals[i])); + props[i].setValue(embId, props[i].parse(rawValues[i])); } return embId; } From 4163b4dc251139b43b2d65044161bea5d72acc6a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 22:23:58 +1200 Subject: [PATCH 101/120] #2317 - Plus test changes due to tidy whitespace on sql generation --- .../test/java/org/tests/model/bridge/TestIdClassScalar.java | 4 ++-- .../java/org/tests/model/history/TestHistoryEmbeddedId.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ebean-core/src/test/java/org/tests/model/bridge/TestIdClassScalar.java b/ebean-core/src/test/java/org/tests/model/bridge/TestIdClassScalar.java index f378dbd29..2e00493fe 100644 --- a/ebean-core/src/test/java/org/tests/model/bridge/TestIdClassScalar.java +++ b/ebean-core/src/test/java/org/tests/model/bridge/TestIdClassScalar.java @@ -132,7 +132,7 @@ public class TestIdClassScalar extends BaseTestCase { sql = LoggedSqlCollector.stop(); assertThat(sql).hasSize(2); - assertSql(sql.get(0)).contains("select t0.site_id, t0.user_id, t0.site_id, t0.user_id, t0.access_level, t0.version from bsite_user_d t0 where t0.site_id = ? and t0.user_id = ?"); + assertSql(sql.get(0)).contains("select t0.site_id, t0.user_id, t0.site_id, t0.user_id, t0.access_level, t0.version from bsite_user_d t0 where t0.site_id=? and t0.user_id=?"); assertSql(sql.get(1)).contains("update bsite_user_d set access_level=?, version=? where site_id=? and user_id=? and version=?"); } @@ -178,7 +178,7 @@ public class TestIdClassScalar extends BaseTestCase { sql = LoggedSqlCollector.stop(); assertThat(sql).hasSize(2); - assertSql(sql.get(0)).contains("select t0.site_id, t0.user_id, t0.access_level, t0.site_id, t0.user_id from bsite_user_e t0 where t0.site_id = ? and t0.user_id = ?"); + assertSql(sql.get(0)).contains("select t0.site_id, t0.user_id, t0.access_level, t0.site_id, t0.user_id from bsite_user_e t0 where t0.site_id=? and t0.user_id=?"); assertSql(sql.get(1)).contains("update bsite_user_e set access_level=? where site_id=? and user_id=?"); } diff --git a/ebean-core/src/test/java/org/tests/model/history/TestHistoryEmbeddedId.java b/ebean-core/src/test/java/org/tests/model/history/TestHistoryEmbeddedId.java index 0bd8ddef3..ffe82ac75 100644 --- a/ebean-core/src/test/java/org/tests/model/history/TestHistoryEmbeddedId.java +++ b/ebean-core/src/test/java/org/tests/model/history/TestHistoryEmbeddedId.java @@ -48,7 +48,7 @@ public class TestHistoryEmbeddedId extends BaseTestCase { assertThat(namePair.getOldValue()).isEqualTo("ten"); assertThat(sql).hasSize(1); - assertThat(sql.get(0)).contains("from hembi_bean_with_history t0 where t0.part = ? and t0.brand = ?"); + assertThat(sql.get(0)).contains("from hembi_bean_with_history t0 where t0.part=? and t0.brand=?"); if (isH2()) { assertThat(sql.get(0)).contains("order by t0.sys_period_start desc"); } else if (isPostgres()) { From f33e54d8bac2465791e7ccaa91ad736bc09bb8e7 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 22:53:38 +1200 Subject: [PATCH 102/120] #2318 - Refactor internals - final classes in id and generated property packages --- .../deploy/generatedproperty/CounterFactory.java | 7 ++----- .../deploy/generatedproperty/GeneratedCounter.java | 2 +- .../generatedproperty/GeneratedCounterInteger.java | 6 +----- .../generatedproperty/GeneratedCounterLong.java | 6 +----- .../generatedproperty/GeneratedInsertDate.java | 2 +- .../generatedproperty/GeneratedInsertJavaTime.java | 12 ++++++------ .../generatedproperty/GeneratedInsertJodaTime.java | 8 ++++---- .../generatedproperty/GeneratedInsertLong.java | 2 +- .../generatedproperty/GeneratedInsertTimestamp.java | 2 +- .../generatedproperty/GeneratedPropertyFactory.java | 10 +--------- .../generatedproperty/GeneratedUpdateDate.java | 2 +- .../generatedproperty/GeneratedUpdateJavaTime.java | 12 ++++++------ .../generatedproperty/GeneratedUpdateJodaTime.java | 8 ++++---- .../generatedproperty/GeneratedUpdateLong.java | 2 +- .../generatedproperty/GeneratedUpdateTimestamp.java | 2 +- .../generatedproperty/GeneratedWhoCreated.java | 2 +- .../generatedproperty/GeneratedWhoModified.java | 2 +- .../generatedproperty/InsertTimestampFactory.java | 2 +- .../deploy/generatedproperty/JavaTimeUtils.java | 2 +- .../generatedproperty/UpdateTimestampFactory.java | 2 +- .../generatedproperty/UuidGeneratedProperty.java | 2 +- .../server/deploy/id/IdBinderFactory.java | 3 +-- .../server/deploy/id/IdBinderSimple.java | 4 ---- .../server/deploy/id/ImportedIdEmbedded.java | 4 +--- .../server/deploy/id/ImportedIdSimple.java | 12 ------------ 25 files changed, 40 insertions(+), 78 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/CounterFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/CounterFactory.java index 1bfd2542e..999deb121 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/CounterFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/CounterFactory.java @@ -13,14 +13,13 @@ import java.sql.Types; * Aka, Integer, Long, Short etc. *

*/ -class CounterFactory { +final class CounterFactory { private final GeneratedCounterInteger integerCounter = new GeneratedCounterInteger(); private final GeneratedCounterLong longCounter = new GeneratedCounterLong(); - public void setCounter(DeployBeanProperty property) { - + void setCounter(DeployBeanProperty property) { property.setGeneratedProperty(createCounter(property)); } @@ -28,7 +27,6 @@ class CounterFactory { * Create the GeneratedProperty based on the property type. */ private GeneratedProperty createCounter(DeployBeanProperty property) { - Class propType = property.getPropertyType(); if (propType.equals(Integer.class) || propType.equals(int.class)) { return integerCounter; @@ -36,7 +34,6 @@ class CounterFactory { if (propType.equals(Long.class) || propType.equals(long.class)) { return longCounter; } - int type = getType(propType); return new GeneratedCounter(type); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounter.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounter.java index 319e6e40a..38f0085fb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounter.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounter.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * A general number counter for various number types. */ -public class GeneratedCounter implements GeneratedProperty { +final class GeneratedCounter implements GeneratedProperty { private final int numberType; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounterInteger.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounterInteger.java index 88cd3a866..4031465e8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounterInteger.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounterInteger.java @@ -6,11 +6,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Used to create a counter version column for Integer. */ -public class GeneratedCounterInteger implements GeneratedProperty { - - public GeneratedCounterInteger() { - - } +final class GeneratedCounterInteger implements GeneratedProperty { /** * Always returns a 1. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounterLong.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounterLong.java index 310242465..5282bec11 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounterLong.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedCounterLong.java @@ -6,11 +6,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Used to create a counter version column for Long. */ -public class GeneratedCounterLong implements GeneratedProperty { - - public GeneratedCounterLong() { - - } +final class GeneratedCounterLong implements GeneratedProperty { /** * Always returns a 1. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertDate.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertDate.java index 2bb206e3d..57ff0c9bd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertDate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertDate.java @@ -8,7 +8,7 @@ import java.util.Date; /** * Used to generate a (java.util.Date) timestamp when a bean is inserted. */ -public class GeneratedInsertDate implements GeneratedProperty, GeneratedWhenCreated { +final class GeneratedInsertDate implements GeneratedProperty, GeneratedWhenCreated { /** * Return the current time as a Timestamp. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertJavaTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertJavaTime.java index 3b95b4e0d..f71aaccfd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertJavaTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertJavaTime.java @@ -6,9 +6,9 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Support java.time types as GeneratedProperty. */ -public class GeneratedInsertJavaTime { +final class GeneratedInsertJavaTime { - public static abstract class Base implements GeneratedProperty, GeneratedWhenCreated { + static abstract class Base implements GeneratedProperty, GeneratedWhenCreated { @Override public boolean includeInUpdate() { @@ -39,7 +39,7 @@ public class GeneratedInsertJavaTime { /** * Instant support. */ - public static class InstantDT extends Base { + static final class InstantDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { @@ -50,7 +50,7 @@ public class GeneratedInsertJavaTime { /** * LocalDateTime support. */ - public static class LocalDT extends Base { + static final class LocalDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { @@ -61,7 +61,7 @@ public class GeneratedInsertJavaTime { /** * OffsetDateTime support. */ - public static class OffsetDT extends Base { + static final class OffsetDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { @@ -73,7 +73,7 @@ public class GeneratedInsertJavaTime { /** * ZonedDateTime support. */ - public static class ZonedDT extends Base { + static final class ZonedDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertJodaTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertJodaTime.java index f346be035..5a4c11550 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertJodaTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertJodaTime.java @@ -8,9 +8,9 @@ import org.joda.time.LocalDateTime; /** * Support joda time types as GeneratedProperty. */ -public class GeneratedInsertJodaTime { +final class GeneratedInsertJodaTime { - public static abstract class Base implements GeneratedProperty, GeneratedWhenCreated { + static abstract class Base implements GeneratedProperty, GeneratedWhenCreated { @Override public boolean includeInUpdate() { @@ -41,7 +41,7 @@ public class GeneratedInsertJodaTime { /** * LocalDateTime support. */ - public static class LocalDT extends Base { + static final class LocalDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { @@ -52,7 +52,7 @@ public class GeneratedInsertJodaTime { /** * DateTime support. */ - public static class DateTimeDT extends Base { + static final class DateTimeDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertLong.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertLong.java index f56f97490..5e3e0d2f1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertLong.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertLong.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Used to generate a (Long) timestamp when a bean is inserted. */ -public class GeneratedInsertLong implements GeneratedProperty { +final class GeneratedInsertLong implements GeneratedProperty { /** * Return the current time as a Timestamp. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertTimestamp.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertTimestamp.java index abc7f963c..028f71a10 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertTimestamp.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedInsertTimestamp.java @@ -8,7 +8,7 @@ import java.sql.Timestamp; /** * Used to generate a timestamp when a bean is inserted. */ -public class GeneratedInsertTimestamp implements GeneratedProperty, GeneratedWhenCreated { +final class GeneratedInsertTimestamp implements GeneratedProperty, GeneratedWhenCreated { /** * Return the current time as a Timestamp. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java index b395732b0..e876fb379 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java @@ -17,24 +17,16 @@ import java.util.Map; /** * Default implementation of GeneratedPropertyFactory. */ -public class GeneratedPropertyFactory { +public final class GeneratedPropertyFactory { private final CounterFactory counterFactory = new CounterFactory(); - private final InsertTimestampFactory insertFactory; - private final UpdateTimestampFactory updateFactory; - private final HashSet numberTypes = new HashSet<>(); - private final UuidGeneratedProperty generatedUuid = new UuidGeneratedProperty(); - private final GeneratedWhoModified generatedWhoModified; - private final GeneratedWhoCreated generatedWhoCreated; - private final ClassLoadConfig classLoadConfig; - private final Map idGeneratorMap = new HashMap<>(); public GeneratedPropertyFactory(boolean offlineMode, DatabaseConfig config, List idGenerators) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateDate.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateDate.java index f9cd94659..f8ec8effe 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateDate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateDate.java @@ -9,7 +9,7 @@ import java.util.Date; * Generate a (java.util.Date) Timestamp whenever the bean is inserted or * updated. */ -public class GeneratedUpdateDate implements GeneratedProperty { +final class GeneratedUpdateDate implements GeneratedProperty { /** * Return now as a Timestamp. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateJavaTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateJavaTime.java index 8592425df..6abbf2c6b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateJavaTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateJavaTime.java @@ -6,9 +6,9 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Support java.time DateTime types as GeneratedProperty. */ -public class GeneratedUpdateJavaTime { +final class GeneratedUpdateJavaTime { - public static abstract class Base implements GeneratedProperty, GeneratedWhenModified { + static abstract class Base implements GeneratedProperty, GeneratedWhenModified { @Override public boolean includeInUpdate() { @@ -34,7 +34,7 @@ public class GeneratedUpdateJavaTime { /** * Instant support. */ - public static class InstantDT extends Base { + static final class InstantDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { @@ -50,7 +50,7 @@ public class GeneratedUpdateJavaTime { /** * LocalDateTime support. */ - public static class LocalDT extends Base { + static final class LocalDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { @@ -66,7 +66,7 @@ public class GeneratedUpdateJavaTime { /** * OffsetDateTime support. */ - public static class OffsetDT extends Base { + static final class OffsetDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { @@ -82,7 +82,7 @@ public class GeneratedUpdateJavaTime { /** * ZonedDateTime support. */ - public static class ZonedDT extends Base { + static final class ZonedDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateJodaTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateJodaTime.java index de4cc1878..ab95ce24a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateJodaTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateJodaTime.java @@ -8,9 +8,9 @@ import org.joda.time.LocalDateTime; /** * Support java.time DateTime types as GeneratedProperty. */ -public class GeneratedUpdateJodaTime { +final class GeneratedUpdateJodaTime { - public static abstract class Base implements GeneratedProperty, GeneratedWhenModified { + static abstract class Base implements GeneratedProperty, GeneratedWhenModified { @Override public boolean includeInUpdate() { @@ -36,7 +36,7 @@ public class GeneratedUpdateJodaTime { /** * LocalDateTime support. */ - public static class LocalDT extends Base { + static final class LocalDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { @@ -52,7 +52,7 @@ public class GeneratedUpdateJodaTime { /** * OffsetDateTime support. */ - public static class DateTimeDT extends Base { + static final class DateTimeDT extends Base { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateLong.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateLong.java index 2d4c85192..72c2b9079 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateLong.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateLong.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Generate a (Long) Timestamp whenever the bean is inserted or updated. */ -public class GeneratedUpdateLong implements GeneratedProperty { +final class GeneratedUpdateLong implements GeneratedProperty { /** * Return now as a Timestamp. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateTimestamp.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateTimestamp.java index f493401d8..3ee658eb2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateTimestamp.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedUpdateTimestamp.java @@ -8,7 +8,7 @@ import java.sql.Timestamp; /** * Generate a Timestamp whenever the bean is inserted or updated. */ -public class GeneratedUpdateTimestamp implements GeneratedProperty, GeneratedWhenModified { +final class GeneratedUpdateTimestamp implements GeneratedProperty, GeneratedWhenModified { /** * Return now as a Timestamp. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedWhoCreated.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedWhoCreated.java index cdb719014..404f31049 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedWhoCreated.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedWhoCreated.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Used to populate @WhoCreated bean properties. */ -public class GeneratedWhoCreated implements GeneratedProperty { +final class GeneratedWhoCreated implements GeneratedProperty { private final CurrentUserProvider currentUserProvider; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedWhoModified.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedWhoModified.java index e4e68a373..c9aa65537 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedWhoModified.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/GeneratedWhoModified.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; /** * Used to populate @WhoModified bean properties. */ -public class GeneratedWhoModified implements GeneratedProperty { +final class GeneratedWhoModified implements GeneratedProperty { private final CurrentUserProvider currentUserProvider; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactory.java index ee2c88a66..f5083c632 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/InsertTimestampFactory.java @@ -15,7 +15,7 @@ import java.util.Map; /** * Helper for creating Insert timestamp GeneratedProperty objects. */ -class InsertTimestampFactory { +final class InsertTimestampFactory { private final Map, GeneratedProperty> map = new HashMap<>(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/JavaTimeUtils.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/JavaTimeUtils.java index bf3f6db12..cea0a6e86 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/JavaTimeUtils.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/JavaTimeUtils.java @@ -9,7 +9,7 @@ import java.time.ZonedDateTime; /** * Helper methods for Java time conversion. */ -class JavaTimeUtils { +final class JavaTimeUtils { /** * Return the system millis time as a LocalDateTime. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactory.java index d405f2ec7..d08b75cc6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/UpdateTimestampFactory.java @@ -15,7 +15,7 @@ import java.util.Map; /** * Helper for creating Update timestamp GeneratedProperty objects. */ -class UpdateTimestampFactory { +final class UpdateTimestampFactory { private final Map, GeneratedProperty> map = new HashMap<>(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/UuidGeneratedProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/UuidGeneratedProperty.java index 2090fac13..6eff4c21a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/UuidGeneratedProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/generatedproperty/UuidGeneratedProperty.java @@ -5,7 +5,7 @@ import io.ebeaninternal.server.deploy.BeanProperty; import java.util.UUID; -public class UuidGeneratedProperty implements GeneratedProperty { +final class UuidGeneratedProperty implements GeneratedProperty { @Override public Object getInsertValue(BeanProperty prop, EntityBean bean, long now) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderFactory.java index 70f8a1175..b9bf6f6e6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderFactory.java @@ -7,12 +7,11 @@ import io.ebeaninternal.server.persist.platform.MultiValueBind; /** * Creates the appropriate IdConvertSet depending on the type of Id property(s). */ -public class IdBinderFactory { +public final class IdBinderFactory { private static final IdBinderEmpty EMPTY = new IdBinderEmpty(); private final boolean idInExpandedForm; - private final MultiValueBind multiValueBind; public IdBinderFactory(boolean idInExpandedForm, MultiValueBind multiValueBind) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderSimple.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderSimple.java index cb9e6f9aa..6541b3fa5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderSimple.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/IdBinderSimple.java @@ -26,13 +26,9 @@ import java.util.List; public final class IdBinderSimple implements IdBinder { private final BeanProperty idProperty; - private final String bindIdSql; - private final Class expectedType; - private final MultiValueBind multiValueBind; - @SuppressWarnings("rawtypes") private final ScalarType scalarType; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/ImportedIdEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/ImportedIdEmbedded.java index 537575ae8..d0f888582 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/ImportedIdEmbedded.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/ImportedIdEmbedded.java @@ -18,12 +18,10 @@ import java.sql.SQLException; /** * Imported Embedded id. */ -public class ImportedIdEmbedded implements ImportedId { +public final class ImportedIdEmbedded implements ImportedId { private final BeanPropertyAssoc owner; - private final BeanPropertyAssocOne foreignAssocOne; - private final ImportedIdSimple[] imported; public ImportedIdEmbedded(BeanPropertyAssoc owner, BeanPropertyAssocOne foreignAssocOne, ImportedIdSimple[] imported) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/ImportedIdSimple.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/ImportedIdSimple.java index ea9844ec1..83f615994 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/ImportedIdSimple.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/id/ImportedIdSimple.java @@ -36,23 +36,11 @@ public final class ImportedIdSimple implements ImportedId, Comparable owner; - final String localDbColumn; - private final String localSqlFormula; - final BeanProperty foreignProperty; - private final int position; - - /** - * If true include in insert. - */ private final boolean insertable; - - /** - * If true include in update. - */ private final boolean updateable; public ImportedIdSimple(BeanPropertyAssoc owner, String localDbColumn, String localSqlFormula, BeanProperty foreignProperty, int position, From 0413d89a9e8cf7a86b0acedd00578d860b8f40ce Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 23:19:02 +1200 Subject: [PATCH 103/120] #2318 - Refactor internals - final classes in expression packages --- .../server/expression/AbstractExpression.java | 4 +--- .../expression/AbstractTextExpression.java | 2 +- .../expression/AbstractValueExpression.java | 2 +- .../server/expression/AllEqualsExpression.java | 17 ++--------------- .../expression/ArrayContainsExpression.java | 4 +--- .../expression/ArrayIsEmptyExpression.java | 2 +- .../server/expression/BetweenExpression.java | 3 +-- .../expression/BetweenPropertyExpression.java | 6 ++---- .../server/expression/BitwiseExpression.java | 9 +++------ .../CaseInsensitiveEqualExpression.java | 4 +--- .../expression/DefaultExampleExpression.java | 4 ++-- .../expression/DefaultExpressionList.java | 5 ----- .../expression/DefaultExpressionRequest.java | 11 +---------- .../expression/ExistsQueryExpression.java | 16 +++++----------- .../server/expression/FilterExprPath.java | 2 +- .../server/expression/FilterExpressionList.java | 4 +--- .../server/expression/IdExpression.java | 2 +- .../server/expression/IdInExpression.java | 3 +-- .../server/expression/InExpression.java | 2 +- .../server/expression/InPairsExpression.java | 8 +------- .../server/expression/InQueryExpression.java | 5 +---- .../server/expression/InRangeExpression.java | 3 +-- .../server/expression/IsEmptyExpression.java | 4 +--- .../server/expression/JsonPathExpression.java | 10 +++++----- .../server/expression/JunctionExpression.java | 7 +++---- .../server/expression/LikeExpression.java | 6 +----- .../server/expression/LogicExpression.java | 6 ++---- .../server/expression/NamedParamHelp.java | 2 +- .../expression/NativeILikeExpression.java | 2 +- .../expression/NestedPathWrapperExpression.java | 7 +++---- .../server/expression/NoopExpression.java | 4 ++-- .../server/expression/NullExpression.java | 5 +---- .../server/expression/PrepareDocNested.java | 2 +- .../server/expression/RawExpression.java | 3 +-- .../server/expression/RawExpressionBuilder.java | 2 +- .../ebeaninternal/server/expression/Same.java | 11 +++++------ .../server/expression/SimpleExpression.java | 2 +- .../expression/TextCommonTermsExpression.java | 3 +-- .../server/expression/TextMatchExpression.java | 5 ++--- .../expression/TextMultiMatchExpression.java | 5 ++--- .../expression/TextQueryStringExpression.java | 5 ++--- .../server/expression/TextSimpleExpression.java | 5 ++--- .../expression/platform/BaseDbExpression.java | 2 -- .../expression/platform/BasicDbExpression.java | 2 +- .../platform/DbExpressionHandlerFactory.java | 3 +-- .../expression/platform/H2DbExpression.java | 2 +- .../expression/platform/HanaDbExpression.java | 2 +- .../expression/platform/MariaDbExpression.java | 2 +- .../expression/platform/MySqlDbExpression.java | 2 +- .../expression/platform/OracleDbExpression.java | 3 +-- .../expression/platform/PostgresCast.java | 7 +++---- .../platform/PostgresDbExpression.java | 5 +---- .../platform/SqlServerDbExpression.java | 2 +- 53 files changed, 80 insertions(+), 166 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractExpression.java index c3090e38f..f3c9d5aae 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractExpression.java @@ -14,7 +14,7 @@ import io.ebeaninternal.api.NaturalKeyQueryData; /** * Base class for simple expressions. */ -public abstract class AbstractExpression implements SpiExpression { +abstract class AbstractExpression implements SpiExpression { protected String propName; @@ -66,7 +66,6 @@ public abstract class AbstractExpression implements SpiExpression { @Override public void containsMany(BeanDescriptor desc, ManyWhereJoins manyWhereJoin) { - propertyContainsMany(propName, desc, manyWhereJoin); } @@ -103,7 +102,6 @@ public abstract class AbstractExpression implements SpiExpression { } protected final ElPropertyValue getElProp(SpiExpressionRequest request) { - return request.getBeanDescriptor().getElGetValue(propName); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java index 363bcb08d..272e557d7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractTextExpression.java @@ -10,7 +10,7 @@ import io.ebeaninternal.api.SpiExpressionRequest; * This means they can not be part of a SQL query nor do they use the built in query plan cache etc. *

*/ -public abstract class AbstractTextExpression extends AbstractExpression { +abstract class AbstractTextExpression extends AbstractExpression { AbstractTextExpression(String propName) { super(propName); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractValueExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractValueExpression.java index 7adb2729b..a758dcd10 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractValueExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AbstractValueExpression.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.expression; /** * Abstract expression that helps with named parameter use. */ -public abstract class AbstractValueExpression extends AbstractExpression { +abstract class AbstractValueExpression extends AbstractExpression { protected final Object bindValue; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java index 56761dcf2..fafb3bc96 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/AllEqualsExpression.java @@ -13,7 +13,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; -class AllEqualsExpression extends NonPrepareExpression { +final class AllEqualsExpression extends NonPrepareExpression { private final Map propMap; @@ -21,7 +21,7 @@ class AllEqualsExpression extends NonPrepareExpression { this.propMap = propMap; } - protected String name(String propName) { + String name(String propName) { return propName; } @@ -56,7 +56,6 @@ class AllEqualsExpression extends NonPrepareExpression { @Override public void addBindValues(SpiExpressionRequest request) { - if (propMap.isEmpty()) { return; } @@ -70,23 +69,17 @@ class AllEqualsExpression extends NonPrepareExpression { @Override public void addSql(SpiExpressionRequest request) { - if (propMap.isEmpty()) { return; } - request.append("("); - int count = 0; for (Map.Entry entry : propMap.entrySet()) { - Object value = entry.getValue(); String propName = entry.getKey(); - if (count > 0) { request.append("and "); } - request.append(name(propName)); if (value == null) { request.append(" is null "); @@ -106,7 +99,6 @@ class AllEqualsExpression extends NonPrepareExpression { */ @Override public void queryPlanHash(StringBuilder builder) { - builder.append("AllEquals["); for (Entry entry : propMap.entrySet()) { Object value = entry.getValue(); @@ -135,20 +127,16 @@ class AllEqualsExpression extends NonPrepareExpression { if (!(other instanceof AllEqualsExpression)) { return false; } - AllEqualsExpression that = (AllEqualsExpression) other; return isSameByValue(that, true); } private boolean isSameByValue(AllEqualsExpression that, boolean byValue) { - if (propMap.size() != that.propMap.size()) { return false; } - Iterator> thisIt = propMap.entrySet().iterator(); Iterator> thatIt = that.propMap.entrySet().iterator(); - while (thisIt.hasNext() && thatIt.hasNext()) { Entry thisNext = thisIt.next(); Entry thatNext = thatIt.next(); @@ -160,7 +148,6 @@ class AllEqualsExpression extends NonPrepareExpression { return false; } } - return true; } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java index 7a9e903f6..34fec6037 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayContainsExpression.java @@ -9,10 +9,9 @@ import java.io.IOException; /** * Contains expression for ARRAY type. */ -public class ArrayContainsExpression extends AbstractExpression { +final class ArrayContainsExpression extends AbstractExpression { private final boolean contains; - private final Object[] values; ArrayContainsExpression(String propName, boolean contains, Object... values) { @@ -26,7 +25,6 @@ public class ArrayContainsExpression extends AbstractExpression { @Override public void writeDocQuery(DocQueryContext context) throws IOException { - if (values.length == 1) { context.writeEqualTo(propName, values[0]); } else { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java index f9cd530c8..2234f9500 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ArrayIsEmptyExpression.java @@ -9,7 +9,7 @@ import java.io.IOException; /** * IsEmpty expression for ARRAY type. */ -public class ArrayIsEmptyExpression extends AbstractExpression { +final class ArrayIsEmptyExpression extends AbstractExpression { private final boolean empty; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java index ed3d58d8b..be113e7a5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenExpression.java @@ -6,12 +6,11 @@ import io.ebeaninternal.api.SpiExpressionRequest; import java.io.IOException; -class BetweenExpression extends AbstractExpression { +final class BetweenExpression extends AbstractExpression { private static final String _BETWEEN = " between ? and ?"; private final Object valueHigh; - private final Object valueLow; BetweenExpression(String propertyName, Object valueLow, Object valueHigh) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java index 55b08380d..74129849d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BetweenPropertyExpression.java @@ -14,7 +14,7 @@ import java.io.IOException; /** * Between expression where a value is between two properties. */ -class BetweenPropertyExpression extends NonPrepareExpression { +final class BetweenPropertyExpression extends NonPrepareExpression { private static final String BETWEEN = " between "; @@ -34,7 +34,7 @@ class BetweenPropertyExpression extends NonPrepareExpression { this.highProperty = path + "." + highProperty; } - protected String name(String propName) { + String name(String propName) { return propName; } @@ -62,12 +62,10 @@ class BetweenPropertyExpression extends NonPrepareExpression { @Override public void containsMany(BeanDescriptor desc, ManyWhereJoins manyWhereJoin) { - ElPropertyDeploy elProp = desc.getElPropertyDeploy(name(lowProperty)); if (elProp != null && elProp.containsMany()) { manyWhereJoin.add(elProp); } - elProp = desc.getElPropertyDeploy(name(highProperty)); if (elProp != null && elProp.containsMany()) { manyWhereJoin.add(elProp); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java index 460af37ec..aa68f2662 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/BitwiseExpression.java @@ -9,14 +9,11 @@ import java.io.IOException; /** * Bitwise expression. */ -class BitwiseExpression extends AbstractExpression { - - protected final BitwiseOp operator; +final class BitwiseExpression extends AbstractExpression { + private final BitwiseOp operator; private final String compare; - - protected final long flags; - + private final long flags; private final long match; BitwiseExpression(String propertyName, BitwiseOp operator, long flags, String compare, long match) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java index 3a6224d9c..a8075090a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/CaseInsensitiveEqualExpression.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.el.ElPropertyValue; import java.io.IOException; -class CaseInsensitiveEqualExpression extends AbstractValueExpression { +final class CaseInsensitiveEqualExpression extends AbstractValueExpression { private final boolean not; @@ -34,7 +34,6 @@ class CaseInsensitiveEqualExpression extends AbstractValueExpression { @Override public void addBindValues(SpiExpressionRequest request) { - ElPropertyValue prop = getElProp(request); if (prop != null && prop.isDbEncrypted()) { // bind the key as well as the value @@ -47,7 +46,6 @@ class CaseInsensitiveEqualExpression extends AbstractValueExpression { @Override public void addSql(SpiExpressionRequest request) { - String pname = propName; ElPropertyValue prop = getElProp(request); if (prop != null && prop.isDbEncrypted()) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java index cd8a59857..ca97b5408 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExampleExpression.java @@ -39,7 +39,7 @@ import java.util.ArrayList; * * } */ -public class DefaultExampleExpression implements SpiExpression, ExampleExpression { +final class DefaultExampleExpression implements SpiExpression, ExampleExpression { /** * The example bean containing the properties. @@ -75,7 +75,7 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio * @param caseInsensitive if true use case insensitive expressions * @param likeType the type of Like wild card used */ - public DefaultExampleExpression(EntityBean entity, boolean caseInsensitive, LikeType likeType) { + DefaultExampleExpression(EntityBean entity, boolean caseInsensitive, LikeType likeType) { this.entity = entity; this.caseInsensitive = caseInsensitive; this.likeType = likeType; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java index ed3f57e14..b9693df6d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionList.java @@ -56,15 +56,10 @@ public class DefaultExpressionList implements SpiExpressionList { private static final String AND = " and "; protected List list; - protected final Query query; - private final ExpressionList parentExprList; - protected final ExpressionFactory expr; - String allDocNestedPath; - /** * Set to true for the "Text" root expression list. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionRequest.java index 557c53996..09ff401af 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/DefaultExpressionRequest.java @@ -13,26 +13,17 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -public class DefaultExpressionRequest implements SpiExpressionRequest { +public final class DefaultExpressionRequest implements SpiExpressionRequest { private final SpiOrmQueryRequest queryRequest; - private final BeanDescriptor beanDescriptor; - private final StringBuilder sql = new StringBuilder(); - private final List bindValues = new ArrayList<>(); - private final DeployParser deployParser; - private final Binder binder; - private final SpiExpressionList expressionList; - private int paramIndex; - private final boolean enableBindLog; - private StringBuilder bindLog; public DefaultExpressionRequest(SpiOrmQueryRequest queryRequest, DeployParser deployParser, Binder binder, SpiExpressionList expressionList) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java index 71ca665fe..438f1a2d5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/ExistsQueryExpression.java @@ -16,15 +16,12 @@ import io.ebeaninternal.server.query.CQuery; import java.io.IOException; import java.util.List; -class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpression { +final class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpression { - protected final boolean not; - - protected final SpiQuery subQuery; - - protected List bindParams; - - protected String sql; + private final boolean not; + private final SpiQuery subQuery; + private List bindParams; + private String sql; ExistsQueryExpression(SpiQuery subQuery, boolean not) { this.subQuery = subQuery; @@ -67,7 +64,6 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress @Override public void prepareExpression(BeanQueryRequest request) { - CQuery subQuery = compileSubQuery(request); this.bindParams = subQuery.getPredicates().getWhereExprBindValues(); this.sql = subQuery.getGeneratedSql().replace('\n', ' '); @@ -99,7 +95,6 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress @Override public void addSql(SpiExpressionRequest request) { - if (not) { request.append(" not"); } @@ -110,7 +105,6 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress @Override public void addBindValues(SpiExpressionRequest request) { - for (Object bindParam : bindParams) { request.addBindValue(bindParam); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/FilterExprPath.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/FilterExprPath.java index d7b04de44..5765c7e43 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/FilterExprPath.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/FilterExprPath.java @@ -9,7 +9,7 @@ import java.io.Serializable; * query that includes the filterMany. *

*/ -public class FilterExprPath implements Serializable { +public final class FilterExprPath implements Serializable { private static final long serialVersionUID = -6420905565372842018L; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/FilterExpressionList.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/FilterExpressionList.java index b6b1874a8..0e8d4ba0b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/FilterExpressionList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/FilterExpressionList.java @@ -18,14 +18,12 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -public class FilterExpressionList extends DefaultExpressionList { +public final class FilterExpressionList extends DefaultExpressionList { private static final String notAllowedMessage = "This method is not allowed on a filter"; private final Query rootQuery; - private final FilterExprPath pathPrefix; - private int firstRow; private int maxRows; private String orderByClause; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java index 94cab6de7..c61f884a4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdExpression.java @@ -12,7 +12,7 @@ import java.io.IOException; /** * Slightly redundant as Query.setId() ultimately also does the same job. */ -class IdExpression extends NonPrepareExpression implements SpiExpression { +final class IdExpression extends NonPrepareExpression implements SpiExpression { private final Object value; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java index edf56b443..c1bd76db0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IdInExpression.java @@ -20,10 +20,9 @@ import java.util.Set; /** * In a collection of Id values. */ -public class IdInExpression extends NonPrepareExpression { +public final class IdInExpression extends NonPrepareExpression { private final List idCollection; - private boolean multiValueIdSupported; public IdInExpression(Collection idCollection) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java index 0bc5a4588..1a84d87eb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InExpression.java @@ -16,7 +16,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -class InExpression extends AbstractExpression { +final class InExpression extends AbstractExpression { private final boolean not; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java index e5bd27413..b5533b7ad 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InPairsExpression.java @@ -13,20 +13,14 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -class InPairsExpression extends AbstractExpression { +final class InPairsExpression extends AbstractExpression { private final boolean not; - private final String property0, property1; - private List entries; - private boolean multiValueSupported; - private final String separator; - private final String suffix; - private List concatBindValues; InPairsExpression(Pairs pairs, boolean not) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java index a2d6d787c..e53792550 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InQueryExpression.java @@ -15,14 +15,11 @@ import java.util.List; /** * In expression using a sub query. */ -class InQueryExpression extends AbstractExpression implements UnsupportedDocStoreExpression { +final class InQueryExpression extends AbstractExpression implements UnsupportedDocStoreExpression { private final boolean not; - private final SpiQuery subQuery; - private List bindParams; - private String sql; InQueryExpression(String propertyName, SpiQuery subQuery, boolean not) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java index 04b242ba8..8bcdb12a8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/InRangeExpression.java @@ -6,10 +6,9 @@ import io.ebeaninternal.api.SpiExpressionRequest; import java.io.IOException; -class InRangeExpression extends AbstractExpression { +final class InRangeExpression extends AbstractExpression { private final Object valueHigh; - private final Object valueLow; InRangeExpression(String propertyName, Object valueLow, Object valueHigh) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java index d6b878bfa..fc3be3e34 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/IsEmptyExpression.java @@ -10,12 +10,10 @@ import io.ebean.util.SplitName; import java.io.IOException; -class IsEmptyExpression extends AbstractExpression { +final class IsEmptyExpression extends AbstractExpression { private final boolean empty; - private final String propertyPath; - private String nestedPath; IsEmptyExpression(String propertyName, boolean empty) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java index 1d954dcc1..a6e8f128b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JsonPathExpression.java @@ -16,27 +16,27 @@ import java.util.Objects; * The value passed in is expected to be a valid JSON type so string, number, boolean. *

*/ -class JsonPathExpression extends AbstractExpression { +final class JsonPathExpression extends AbstractExpression { /** * The path in the JSON document in dot notation form. */ - protected final String path; + private final String path; /** * The expression operator. */ - protected final Op operator; + private final Op operator; /** * The bind value used to compare against the document path value. */ - protected final Object value; + private final Object value; /** * For Between this is the upper bind value. */ - protected final Object upperValue; + private final Object upperValue; /** * Construct for Operator (not BETWEEN though). diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java index 5637fba7f..a408b5e74 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/JunctionExpression.java @@ -48,11 +48,10 @@ import java.util.function.Predicate; /** * Junction implementation. */ -class JunctionExpression implements SpiJunction, SpiExpression, ExpressionList { +final class JunctionExpression implements SpiJunction, SpiExpression, ExpressionList { - protected DefaultExpressionList exprList; - - protected Junction.Type type; + DefaultExpressionList exprList; + Junction.Type type; JunctionExpression(Junction.Type type, Query query, ExpressionList parent) { this.type = type; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java index f40501929..bf3871c23 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LikeExpression.java @@ -8,10 +8,9 @@ import io.ebeaninternal.server.el.ElPropertyValue; import java.io.IOException; -class LikeExpression extends AbstractValueExpression { +final class LikeExpression extends AbstractValueExpression { private final boolean caseInsensitive; - private final LikeType type; LikeExpression(String propertyName, Object value, boolean caseInsensitive, LikeType type) { @@ -27,7 +26,6 @@ class LikeExpression extends AbstractValueExpression { @Override public void addBindValues(SpiExpressionRequest request) { - ElPropertyValue prop = getElProp(request); if (prop != null && prop.isDbEncrypted()) { // bind the key as well as the value @@ -40,7 +38,6 @@ class LikeExpression extends AbstractValueExpression { @Override public void addSql(SpiExpressionRequest request) { - String pname = propName; ElPropertyValue prop = getElProp(request); if (prop != null && prop.isDbEncrypted()) { @@ -98,7 +95,6 @@ class LikeExpression extends AbstractValueExpression { return "%" + value + "%"; case EQUAL_TO: return value; - default: throw new RuntimeException("LikeType " + type + " missed?"); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java index a66e2e88a..b0ef74f03 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/LogicExpression.java @@ -21,7 +21,7 @@ abstract class LogicExpression implements SpiExpression { static final String AND = " and "; static final String OR = " or "; - static class And extends LogicExpression { + static final class And extends LogicExpression { And(Expression expOne, Expression expTwo) { super(true, expOne, expTwo); @@ -34,7 +34,7 @@ abstract class LogicExpression implements SpiExpression { } - static class Or extends LogicExpression { + static final class Or extends LogicExpression { Or(Expression expOne, Expression expTwo) { super(false, expOne, expTwo); @@ -47,9 +47,7 @@ abstract class LogicExpression implements SpiExpression { } SpiExpression expOne; - SpiExpression expTwo; - private final boolean conjunction; LogicExpression(boolean conjunction, Expression expOne, Expression expTwo) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NamedParamHelp.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NamedParamHelp.java index 5487cffbf..3a56ec7de 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NamedParamHelp.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NamedParamHelp.java @@ -8,7 +8,7 @@ import java.util.List; /** * Helper for evaluating named parameters. */ -class NamedParamHelp { +final class NamedParamHelp { /** * Return the bind value taking into account named parameters. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java index f64933df5..110442365 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NativeILikeExpression.java @@ -8,7 +8,7 @@ import io.ebeaninternal.server.el.ElPropertyValue; import java.io.IOException; -class NativeILikeExpression extends AbstractExpression { +final class NativeILikeExpression extends AbstractExpression { private final String val; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java index b76bfef4d..0bb63f1ed 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NestedPathWrapperExpression.java @@ -14,11 +14,10 @@ import java.io.IOException; /** * Wraps a single expression with nestedPath for document queries. */ -class NestedPathWrapperExpression implements SpiExpression { +final class NestedPathWrapperExpression implements SpiExpression { - protected final String nestedPath; - - protected final SpiExpression delegate; + final String nestedPath; + final SpiExpression delegate; NestedPathWrapperExpression(String nestedPath, SpiExpression delegate) { this.nestedPath = nestedPath; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java index 6c8d709e7..079f26874 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NoopExpression.java @@ -14,9 +14,9 @@ import java.io.IOException; /** * Effectively an expression that has no effect. */ -class NoopExpression implements SpiExpression { +final class NoopExpression implements SpiExpression { - protected static final NoopExpression INSTANCE = new NoopExpression(); + static final NoopExpression INSTANCE = new NoopExpression(); @Override public void prefixProperty(String path) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java index 2808acce7..4a4a81201 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/NullExpression.java @@ -17,14 +17,11 @@ import java.io.IOException; * Note that for OneToMany/ManyToMany this effectively gets translated into isEmpty()/isNotEmpty(). *

*/ -class NullExpression extends AbstractExpression { +final class NullExpression extends AbstractExpression { private final boolean notNull; - private ElPropertyValue elProperty; - private boolean assocMany; - private String propertyPath; NullExpression(String propertyName, boolean notNull) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/PrepareDocNested.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/PrepareDocNested.java index ebc2d794b..8f1f48d38 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/PrepareDocNested.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/PrepareDocNested.java @@ -13,7 +13,7 @@ import java.util.Map; /** * Prepare nested path expressions for */ -class PrepareDocNested { +final class PrepareDocNested { /** * Prepare the top level expressions for nested path handling. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java index 9e1c3e8dc..53571cad7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpression.java @@ -11,10 +11,9 @@ import io.ebeaninternal.server.persist.MultiValueWrapper; import java.io.IOException; import java.util.Collection; -class RawExpression extends NonPrepareExpression { +final class RawExpression extends NonPrepareExpression { final String sql; - final Object[] values; RawExpression(String sql, Object[] values) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpressionBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpressionBuilder.java index 73a4da911..40aa47271 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpressionBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/RawExpressionBuilder.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -class RawExpressionBuilder { +final class RawExpressionBuilder { private static final String BP_1 = "?1"; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/Same.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/Same.java index 931e3e3e3..104d27969 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/Same.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/Same.java @@ -7,26 +7,26 @@ import java.util.Objects; /** * Utility to help isSame methods. */ -public class Same { +final class Same { /** * Return true if both values are null or both an not null. */ - public static boolean sameByNull(Object v1, Object v2) { + static boolean sameByNull(Object v1, Object v2) { return (v1 == null) == (v2 == null); } /** * Null safe equals check. */ - public static boolean sameByValue(Object v1, Object v2) { + static boolean sameByValue(Object v1, Object v2) { return Objects.equals(v1, v2); } /** * Return true if both collections are the same by value and order is taken into account. */ - public static boolean sameByValue(Collection v1, Collection v2) { + static boolean sameByValue(Collection v1, Collection v2) { if (v1 == null) { return v2 == null; } @@ -46,8 +46,7 @@ public class Same { /** * Null safe check by sameByValue or sameByNull based on byValue. */ - public static boolean sameBy(boolean byValue, Object value, Object value1) { - + static boolean sameBy(boolean byValue, Object value, Object value1) { if (byValue) { return sameByValue(value, value1); } else { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java index bc23b84f2..87b0ed3bf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/SimpleExpression.java @@ -11,7 +11,7 @@ import io.ebeaninternal.api.NaturalKeyQueryData; import java.io.IOException; import java.util.Arrays; -public class SimpleExpression extends AbstractValueExpression { +public final class SimpleExpression extends AbstractValueExpression { private final Op type; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextCommonTermsExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextCommonTermsExpression.java index 8cc5fb5bb..3f289edb5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextCommonTermsExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextCommonTermsExpression.java @@ -7,10 +7,9 @@ import java.io.IOException; /** * Full text common terms expression. */ -class TextCommonTermsExpression extends AbstractTextExpression { +final class TextCommonTermsExpression extends AbstractTextExpression { private final String search; - private final TextCommonTerms options; public TextCommonTermsExpression(String search, TextCommonTerms options) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextMatchExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextMatchExpression.java index d36f491b7..f7cb06e6a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextMatchExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextMatchExpression.java @@ -7,13 +7,12 @@ import java.io.IOException; /** * Full text MATCH expression. */ -public class TextMatchExpression extends AbstractTextExpression { +final class TextMatchExpression extends AbstractTextExpression { private final String search; - private final Match options; - public TextMatchExpression(String propertyName, String search, Match options) { + TextMatchExpression(String propertyName, String search, Match options) { super(propertyName); this.search = search; this.options = options; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextMultiMatchExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextMultiMatchExpression.java index e51538e9f..f9fe1e909 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextMultiMatchExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextMultiMatchExpression.java @@ -7,13 +7,12 @@ import java.io.IOException; /** * Full text Multi-Match expression. */ -public class TextMultiMatchExpression extends AbstractTextExpression { +final class TextMultiMatchExpression extends AbstractTextExpression { private final String search; - private final MultiMatch options; - public TextMultiMatchExpression(String search, MultiMatch options) { + TextMultiMatchExpression(String search, MultiMatch options) { super(null); this.search = search; this.options = options; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextQueryStringExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextQueryStringExpression.java index 2a44e39d5..dcd46a240 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextQueryStringExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextQueryStringExpression.java @@ -7,13 +7,12 @@ import java.io.IOException; /** * Full text query string expression. */ -class TextQueryStringExpression extends AbstractTextExpression { +final class TextQueryStringExpression extends AbstractTextExpression { private final String search; - private final TextQueryString options; - public TextQueryStringExpression(String search, TextQueryString options) { + TextQueryStringExpression(String search, TextQueryString options) { super(null); this.search = search; this.options = options; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextSimpleExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextSimpleExpression.java index 9faa7d1a7..ec6702c2a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextSimpleExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/TextSimpleExpression.java @@ -7,13 +7,12 @@ import java.io.IOException; /** * Full text Multi-Match expression. */ -class TextSimpleExpression extends AbstractTextExpression { +final class TextSimpleExpression extends AbstractTextExpression { private final String search; - private final TextSimple options; - public TextSimpleExpression(String search, TextSimple options) { + TextSimpleExpression(String search, TextSimple options) { super(null); this.search = search; this.options = options; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/BaseDbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/BaseDbExpression.java index 2c85e7963..a8d4d6adc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/BaseDbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/BaseDbExpression.java @@ -10,7 +10,6 @@ abstract class BaseDbExpression implements DbExpressionHandler { @Override public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) { - String bitOp = bitOp(operator); request.append("(").append(propName).append(" ").append(bitOp).append(" ? ").append(compare).append(" ?)"); } @@ -30,7 +29,6 @@ abstract class BaseDbExpression implements DbExpressionHandler { * Common alternative where the bitwise operation is a function (specifically bitand is used - H2 and Oracle). */ protected void bitwiseFunction(SpiExpressionRequest request, String propName, BitwiseOp operator, String compare) { - String funcName = functionName(operator); request.append(funcName).append("(").append(propName).append(", ?) ").append(compare).append(" ?"); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/BasicDbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/BasicDbExpression.java index 8b5ab8d70..edecf8230 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/BasicDbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/BasicDbExpression.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.expression.Op; /** * Not supported JSON or ARRAY expression handler. */ -public class BasicDbExpression extends BaseDbExpression { +class BasicDbExpression extends BaseDbExpression { @Override public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/DbExpressionHandlerFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/DbExpressionHandlerFactory.java index c4b24fc84..6f773b270 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/DbExpressionHandlerFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/DbExpressionHandlerFactory.java @@ -4,13 +4,12 @@ import io.ebean.annotation.Platform; import io.ebean.config.dbplatform.DatabasePlatform; -public class DbExpressionHandlerFactory { +public final class DbExpressionHandlerFactory { /** * Create and return the appropriate platform specific handing of expressions. */ public static DbExpressionHandler from(DatabasePlatform databasePlatform) { - Platform platform = databasePlatform.getPlatform(); switch (platform) { case H2: diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/H2DbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/H2DbExpression.java index 0c7e43b65..5eddb5d11 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/H2DbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/H2DbExpression.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.expression.BitwiseOp; /** * H2 handling of platform specific expressions. */ -class H2DbExpression extends BasicDbExpression { +final class H2DbExpression extends BasicDbExpression { @Override public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/HanaDbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/HanaDbExpression.java index a6633edfa..43919c1a0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/HanaDbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/HanaDbExpression.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.expression.Op; /** * HANA handling of platform specific expressions. */ -public class HanaDbExpression extends BaseDbExpression { +final class HanaDbExpression extends BaseDbExpression { @Override public void bitwise(SpiExpressionRequest request, String propName, BitwiseOp operator, long flags, String compare, long match) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/MariaDbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/MariaDbExpression.java index 8e4c0be1d..8116b2c4e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/MariaDbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/MariaDbExpression.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.expression.Op; /** * MariaDB specific handling of platform specific expressions. */ -class MariaDbExpression extends BasicDbExpression { +final class MariaDbExpression extends BasicDbExpression { @Override public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/MySqlDbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/MySqlDbExpression.java index 8ea2595fe..b0721a44e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/MySqlDbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/MySqlDbExpression.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.expression.Op; /** * MySql specific handling of platform specific expressions. */ -class MySqlDbExpression extends BasicDbExpression { +final class MySqlDbExpression extends BasicDbExpression { @Override public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/OracleDbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/OracleDbExpression.java index 3ec4b4071..f1fbaef7a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/OracleDbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/OracleDbExpression.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.expression.Op; /** * Oracle handling of platform specific expressions. ARRAY expressions not supported. */ -public class OracleDbExpression extends BaseDbExpression { +final class OracleDbExpression extends BaseDbExpression { @Override public String concat(String property0, String separator, String property1, String suffix) { @@ -16,7 +16,6 @@ public class OracleDbExpression extends BaseDbExpression { @Override public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) { - if (operator == Op.EXISTS) { request.append("json_exists(").append(propName).append(", '$.").append(path).append("')"); } else if (operator == Op.NOT_EXISTS) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/PostgresCast.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/PostgresCast.java index 3e833cb12..595acb6cd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/PostgresCast.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/PostgresCast.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.expression.platform; /** * Helper for determining type casting for JSON and ARRAY expressions. */ -public class PostgresCast { +final class PostgresCast { /** * Postgres CAST the type if necessary. @@ -11,15 +11,14 @@ public class PostgresCast { * This is generally necessary for JSON expressions as text values always returned from the json operators used. *

*/ - protected static String cast(Object value) { + static String cast(Object value) { return cast(value, false); } /** * Postgres CAST the type if necessary additionally specify if DB ARRAY is used. */ - protected static String cast(Object value, boolean asArray) { - + static String cast(Object value, boolean asArray) { if (value == null) { // for exists and not-exists expressions return ""; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/PostgresDbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/PostgresDbExpression.java index 54270ee5c..a3f044072 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/PostgresDbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/PostgresDbExpression.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.expression.Op; /** * Postgres JSON and ARRAY expression handler */ -public class PostgresDbExpression extends BaseDbExpression { +final class PostgresDbExpression extends BaseDbExpression { @Override public String concat(String property0, String separator, String property1, String suffix) { @@ -15,7 +15,6 @@ public class PostgresDbExpression extends BaseDbExpression { @Override public void json(SpiExpressionRequest request, String propName, String path, Op operator, Object value) { - StringBuilder sb = new StringBuilder(50); String[] paths = path.split("\\."); if (paths.length == 1) { @@ -41,7 +40,6 @@ public class PostgresDbExpression extends BaseDbExpression { @Override public void arrayContains(SpiExpressionRequest request, String propName, boolean contains, Object... values) { - if (!contains) { request.append("not ("); } @@ -58,7 +56,6 @@ public class PostgresDbExpression extends BaseDbExpression { @Override public void arrayIsEmpty(SpiExpressionRequest request, String propName, boolean empty) { - request.append("coalesce(cardinality(").append(propName).append("),0)"); if (empty) { request.append(" = 0"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/SqlServerDbExpression.java b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/SqlServerDbExpression.java index 98d76ec43..78838a81e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/SqlServerDbExpression.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/expression/platform/SqlServerDbExpression.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.expression.Op; /** * Microsoft SQL Server JSON. ARRAY expressions not supported. */ -public class SqlServerDbExpression extends BaseDbExpression { +final class SqlServerDbExpression extends BaseDbExpression { @Override public void json(final SpiExpressionRequest request, final String propName, From 9ee63144e57721ec49a9cd3c54c5de88f99678e6 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 23:32:05 +1200 Subject: [PATCH 104/120] #2318 - Refactor internals - final classes in core packages --- .../server/core/DScriptRunner.java | 2 +- .../server/core/DefaultBeanLoader.java | 19 +- .../server/core/DefaultBeanState.java | 2 +- .../server/core/DefaultCallOriginFactory.java | 2 +- .../server/core/DefaultCallableSql.java | 2 +- .../server/core/DefaultContainer.java | 2 +- .../server/core/DefaultMetaInfoManager.java | 2 +- .../server/core/DefaultQueryPlanListener.java | 2 +- .../server/core/DefaultSlowQueryListener.java | 3 +- .../ebeaninternal/server/core/DiffHelp.java | 6 +- .../server/core/DumpMetrics.java | 4 +- .../server/core/DumpMetricsData.java | 4 +- .../server/core/DumpMetricsJson.java | 7 +- .../server/core/InitDataSource.java | 3 +- .../server/core/InternalConfigXmlMap.java | 2 +- .../server/core/InternalConfiguration.java | 2 +- .../server/core/JndiDataSourceLookup.java | 6 +- .../core/MultiTenantDbCatalogSupplier.java | 3 +- .../core/MultiTenantDbSchemaSupplier.java | 3 +- .../server/core/MultiTenantDbSupplier.java | 3 +- .../server/core/NoopCallOriginFactory.java | 2 +- .../core/PersistDeferredRelationship.java | 2 +- .../server/core/RefreshHelp.java | 215 ------------------ .../server/core/SimpleDataSourceProvider.java | 3 +- .../server/core/SpiResultSet.java | 2 +- 25 files changed, 24 insertions(+), 279 deletions(-) delete mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/core/RefreshHelp.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DScriptRunner.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DScriptRunner.java index 8bf649438..cb78076bc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DScriptRunner.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DScriptRunner.java @@ -17,7 +17,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.Map; -class DScriptRunner implements ScriptRunner { +final class DScriptRunner implements ScriptRunner { private static final String NEWLINE = "\n"; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java index 34417ed14..4d0409d4c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanLoader.java @@ -26,12 +26,11 @@ import java.util.List; /** * Helper to handle lazy loading and refreshing of beans. */ -class DefaultBeanLoader { +final class DefaultBeanLoader { private static final Logger logger = LoggerFactory.getLogger(DefaultBeanLoader.class); private final DefaultServer server; - private final boolean onIterateUseExtraTxn; DefaultBeanLoader(DefaultServer server) { @@ -40,17 +39,14 @@ class DefaultBeanLoader { } void loadMany(LoadManyRequest loadRequest) { - SpiQuery query = loadRequest.createQuery(server); executeQuery(loadRequest, query); loadRequest.postLoad(); } void loadMany(BeanCollection bc, boolean onlyIds) { - EntityBean parentBean = bc.getOwnerBean(); String propertyName = bc.getPropertyName(); - loadManyInternal(parentBean, propertyName, null, false, onlyIds); } @@ -59,13 +55,10 @@ class DefaultBeanLoader { } private void loadManyInternal(EntityBean parentBean, String propertyName, Transaction t, boolean refresh, boolean onlyIds) { - EntityBeanIntercept ebi = parentBean._ebean_getIntercept(); PersistenceContext pc = ebi.getPersistenceContext(); - BeanDescriptor parentDesc = server.getBeanDescriptor(parentBean.getClass()); BeanPropertyAssocMany many = (BeanPropertyAssocMany) parentDesc.getBeanProperty(propertyName); - BeanCollection beanCollection = null; ExpressionList filterMany = null; @@ -126,7 +119,6 @@ class DefaultBeanLoader { } server.findOne(query, t); - if (beanCollection != null) { if (beanCollection.checkEmptyLazyLoad()) { if (logger.isDebugEnabled()) { @@ -142,7 +134,6 @@ class DefaultBeanLoader { * Load a batch of beans for +query or +lazy loading. */ void loadBean(LoadBeanRequest loadRequest) { - List batch = loadRequest.getBatch(); if (batch.isEmpty()) { throw new RuntimeException("Nothing in batch?"); @@ -190,7 +181,6 @@ class DefaultBeanLoader { } private void refreshBeanInternal(EntityBean bean, SpiQuery.Mode mode, int embeddedOwnerIndex) { - EntityBeanIntercept ebi = bean._ebean_getIntercept(); PersistenceContext pc = ebi.getPersistenceContext(); if (Mode.REFRESH_BEAN == mode) { @@ -203,12 +193,10 @@ class DefaultBeanLoader { // lazy loading on an embedded bean property EntityBean embeddedOwner = (EntityBean) ebi.getEmbeddedOwner(); int ownerIndex = ebi.getEmbeddedOwnerIndex(); - refreshBeanInternal(embeddedOwner, mode, ownerIndex); } Object id = desc.getId(bean); - if (pc == null) { // a reference with no existing persistenceContext pc = new DefaultPersistenceContext(); @@ -216,7 +204,6 @@ class DefaultBeanLoader { ebi.setPersistenceContext(pc); } boolean draft = desc.isDraftInstance(bean); - if (embeddedOwnerIndex == -1) { if (desc.lazyLoadMany(ebi)) { return; @@ -246,16 +233,13 @@ class DefaultBeanLoader { query.setPersistenceContext(pc); query.setMode(mode); query.setId(id); - if (embeddedOwnerIndex > -1 || mode == Mode.REFRESH_BEAN) { // make sure the query doesn't use the cache query.setUseCache(false); } - if (ebi.isReadOnly()) { query.setReadOnly(true); } - if (Mode.REFRESH_BEAN == mode) { // explicitly state to load all properties on REFRESH. // Lobs default to fetch lazy so this forces lobs to be @@ -268,7 +252,6 @@ class DefaultBeanLoader { String msg = "Bean not found during lazy load or refresh." + " id[" + id + "] type[" + desc.getBeanType() + "]"; throw new EntityNotFoundException(msg); } - desc.resetManyProperties(dbBean); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanState.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanState.java index 22f2b7ae8..332b4fc0d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanState.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultBeanState.java @@ -11,7 +11,7 @@ import java.util.Set; /** * Default implementation of BeanState. */ -public class DefaultBeanState implements BeanState { +public final class DefaultBeanState implements BeanState { private final EntityBeanIntercept intercept; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultCallOriginFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultCallOriginFactory.java index 249f4dbdb..233a2a920 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultCallOriginFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultCallOriginFactory.java @@ -8,7 +8,7 @@ import java.util.Arrays; /** * Default CallStackFactory where the Hash function for StackTraceElement includes the line number. */ -public class DefaultCallOriginFactory implements CallOriginFactory { +public final class DefaultCallOriginFactory implements CallOriginFactory { private static final int IGNORE_LEADING_ELEMENTS = 5; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultCallableSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultCallableSql.java index f41919ce2..fe7b18392 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultCallableSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultCallableSql.java @@ -12,7 +12,7 @@ import java.sql.CallableStatement; import java.sql.SQLException; -public class DefaultCallableSql implements Serializable, SpiCallableSql { +public final class DefaultCallableSql implements Serializable, SpiCallableSql { private static final long serialVersionUID = 8984272253185424701L; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java index e912b8cbb..348fd2f32 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultContainer.java @@ -32,7 +32,7 @@ import java.util.concurrent.locks.ReentrantLock; /** * Default Server side implementation of ServerFactory. */ -public class DefaultContainer implements SpiContainer { +public final class DefaultContainer implements SpiContainer { private static final Logger logger = LoggerFactory.getLogger("io.ebean.DB"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultMetaInfoManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultMetaInfoManager.java index a6a65e19d..a1775e818 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultMetaInfoManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultMetaInfoManager.java @@ -19,7 +19,7 @@ import java.util.List; /** * DefaultServer based implementation of MetaInfoManager. */ -public class DefaultMetaInfoManager implements MetaInfoManager { +final class DefaultMetaInfoManager implements MetaInfoManager { private final DefaultServer server; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultQueryPlanListener.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultQueryPlanListener.java index 20d7ec223..ba2e99bda 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultQueryPlanListener.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultQueryPlanListener.java @@ -6,7 +6,7 @@ import io.ebean.meta.MetaQueryPlan; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -class DefaultQueryPlanListener implements QueryPlanListener { +final class DefaultQueryPlanListener implements QueryPlanListener { static final QueryPlanListener INSTANT = new DefaultQueryPlanListener(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultSlowQueryListener.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultSlowQueryListener.java index b271a513e..64c813213 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultSlowQueryListener.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultSlowQueryListener.java @@ -9,13 +9,12 @@ import org.slf4j.LoggerFactory; /** * Default slow query listener implementation that logs a warning message. */ -class DefaultSlowQueryListener implements SlowQueryListener { +final class DefaultSlowQueryListener implements SlowQueryListener { private static final Logger log = LoggerFactory.getLogger("io.ebean.SlowQuery"); @Override public void process(SlowQueryEvent event) { - String firstStack = ""; ObjectGraphNode node = event.getOriginNode(); if (node != null) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DiffHelp.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DiffHelp.java index b879727db..9eca59e19 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DiffHelp.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DiffHelp.java @@ -12,7 +12,7 @@ import java.util.Map; * This intentionally does not include any OneToMany or ManyToMany properties. *

*/ -public class DiffHelp { +public final class DiffHelp { private DiffHelp() { } @@ -28,11 +28,9 @@ public class DiffHelp { *

*/ public static Map diff(Object newBean, Object oldBean, BeanDescriptor desc) { - if (!(newBean instanceof EntityBean)) { throw new IllegalArgumentException("First bean expected to be an enhanced EntityBean? bean:" + newBean); } - if (oldBean != null) { if (!(oldBean instanceof EntityBean)) { throw new IllegalArgumentException("Second bean expected to be an enhanced EntityBean? bean:" + oldBean); @@ -41,11 +39,9 @@ public class DiffHelp { throw new IllegalArgumentException("Second bean not assignable to the first bean?"); } } - if (oldBean == null) { return ((EntityBean) newBean)._ebean_getIntercept().getDirtyValues(); } - return desc.diff((EntityBean) newBean, (EntityBean) oldBean); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java index 5274b4ced..9b5a1afa7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetrics.java @@ -10,14 +10,12 @@ import io.ebeaninternal.api.SpiEbeanServer; import java.util.Comparator; import java.util.List; -class DumpMetrics { +final class DumpMetrics { private final SpiEbeanServer server; private final String options; - private final String nameFormat; private final String nameFormatTimed; - private boolean dumpHash; private boolean dumpSql; private boolean dumpLoc; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java index 4bc1e5035..712521ce0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsData.java @@ -14,10 +14,9 @@ import java.util.List; /** * Dump the metrics into a list of MetricData. */ -class DumpMetricsData { +final class DumpMetricsData { private final Database database; - private final List list = new ArrayList<>(); DumpMetricsData(Database database) { @@ -30,7 +29,6 @@ class DumpMetricsData { } private void collect(ServerMetrics serverMetrics) { - final List timedMetrics = serverMetrics.timedMetrics(); final List countMetrics = serverMetrics.countMetrics(); final List queryMetrics = serverMetrics.queryMetrics(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java index 90200f79b..190af0af4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DumpMetricsJson.java @@ -14,23 +14,18 @@ import java.io.StringWriter; import java.util.Comparator; import java.util.List; -class DumpMetricsJson implements ServerMetricsAsJson { +final class DumpMetricsJson implements ServerMetricsAsJson { private final Database database; - private Appendable writer; - /** * By default include sql and location attributes for the initial collection only. */ private int includeExtraAttributes = 1; - private boolean withHeader = true; private boolean withHash = true; private String newLine = "\n"; - private Comparator sortBy = SortMetric.NAME; - private int listCounter; private int objKeyCounter; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/InitDataSource.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/InitDataSource.java index 3a03c7361..f65cb0823 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/InitDataSource.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/InitDataSource.java @@ -12,10 +12,9 @@ import javax.sql.DataSource; /** * Initialise the main DataSource and read-only DataSource. */ -class InitDataSource { +final class InitDataSource { private final JndiDataSourceLookup jndiDataSourceFactory = new JndiDataSourceLookup(); - private final DatabaseConfig config; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlMap.java index ccfa08de3..594a9f29d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfigXmlMap.java @@ -14,7 +14,7 @@ import java.util.Map; /** * Reads the Xml deployment information. */ -class InternalConfigXmlMap { +final class InternalConfigXmlMap { private static final Logger log = LoggerFactory.getLogger(InternalConfigXmlMap.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java index dca8e3059..96ab21aa2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java @@ -113,7 +113,7 @@ import java.util.ServiceLoader; * Used to extend the DatabaseConfig with additional objects used to configure and * construct an Database. */ -public class InternalConfiguration { +public final class InternalConfiguration { private static final Logger logger = LoggerFactory.getLogger(InternalConfiguration.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/JndiDataSourceLookup.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/JndiDataSourceLookup.java index 0e541fadd..09b2f7a9c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/JndiDataSourceLookup.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/JndiDataSourceLookup.java @@ -9,10 +9,7 @@ import javax.sql.DataSource; /** * Helper to lookup a DataSource from JNDI. */ -public class JndiDataSourceLookup { - - public JndiDataSourceLookup() { - } +class JndiDataSourceLookup { /** * Return the DataSource by JNDI lookup. @@ -21,7 +18,6 @@ public class JndiDataSourceLookup { *

*/ public DataSource lookup(String jndiName) { - try { Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(jndiName); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbCatalogSupplier.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbCatalogSupplier.java index 8b369d25a..abe20b1ca 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbCatalogSupplier.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbCatalogSupplier.java @@ -15,11 +15,10 @@ import java.util.logging.Logger; /** * DataSource supplier that changes DB catalog based on current Tenant Id. */ -public class MultiTenantDbCatalogSupplier implements DataSourceSupplier { +final class MultiTenantDbCatalogSupplier implements DataSourceSupplier { private final DataSource dataSource; private final DataSource readOnlyDataSource; - private final CatalogDataSource catalogDataSource; private final CatalogDataSource readOnly; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbSchemaSupplier.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbSchemaSupplier.java index f37ce202e..2a1af6016 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbSchemaSupplier.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbSchemaSupplier.java @@ -15,11 +15,10 @@ import java.util.logging.Logger; /** * DataSource supplier that changes DB schema based on current Tenant Id. */ -class MultiTenantDbSchemaSupplier implements DataSourceSupplier { +final class MultiTenantDbSchemaSupplier implements DataSourceSupplier { private final DataSource dataSource; private final DataSource readOnlyDataSource; - private final SchemaDataSource schemaDataSource; private final SchemaDataSource readOnly; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbSupplier.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbSupplier.java index b985c7864..e6237abfa 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbSupplier.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/MultiTenantDbSupplier.java @@ -11,10 +11,9 @@ import java.sql.SQLException; /** * DataSource supplier based on DataSource per Tenant. */ -class MultiTenantDbSupplier implements DataSourceSupplier { +final class MultiTenantDbSupplier implements DataSourceSupplier { private final CurrentTenantProvider tenantProvider; - private final TenantDataSourceProvider dataSourceProvider; MultiTenantDbSupplier(CurrentTenantProvider tenantProvider, TenantDataSourceProvider dataSourceProvider) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/NoopCallOriginFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/NoopCallOriginFactory.java index eee313bc3..a95e507ea 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/NoopCallOriginFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/NoopCallOriginFactory.java @@ -6,7 +6,7 @@ import io.ebean.bean.CallStack; /** * A CallOriginFactory we can use when we don't use AutoTune. */ -class NoopCallOriginFactory implements CallOriginFactory { +final class NoopCallOriginFactory implements CallOriginFactory { private static final StackTraceElement E0 = new StackTraceElement("none", "none", "none", 0); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistDeferredRelationship.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistDeferredRelationship.java index ff81f49da..41bbb20ef 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistDeferredRelationship.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/PersistDeferredRelationship.java @@ -11,7 +11,7 @@ import io.ebeaninternal.server.deploy.id.ImportedId; * Deferred update of a relationship where an Id value is not initially available * so instead we execute this later as a SqlUpdate statement. */ -public class PersistDeferredRelationship { +public final class PersistDeferredRelationship { private final SpiEbeanServer ebeanServer; private final BeanDescriptor beanDescriptor; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/RefreshHelp.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/RefreshHelp.java deleted file mode 100644 index 24ff1d117..000000000 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/RefreshHelp.java +++ /dev/null @@ -1,215 +0,0 @@ -package io.ebeaninternal.server.core; - - -/** - * Helper for performing a 'refresh' on an Entity bean. - *

- * Note that this does not 'refresh' any OnetoMany or ManyToMany properties. It - * refreshes all the other properties though. - *

- */ -public class RefreshHelp { -// -// /** -// * Helper for debug of lazy loading. -// */ -// private final DebugLazyLoad debugLazyLoad; -// -// private final MAdminLoggingMBean logControl; -// -// public RefreshHelp(MAdminLoggingMBean logControl, boolean debugLazyLoad){ -// this.logControl = logControl; -// this.debugLazyLoad = new DebugLazyLoad(debugLazyLoad); -// } -// -// /** -// * Refresh the bean from property values in dbBean. -// */ -// public void refresh(Object o, Object dbBean, BeanDescriptor desc, EntityBeanIntercept ebi, Object id, boolean isLazyLoad) { -// -// Object originalOldValues = null; -// boolean setOriginalOldValues = false; -// -// // set of properties to exclude from the refresh because it is -// // not a refresh but rather a lazyLoading event. -// Set excludes = null; -// -// // turn off intercepting so lazy loading is -// // not invoked when populating the bean -// // with PropertyChangeSupport -// ebi.setIntercepting(false); -// -// boolean readOnly = ebi.isReadOnly(); -// boolean sharedInstance = ebi.isSharedInstance(); -// -// if (isLazyLoad){ -// excludes = ebi.getLoadedProps(); -// if (excludes != null){ -// // lazy loading a "Partial Object"... which already -// // contains some properties and perhaps some oldValues -// // and these will need to be maintained... -// originalOldValues = ebi.getOldValues(); -// setOriginalOldValues = originalOldValues != null; -// } -// -// if (logControl.isDebugLazyLoad()){ -// debug(desc, ebi, id, excludes); -// } -// } -// -// -// BeanProperty[] props = desc.propertiesBaseScalar(); -// for (int i = 0; i < props.length; i++) { -// BeanProperty prop = props[i]; -// if (excludes != null && excludes.contains(prop.getName())){ -// // ignore this property (partial bean lazy loading) -// -// } else { -// Object dbVal = prop.getValue(dbBean); -// if (isLazyLoad) { -// prop.setValue(o, dbVal); -// } else { -// prop.setValueIntercept(o, dbVal); -// } -// if (setOriginalOldValues){ -// // maintain original oldValues for partially loaded bean -// prop.setValue(originalOldValues, dbVal); -// } -// } -// } -// -// BeanPropertyAssocOne[] ones = desc.propertiesOne(); -// for (int i = 0; i < ones.length; i++) { -// BeanProperty prop = ones[i]; -// if (excludes != null && excludes.contains(prop.getName())){ -// // ignore this property (partial bean lazy loading) -// -// } else { -// Object dbVal = prop.getValue(dbBean); -// if (isLazyLoad){ -// prop.setValue(o, dbVal); -// } else { -// prop.setValueIntercept(o, dbVal); -// } -// if (setOriginalOldValues){ -// // maintain original oldValues for partially loaded bean -// prop.setValue(originalOldValues, dbVal); -// } -// if (dbVal != null){ -// if (sharedInstance){ -// // propagate sharedInstance status to associated beans -// ((EntityBean)dbVal)._ebean_getIntercept().setSharedInstance(); -// } else if (readOnly) { -// // propagate readOnly status to associated beans -// ((EntityBean)dbVal)._ebean_getIntercept().setReadOnly(true); -// } -// } -// -// } -// } -// -// refreshEmbedded(o, dbBean, desc, excludes, readOnly); -// -// // set a lazy loading many proxy if required -// BeanPropertyAssocMany[] manys = desc.propertiesMany(); -// for (int i = 0; i < manys.length; i++) { -// BeanPropertyAssocMany prop = manys[i]; -// if (excludes != null && excludes.contains(prop.getName())){ -// // the many already existed on the bean -// -// } else { -// // set a lazy loading proxy -// prop.createReference(o, null, readOnly, sharedInstance); -// } -// } -// -// // the refreshed/lazy loaded bean is always fully -// // populated so set loadedProps to null -// ebi.setLoadedProps(null); -// -// -// // reset the loaded status -// ebi.setLoaded(); -// } -// -// /** -// * Refresh the Embedded beans. -// */ -// private void refreshEmbedded(Object o, Object dbBean, BeanDescriptor desc, Set excludes, boolean propagateReadOnly) { -// -// BeanPropertyAssocOne[] embeds = desc.propertiesEmbedded(); -// for (int i = 0; i < embeds.length; i++) { -// BeanPropertyAssocOne prop = embeds[i]; -// if (excludes != null && excludes.contains(prop.getName())){ -// // ignore this property -// } else { -// // the original embedded bean -// Object oEmb = prop.getValue(o); -// -// // the new one from the database -// Object dbEmb = prop.getValue(dbBean); -// -// if (oEmb == null){ -// // original embedded bean was null -// // so just replace the entire embedded bean -// prop.setValueIntercept(o, dbEmb); -// if (propagateReadOnly && dbEmb != null){ -// // propagate readOnly status to embedded beans -// ((EntityBean)dbEmb)._ebean_getIntercept().setReadOnly(true); -// } -// -// } else { -// // refresh each property of the original -// // embedded bean -// if (oEmb instanceof EntityBean){ -// // turn off interception to stop invoking lazy loading -// // but allow PropertyChangeSupport -// ((EntityBean) oEmb)._ebean_getIntercept().setIntercepting(false); -// } -// -// BeanProperty[] props = prop.getProperties(); -// for (int j = 0; j < props.length; j++) { -// Object v = props[j].getValue(dbEmb); -// props[j].setValueIntercept(oEmb, v); -// } -// -// // No longer calling setLoaded() on embedded bean -// // as the EntityBean itself -// // .. calls setEmbeddedLoaded() on each of -// // .. its embedded beans itself. -// } -// } -// } -// } -// -// -// /** -// * Output some debug to describe the lazy loading event. -// */ -// private void debug(BeanDescriptor desc, EntityBeanIntercept ebi, Object id, Set excludes) { -// -// -// Class beanType = desc.getBeanType(); -// -// StackTraceElement cause = debugLazyLoad.getStackTraceElement(beanType); -// -// String lazyLoadProperty = ebi.getLazyLoadProperty(); -// String msg = "debug.lazyLoad ["+desc+"] id["+id+"] lazyLoadProperty["+lazyLoadProperty+"]"; -// if (excludes != null){ -// msg += " partialProps"+excludes; -// } -// if (cause != null){ -// String causeLine = cause.toString(); -// if (causeLine.indexOf(".groovy:") > -1){ -// // eclipse console does not like finding groovy source at the moment -// causeLine = StringHelper.replaceString(causeLine, ".groovy:", ".groovy :"); -// } -// msg += " at: "+causeLine; -// } -// System.err.println(msg); -// } -// -// -// - -} diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/SimpleDataSourceProvider.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/SimpleDataSourceProvider.java index f9a11f14d..7680dd086 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/SimpleDataSourceProvider.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/SimpleDataSourceProvider.java @@ -10,10 +10,9 @@ import java.sql.SQLException; /** * Simple DataSource supplier when no multi-tenancy used. */ -class SimpleDataSourceProvider implements DataSourceSupplier { +final class SimpleDataSourceProvider implements DataSourceSupplier { private final DataSource dataSource; - private final DataSource readOnlyDataSource; SimpleDataSourceProvider(DataSource dataSource, DataSource readOnlyDataSource) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/SpiResultSet.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/SpiResultSet.java index 6c539e564..e95c0d461 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/SpiResultSet.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/SpiResultSet.java @@ -8,7 +8,7 @@ import java.sql.ResultSet; * * These both must be closed properly when done. */ -public class SpiResultSet { +public final class SpiResultSet { private final PreparedStatement statement; From cd407ee467ffc18321dc517b4bae8069e1149141 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Mon, 16 Aug 2021 23:32:26 +1200 Subject: [PATCH 105/120] #2318 - Refactor internals - final classes in changelog packages --- .../server/changelog/ChangeJsonBuilder.java | 18 ++---------------- .../changelog/DefaultChangeLogListener.java | 5 ++--- .../changelog/DefaultChangeLogPrepare.java | 2 +- .../changelog/DefaultChangeLogRegister.java | 3 +-- .../changelog/ChangeJsonBuilderTest.java | 3 +-- 5 files changed, 7 insertions(+), 24 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/changelog/ChangeJsonBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/changelog/ChangeJsonBuilder.java index 372de9589..f399b78ad 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/changelog/ChangeJsonBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/changelog/ChangeJsonBuilder.java @@ -14,21 +14,14 @@ import java.util.Map; /** * Builds JSON document for a bean change. */ -class ChangeJsonBuilder { +final class ChangeJsonBuilder { - protected final JsonFactory jsonFactory = new JsonFactory(); - - protected final JsonContext json; - - ChangeJsonBuilder(JsonContext json) { - this.json = json; - } + private final JsonFactory jsonFactory = new JsonFactory(); /** * Write the bean change as JSON. */ void writeBeanJson(Writer writer, BeanChange bean, ChangeSet changeSet) throws IOException { - try (JsonGenerator generator = jsonFactory.createGenerator(writer)) { writeBeanChange(generator, bean, changeSet); generator.flush(); @@ -39,9 +32,7 @@ class ChangeJsonBuilder { * Write the bean change as JSON document containing the transaction header details. */ private void writeBeanChange(JsonGenerator gen, BeanChange bean, ChangeSet changeSet) throws IOException { - gen.writeStartObject(); - gen.writeNumberField("ts", bean.getEventTime()); gen.writeStringField("change", bean.getEvent().getCode()); gen.writeStringField("type", bean.getType()); @@ -49,9 +40,7 @@ class ChangeJsonBuilder { if (bean.getTenantId() != null) { gen.writeStringField("tenantId", bean.getTenantId().toString()); } - writeBeanTransactionDetails(gen, changeSet); - writeBeanValues(gen, bean); gen.writeEndObject(); } @@ -60,7 +49,6 @@ class ChangeJsonBuilder { * Denormalise by writing the transaction header details. */ private void writeBeanTransactionDetails(JsonGenerator gen, ChangeSet changeSet) throws IOException { - String source = changeSet.getSource(); if (source != null) { gen.writeStringField("source", source); @@ -87,12 +75,10 @@ class ChangeJsonBuilder { * For insert and update write the new/old values. */ private void writeBeanValues(JsonGenerator gen, BeanChange bean) throws IOException { - if (bean.getEvent() != ChangeType.DELETE) { gen.writeFieldName("data"); gen.writeRaw(":"); gen.writeRaw(bean.getData()); - String oldData = bean.getOldData(); if (oldData != null) { gen.writeRaw(",\"oldData\":"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogListener.java b/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogListener.java index 0168fa222..ee8e75424 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogListener.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogListener.java @@ -15,7 +15,7 @@ import java.util.Properties; /** * Simply logs the change sets in JSON form to logger named io.ebean.ChangeLog. */ -public class DefaultChangeLogListener implements ChangeLogListener, Plugin { +public final class DefaultChangeLogListener implements ChangeLogListener, Plugin { /** * The usual application specific logger. @@ -45,8 +45,7 @@ public class DefaultChangeLogListener implements ChangeLogListener, Plugin { */ @Override public void configure(SpiServer server) { - jsonBuilder = new ChangeJsonBuilder(server.json()); - + jsonBuilder = new ChangeJsonBuilder(); Properties properties = server.getServerConfig().getProperties(); if (properties != null) { String bufferSize = properties.getProperty("ebean.changeLog.bufferSize"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogPrepare.java b/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogPrepare.java index 16af27424..596d4d331 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogPrepare.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogPrepare.java @@ -11,7 +11,7 @@ import io.ebean.event.changelog.ChangeSet; * on the changeSet. *

*/ -public class DefaultChangeLogPrepare implements ChangeLogPrepare { +public final class DefaultChangeLogPrepare implements ChangeLogPrepare { /** * Just return true to send change set through to the logger. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogRegister.java b/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogRegister.java index a6208a703..d9f962969 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogRegister.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/changelog/DefaultChangeLogRegister.java @@ -14,10 +14,9 @@ import java.util.Set; /** * Default implementation of ChangeLogRegister. */ -public class DefaultChangeLogRegister implements ChangeLogRegister { +public final class DefaultChangeLogRegister implements ChangeLogRegister { private static final BasicFilter INCLUDE_INSERTS = new BasicFilter(true); - private static final BasicFilter EXCLUDE_INSERTS = new BasicFilter(false); private final boolean defaultInsertsInclude; diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/changelog/ChangeJsonBuilderTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/changelog/ChangeJsonBuilderTest.java index f87405087..0e608f3e1 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/changelog/ChangeJsonBuilderTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/changelog/ChangeJsonBuilderTest.java @@ -20,8 +20,7 @@ public class ChangeJsonBuilderTest extends BaseTestCase { @Test public void testToJson() throws Exception { - JsonContext jsonContext = Ebean.getDefaultServer().json(); - ChangeJsonBuilder builder = new ChangeJsonBuilder(jsonContext); + ChangeJsonBuilder builder = new ChangeJsonBuilder(); ChangeSet changeSet = helper.createChangeSet("ABCD", 10); changeSet.getUserContext().put("altUser", "role user"); From b4f4ef3c1b307926956f8c85e58170506e96ade0 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 17 Aug 2021 18:24:28 +1200 Subject: [PATCH 106/120] #2318 - Refactor internals - final classes in server packages --- .../server/DContainerFactory.java | 2 +- .../server/loadcontext/DLoadBeanContext.java | 4 +--- .../server/loadcontext/DLoadContext.java | 10 +--------- .../server/loadcontext/DLoadManyContext.java | 7 ++----- .../server/logger/DLogManager.java | 2 +- .../server/logger/DLoggerFactory.java | 2 +- .../server/logger/DSpiLogger.java | 2 +- .../server/profile/DCountMetric.java | 3 +-- .../server/profile/DMetricFactory.java | 2 +- .../server/profile/DProfileLocation.java | 1 - .../profile/DProfileLocationFactory.java | 2 +- .../server/profile/DQueryPlanMeta.java | 2 +- .../server/profile/DQueryPlanMetric.java | 2 +- .../server/profile/DTimeMetricStats.java | 3 +-- .../server/profile/DTimedMetric.java | 6 +----- .../server/profile/DTimedProfileLocation.java | 5 +---- .../profile/TimedProfileLocationRegistry.java | 2 +- .../properties/BeanPropertiesReader.java | 1 - .../properties/EnhanceBeanPropertyAccess.java | 19 ++++++++---------- .../ebeaninternal/server/rawsql/DRawSql.java | 4 +--- .../server/rawsql/DRawSqlBuilder.java | 4 +--- .../server/rawsql/DRawSqlColumnsParser.java | 1 - .../server/rawsql/DRawSqlParser.java | 7 +------ .../server/rawsql/DRawSqlService.java | 6 +----- .../server/text/json/DJsonBeanReader.java | 3 +-- .../server/text/json/DJsonContext.java | 6 +----- .../server/text/json/DJsonScalar.java | 3 +-- .../server/text/json/PathStack.java | 4 +--- .../server/text/json/ReadJson.java | 20 +------------------ .../server/text/json/WriteJson.java | 9 +-------- .../ebeaninternal/server/util/ArrayStack.java | 4 +--- .../server/util/BindParamsParser.java | 6 +----- .../server/util/DSelectColumnsParser.java | 2 -- .../io/ebeaninternal/server/util/Str.java | 2 +- .../ebeaninternal/util/ParamTypeHelper.java | 11 ++-------- .../io/ebeaninternal/util/SortByClause.java | 6 +----- .../java/io/ebeaninternal/util/UrlHelper.java | 3 +-- .../java/io/ebeaninternal/util/ValueUtil.java | 2 +- .../docstore/none/NoneDocStore.java | 2 +- .../none/NoneDocStoreBeanAdapter.java | 2 +- .../docstore/none/NoneDocStoreFactory.java | 4 ++-- .../none/NoneDocStoreUpdateProcessor.java | 2 +- 42 files changed, 48 insertions(+), 142 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/DContainerFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/DContainerFactory.java index ea9f0b109..77d0a1f72 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/DContainerFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/DContainerFactory.java @@ -8,7 +8,7 @@ import io.ebeaninternal.server.core.DefaultContainer; /** * Default container factory found via service loader. */ -public class DContainerFactory implements SpiContainerFactory { +public final class DContainerFactory implements SpiContainerFactory { @Override public SpiContainer create(ContainerConfig containerConfig) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadBeanContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadBeanContext.java index 25fffe5b7..ac871e5eb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadBeanContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadBeanContext.java @@ -23,12 +23,10 @@ import java.util.concurrent.locks.ReentrantLock; /** * ToOne bean load context. */ -class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext { +final class DLoadBeanContext extends DLoadBaseContext implements LoadBeanContext { private final boolean cache; - private List bufferList; - private LoadBuffer currentBuffer; DLoadBeanContext(DLoadContext parent, BeanDescriptor desc, String path, OrmQueryProperties queryProps) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java index 060633073..a7ec0e0c8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadContext.java @@ -31,17 +31,13 @@ import java.util.Map; /** * Default implementation of LoadContext. */ -public class DLoadContext implements LoadContext { +public final class DLoadContext implements LoadContext { private final SpiEbeanServer ebeanServer; - private final BeanDescriptor rootDescriptor; - private final Map beanMap = new HashMap<>(); private final Map manyMap = new HashMap<>(); - private final DLoadBeanContext rootBeanContext; - private final boolean asDraft; private final Timestamp asOf; private final Boolean readOnly; @@ -60,13 +56,9 @@ public class DLoadContext implements LoadContext { private final String planLabel; private final ProfileLocation profileLocation; private final ProfilingListener profilingListener; - private final Map nodePathMap = new HashMap<>(); - private PersistenceContext persistenceContext; - private List secQuery; - private Object tenantId; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadManyContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadManyContext.java index 5d2b781c7..b830dc96d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadManyContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/loadcontext/DLoadManyContext.java @@ -21,14 +21,11 @@ import java.util.concurrent.locks.ReentrantLock; /** * ToMany bean load context. */ -class DLoadManyContext extends DLoadBaseContext implements LoadManyContext { - - protected final BeanPropertyAssocMany property; +final class DLoadManyContext extends DLoadBaseContext implements LoadManyContext { + private final BeanPropertyAssocMany property; private final boolean docStoreMapped; - private List bufferList; - private LoadBuffer currentBuffer; DLoadManyContext(DLoadContext parent, BeanPropertyAssocMany property, String path, OrmQueryProperties queryProps) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/logger/DLogManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/logger/DLogManager.java index 79ece19fc..31c42f2fd 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/logger/DLogManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/logger/DLogManager.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.logger; import io.ebeaninternal.api.SpiLogManager; import io.ebeaninternal.api.SpiLogger; -public class DLogManager implements SpiLogManager { +public final class DLogManager implements SpiLogManager { private final SpiLogger sql; private final SpiLogger summary; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/logger/DLoggerFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/logger/DLoggerFactory.java index 65dbef013..90f6cbafa 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/logger/DLoggerFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/logger/DLoggerFactory.java @@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory; /** * Default SpiLoggerFactory implementation. */ -public class DLoggerFactory implements SpiLoggerFactory { +public final class DLoggerFactory implements SpiLoggerFactory { /** * Just use a standard slf4j Logger. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/logger/DSpiLogger.java b/ebean-core/src/main/java/io/ebeaninternal/server/logger/DSpiLogger.java index 87b78052f..e921d5aa3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/logger/DSpiLogger.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/logger/DSpiLogger.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.logger; import io.ebeaninternal.api.SpiLogger; import org.slf4j.Logger; -public class DSpiLogger implements SpiLogger { +public final class DSpiLogger implements SpiLogger { private final Logger logger; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java index d93e0dbdb..693aa5de8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DCountMetric.java @@ -9,10 +9,9 @@ import java.util.concurrent.atomic.LongAdder; /** * Used to collect counter metrics. */ -class DCountMetric implements CountMetric { +final class DCountMetric implements CountMetric { private final String name; - private final LongAdder count = new LongAdder(); DCountMetric(String name) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DMetricFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DMetricFactory.java index 633c4c505..d51ff2198 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DMetricFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DMetricFactory.java @@ -10,7 +10,7 @@ import io.ebean.metric.TimedMetricMap; /** * Default metric factory implementation. */ -public class DMetricFactory implements MetricFactory { +public final class DMetricFactory implements MetricFactory { @Override public TimedMetricMap createTimedMetricMap(String name) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java index 63fa0e11a..df4c44c56 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocation.java @@ -13,7 +13,6 @@ class DProfileLocation implements ProfileLocation { private String fullLocation; private String location; private String label; - private final int lineNumber; private int traceCount; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocationFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocationFactory.java index ebf5e78c0..cc6e19bd3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocationFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DProfileLocationFactory.java @@ -8,7 +8,7 @@ import io.ebean.service.SpiProfileLocationFactory; /** * Default implementation of the profile location factory. */ -public class DProfileLocationFactory implements SpiProfileLocationFactory { +public final class DProfileLocationFactory implements SpiProfileLocationFactory { @Override public ProfileLocation create() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java index 67f724051..879d2ee6c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMeta.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.profile; import io.ebean.ProfileLocation; import io.ebeaninternal.server.util.Md5; -class DQueryPlanMeta { +final class DQueryPlanMeta { private final Class type; private final String label; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java index e24da73c7..723c24511 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DQueryPlanMetric.java @@ -6,7 +6,7 @@ import io.ebean.metric.QueryPlanMetric; import io.ebean.metric.TimedMetric; import io.ebean.metric.TimedMetricStats; -class DQueryPlanMetric implements QueryPlanMetric { +final class DQueryPlanMetric implements QueryPlanMetric { private final DQueryPlanMeta meta; private final DTimedMetric metric; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java index a4243e31a..900f47aae 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimeMetricStats.java @@ -5,13 +5,12 @@ import io.ebean.metric.TimedMetricStats; /** * Snapshot of the current statistics for a Counter or TimeCounter. */ -class DTimeMetricStats implements TimedMetricStats { +final class DTimeMetricStats implements TimedMetricStats { private final boolean collected; private final long count; private final long total; private final long max; - private String name; private String location; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java index cc344c3e6..a62fef911 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedMetric.java @@ -12,16 +12,12 @@ import java.util.concurrent.atomic.LongAdder; * It is intended for high concurrent updates to the statistics and relatively infrequent reads. *

*/ -class DTimedMetric implements TimedMetric { +final class DTimedMetric implements TimedMetric { private final String name; - private final LongAdder count = new LongAdder(); - private final LongAdder total = new LongAdder(); - private final LongAccumulator max = new LongAccumulator(Math::max, Long.MIN_VALUE); - private boolean collected; DTimedMetric(String name) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java index 27537737f..2164f86c7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/DTimedProfileLocation.java @@ -7,14 +7,11 @@ import io.ebean.metric.TimedMetricStats; /** * Default profile location that uses stack trace. */ -class DTimedProfileLocation extends DProfileLocation implements TimedProfileLocation { +final class DTimedProfileLocation extends DProfileLocation implements TimedProfileLocation { private final String label; - private final TimedMetric timedMetric; - private final boolean overrideMetricName; - private String fullName; DTimedProfileLocation(int lineNumber, String label, TimedMetric timedMetric) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/profile/TimedProfileLocationRegistry.java b/ebean-core/src/main/java/io/ebeaninternal/server/profile/TimedProfileLocationRegistry.java index 1a5f8ff07..350dd6688 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/profile/TimedProfileLocationRegistry.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/profile/TimedProfileLocationRegistry.java @@ -7,7 +7,7 @@ import java.util.List; /** * Global registry of the TimedProfileLocation instances created. */ -public class TimedProfileLocationRegistry { +public final class TimedProfileLocationRegistry { private static final List list = Collections.synchronizedList(new ArrayList<>()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/properties/BeanPropertiesReader.java b/ebean-core/src/main/java/io/ebeaninternal/server/properties/BeanPropertiesReader.java index a283a42ea..ec56da19d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/properties/BeanPropertiesReader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/properties/BeanPropertiesReader.java @@ -37,7 +37,6 @@ public final class BeanPropertiesReader { try { Field field = clazz.getField("_ebean_props"); return (String[]) field.get(null); - } catch (Exception e) { throw new IllegalStateException("Error getting _ebean_props field on type " + clazz, e); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/properties/EnhanceBeanPropertyAccess.java b/ebean-core/src/main/java/io/ebeaninternal/server/properties/EnhanceBeanPropertyAccess.java index e4d9e9839..e7e48b6f0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/properties/EnhanceBeanPropertyAccess.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/properties/EnhanceBeanPropertyAccess.java @@ -9,23 +9,20 @@ public final class EnhanceBeanPropertyAccess implements BeanPropertyAccess { private static final int CACHE_SIZE = 30; - private final BeanPropertyGetter[] getters = initGetters(CACHE_SIZE); - private final BeanPropertySetter[] setters = initSetters(CACHE_SIZE); + private final BeanPropertyGetter[] getters = initGetters(); + private final BeanPropertySetter[] setters = initSetters(); - public EnhanceBeanPropertyAccess() { - } - - private BeanPropertyGetter[] initGetters(int count) { - BeanPropertyGetter[] getters = new BeanPropertyGetter[count]; - for (int i = 0; i < count; i++) { + private BeanPropertyGetter[] initGetters() { + BeanPropertyGetter[] getters = new BeanPropertyGetter[CACHE_SIZE]; + for (int i = 0; i < CACHE_SIZE; i++) { getters[i] = new Getter(i); } return getters; } - private BeanPropertySetter[] initSetters(int count) { - BeanPropertySetter[] setters = new BeanPropertySetter[count]; - for (int i = 0; i < count; i++) { + private BeanPropertySetter[] initSetters() { + BeanPropertySetter[] setters = new BeanPropertySetter[CACHE_SIZE]; + for (int i = 0; i < CACHE_SIZE; i++) { setters[i] = new Setter(i); } return setters; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSql.java index 9f7e6627d..c58b8bc11 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSql.java @@ -8,9 +8,7 @@ import java.sql.ResultSet; public final class DRawSql implements SpiRawSql { private final ResultSet resultSet; - private final Sql sql; - private final ColumnMapping columnMapping; /** @@ -22,7 +20,7 @@ public final class DRawSql implements SpiRawSql { this.columnMapping = new ColumnMapping(propertyNames); } - protected DRawSql(ResultSet resultSet, Sql sql, ColumnMapping columnMapping) { + DRawSql(ResultSet resultSet, Sql sql, ColumnMapping columnMapping) { this.resultSet = resultSet; this.sql = sql; this.columnMapping = columnMapping; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlBuilder.java index 40160e873..a42c8035d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlBuilder.java @@ -5,12 +5,10 @@ import io.ebean.RawSqlBuilder; import java.sql.ResultSet; -public class DRawSqlBuilder implements RawSqlBuilder { +public final class DRawSqlBuilder implements RawSqlBuilder { private final ResultSet resultSet; - private final SpiRawSql.Sql sql; - private final SpiRawSql.ColumnMapping columnMapping; DRawSqlBuilder(SpiRawSql.Sql sql, SpiRawSql.ColumnMapping columnMapping) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlColumnsParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlColumnsParser.java index 74c02badd..48e61789b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlColumnsParser.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlColumnsParser.java @@ -17,7 +17,6 @@ final class DRawSqlColumnsParser { private static final Pattern COLINFO_SPLIT = Pattern.compile("\\s(?=[^\\)]*(?:\\(|$))"); private final String sqlSelect; - private int indexPos; public static ColumnMapping parse(String sqlSelect) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlParser.java index 0e46cbe10..033aa0755 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlParser.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlParser.java @@ -7,20 +7,15 @@ import io.ebeaninternal.server.rawsql.SpiRawSql.Sql; * Parses sql-select queries to try and determine the location where WHERE and * HAVING clauses can be added dynamically to the sql. */ -class DRawSqlParser { +final class DRawSqlParser { private static final String $_AND_HAVING = "${andHaving}"; - private static final String $_HAVING = "${having}"; - private static final String $_AND_WHERE = "${andWhere}"; - private static final String $_WHERE = "${where}"; private final SimpleTextParser textParser; - private String sql; - private int placeHolderWhere; private int placeHolderAndWhere; private int placeHolderHaving; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlService.java b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlService.java index 5a405dbc4..11b80da38 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlService.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlService.java @@ -11,7 +11,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; -public class DRawSqlService implements SpiRawSqlService { +final class DRawSqlService implements SpiRawSqlService { @Override public RawSql resultSet(ResultSet resultSet, String... propertyNames) { @@ -20,10 +20,8 @@ public class DRawSqlService implements SpiRawSqlService { @Override public RawSqlBuilder parsed(String sql) { - SpiRawSql.Sql sql2 = DRawSqlParser.parse(sql); String select = sql2.getPreFrom(); - SpiRawSql.ColumnMapping mapping = DRawSqlColumnsParser.parse(select); return new DRawSqlBuilder(sql2, mapping); } @@ -36,7 +34,6 @@ public class DRawSqlService implements SpiRawSqlService { @Override public SqlRow sqlRow(ResultSet resultSet, String dbTrueValue, boolean binaryOptimizedUUID) throws SQLException { - ResultSetMetaData meta = resultSet.getMetaData(); int estCap = (int) (meta.getColumnCount() / 0.7f) + 1; DefaultSqlRow ret = new DefaultSqlRow(estCap, 0.75f, dbTrueValue, binaryOptimizedUUID); @@ -77,7 +74,6 @@ public class DRawSqlService implements SpiRawSqlService { * Combine schema table and column names allowing for null schema and table. */ String combine(String schemaName, String tableName, String name) { - StringBuilder sb = new StringBuilder(); if (schemaName != null) { sb.append(schemaName).append("."); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonBeanReader.java b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonBeanReader.java index ecfa3af8c..8193d397c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonBeanReader.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonBeanReader.java @@ -15,10 +15,9 @@ import java.io.IOException; * This is used such that a load context and persistence context can be used to span multiple marshalling requests. *

*/ -public class DJsonBeanReader implements JsonBeanReader { +public final class DJsonBeanReader implements JsonBeanReader { private final BeanDescriptor desc; - private final SpiJsonReader readJson; public DJsonBeanReader(BeanDescriptor desc, SpiJsonReader readJson) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonContext.java b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonContext.java index 6a94bd31d..b0706173c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonContext.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonContext.java @@ -43,18 +43,14 @@ import java.util.Set; /** * Default implementation of JsonContext. */ -public class DJsonContext implements SpiJsonContext { +public final class DJsonContext implements SpiJsonContext { private static final PrettyPrinter PRETTY_PRINTER = new Pretty(); private final SpiEbeanServer server; - private final JsonFactory jsonFactory; - private final Object defaultObjectMapper; - private final JsonConfig.Include defaultInclude; - private final DJsonScalar jsonScalar; private static class Pretty extends DefaultPrettyPrinter { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonScalar.java b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonScalar.java index fed4c5945..d0ef82204 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonScalar.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/DJsonScalar.java @@ -10,7 +10,7 @@ import java.util.List; /** * Default implementation of JsonScalar. */ -public class DJsonScalar { +public final class DJsonScalar { private final TypeManager typeManager; @@ -20,7 +20,6 @@ public class DJsonScalar { @SuppressWarnings({ "unchecked", "rawtypes" }) public void write(JsonGenerator gen, Object value) throws IOException { - if (value instanceof String) { gen.writeString((String) value); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/PathStack.java b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/PathStack.java index 7da49f6ad..6cb3b2b67 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/PathStack.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/PathStack.java @@ -2,10 +2,9 @@ package io.ebeaninternal.server.text.json; import io.ebeaninternal.server.util.ArrayStack; -public class PathStack extends ArrayStack { +public final class PathStack extends ArrayStack { public String peekFullPath(String key) { - String prefix = peekWithNull(); if (prefix != null) { return prefix + "." + key; @@ -15,7 +14,6 @@ public class PathStack extends ArrayStack { } public void pushPathKey(String key) { - String prefix = peekWithNull(); if (prefix != null) { key = prefix + "." + key; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/ReadJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/ReadJson.java index 74c85a770..f685188b6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/ReadJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/ReadJson.java @@ -20,42 +20,28 @@ import java.util.Map; /** * Context for JSON read processing. */ -public class ReadJson implements SpiJsonReader { +public final class ReadJson implements SpiJsonReader { private final BeanDescriptor rootDesc; - - /** - * Jackson parser. - */ private final JsonParser parser; - - /** - * Stack of the path - used to find the appropriate JsonReadBeanVisitor. - */ private final PathStack pathStack; - /** * Map of the JsonReadBeanVisitor keyed by path. */ private final Map> visitorMap; - private final Object objectMapper; - private final PersistenceContext persistenceContext; - private final LoadContext loadContext; /** * Construct with parser and readOptions. */ public ReadJson(BeanDescriptor desc, JsonParser parser, JsonReadOptions readOptions, Object objectMapper) { - this.rootDesc = desc; this.parser = parser; this.objectMapper = objectMapper; this.persistenceContext = initPersistenceContext(readOptions); this.loadContext = initLoadContext(desc, readOptions); - // only create visitorMap, pathStack if needed ... this.visitorMap = (readOptions == null) ? null : readOptions.getVisitorMap(); this.pathStack = (visitorMap == null && loadContext == null) ? null : new PathStack(); @@ -119,7 +105,6 @@ public class ReadJson implements SpiJsonReader { */ @Override public void persistenceContextPut(Object beanId, T currentBean) { - persistenceContextPutIfAbsent(beanId, (EntityBean) currentBean, rootDesc); } @@ -129,16 +114,13 @@ public class ReadJson implements SpiJsonReader { */ @Override public Object persistenceContextPutIfAbsent(Object id, EntityBean bean, BeanDescriptor beanDesc) { - if (persistenceContext == null) { // no persistenceContext means no lazy loading either return null; } - Object existing = beanDesc.contextPutIfAbsent(persistenceContext, id, bean); if (existing != null) { beanDesc.merge(bean, (EntityBean) existing); - } else { if (loadContext != null) { EntityBeanIntercept ebi = bean._ebean_getIntercept(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/WriteJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/WriteJson.java index d7914f587..4ae521e16 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/text/json/WriteJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/text/json/WriteJson.java @@ -21,22 +21,15 @@ import java.util.Collection; import java.util.Map; import java.util.Set; -public class WriteJson implements SpiJsonWriter { +public final class WriteJson implements SpiJsonWriter { private final SpiEbeanServer server; - private final JsonGenerator generator; - private final FetchPath fetchPath; - private final Map> visitors; - private final PathStack pathStack; - private final ArrayStack parentBeans; - private final Object objectMapper; - private final JsonConfig.Include include; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/ArrayStack.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/ArrayStack.java index 9e1107ee5..8e824f664 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/ArrayStack.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/ArrayStack.java @@ -6,10 +6,8 @@ import java.util.List; /** * Stack based on ArrayList. - * - * @author rbygrave */ -public class ArrayStack { +public final class ArrayStack { private final List list; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/BindParamsParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/BindParamsParser.java index c7ae703d5..b28f6b80f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/BindParamsParser.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/BindParamsParser.java @@ -15,19 +15,16 @@ import java.util.Collection; * This is a thread safe implementation. *

*/ -public class BindParamsParser { +public final class BindParamsParser { private static final String ENCRYPTKEY_PREFIX = "encryptkey_"; private static final String ENCRYPTKEY_GAP = "___"; - private static final int ENCRYPTKEY_PREFIX_LEN = ENCRYPTKEY_PREFIX.length(); private static final int ENCRYPTKEY_GAP_LEN = ENCRYPTKEY_GAP.length(); - /** * Used to parse sql looking for named parameters. */ private static final String quote = "'"; - /** * Used to parse sql looking for named parameters. */ @@ -35,7 +32,6 @@ public class BindParamsParser { private final BindParams params; private final String sql; - private final BeanDescriptor beanDescriptor; public static String parse(BindParams params, String sql) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/DSelectColumnsParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/DSelectColumnsParser.java index b4ec33a67..9ec13815b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/DSelectColumnsParser.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/DSelectColumnsParser.java @@ -9,9 +9,7 @@ import java.util.Set; public final class DSelectColumnsParser { private final int end; - private final String selectClause; - private int pos; public static Set parse(String sqlSelect) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/Str.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/Str.java index 56788dc98..c49032c86 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/Str.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/Str.java @@ -5,7 +5,7 @@ package io.ebeaninternal.server.util; *

* Predicts a decent buffer size to append the strings into. */ -public class Str { +public final class Str { /** * Append strings together. diff --git a/ebean-core/src/main/java/io/ebeaninternal/util/ParamTypeHelper.java b/ebean-core/src/main/java/io/ebeaninternal/util/ParamTypeHelper.java index 85de3d4d5..68f8de4a4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/util/ParamTypeHelper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/util/ParamTypeHelper.java @@ -6,13 +6,13 @@ import java.util.List; import java.util.Map; import java.util.Set; -public class ParamTypeHelper { +public final class ParamTypeHelper { public enum ManyType { LIST, SET, MAP, NONE } - public static class TypeInfo { + public static final class TypeInfo { private final ManyType manyType; private final Class beanType; @@ -46,11 +46,9 @@ public class ParamTypeHelper { } public static TypeInfo getTypeInfo(Type genericType) { - if (genericType instanceof ParameterizedType) { return getParamTypeInfo((ParameterizedType) genericType); } - Class entityType = getBeanType(genericType); if (entityType != null) { return new TypeInfo(ManyType.NONE, entityType); @@ -62,16 +60,12 @@ public class ParamTypeHelper { * For Lists Sets and Maps of beans. */ private static TypeInfo getParamTypeInfo(ParameterizedType paramType) { - Type rawType = paramType.getRawType(); - ManyType manyType = getManyType(rawType); if (ManyType.NONE == manyType) { return null; } - Type[] typeArguments = paramType.getActualTypeArguments(); - if (typeArguments.length == 1) { Type argType = typeArguments[0]; Class beanType = getBeanType(argType); @@ -79,7 +73,6 @@ public class ParamTypeHelper { return new TypeInfo(manyType, beanType); } } - return null; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/util/SortByClause.java b/ebean-core/src/main/java/io/ebeaninternal/util/SortByClause.java index 02884990e..764e67b8a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/util/SortByClause.java +++ b/ebean-core/src/main/java/io/ebeaninternal/util/SortByClause.java @@ -10,23 +10,19 @@ import java.util.List; * Primarily used to support sorting of Lists. *

*/ -public class SortByClause { +public final class SortByClause { static final String NULLSHIGH = "nullshigh"; - static final String NULLSLOW = "nullslow"; - /** * The ascending keyword. */ static final String ASC = "asc"; - /** * The descending keyword. */ static final String DESC = "desc"; - private final List properties = new ArrayList<>(); /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/util/UrlHelper.java b/ebean-core/src/main/java/io/ebeaninternal/util/UrlHelper.java index 443273c6b..0779908c9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/util/UrlHelper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/util/UrlHelper.java @@ -8,13 +8,12 @@ import java.net.URLConnection; /** * Helper to open URL content without file descriptor caching (by underlying JDK JarURLConnection). */ -public class UrlHelper { +public final class UrlHelper { /** * Open the URL content without using caching returning the resulting InputStream. */ public static InputStream openNoCache(URL url) throws IOException { - URLConnection urlConnection = url.openConnection(); urlConnection.setUseCaches(false); return urlConnection.getInputStream(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/util/ValueUtil.java b/ebean-core/src/main/java/io/ebeaninternal/util/ValueUtil.java index a93da76cf..2cf7f73ba 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/util/ValueUtil.java +++ b/ebean-core/src/main/java/io/ebeaninternal/util/ValueUtil.java @@ -3,7 +3,7 @@ package io.ebeaninternal.util; import java.math.BigDecimal; import java.net.URL; -public class ValueUtil { +public final class ValueUtil { /** * Helper method to check if two objects are equal. diff --git a/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStore.java b/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStore.java index a7dda71d4..d4932791e 100644 --- a/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStore.java +++ b/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStore.java @@ -16,7 +16,7 @@ import java.util.function.Predicate; /** * DocumentStore that barfs it is used. */ -public class NoneDocStore implements DocumentStore { +public final class NoneDocStore implements DocumentStore { public static IllegalStateException implementationNotInClassPath() { throw new IllegalStateException("DocStore implementation not included in the classPath. You need to add the maven dependency for io.ebean:ebean-elastic"); diff --git a/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreBeanAdapter.java b/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreBeanAdapter.java index d187af169..2be5d1c13 100644 --- a/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreBeanAdapter.java +++ b/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreBeanAdapter.java @@ -12,7 +12,7 @@ import java.io.IOException; /** * DocStoreBeanBaseAdapter that barfs if it is used. */ -public class NoneDocStoreBeanAdapter extends DocStoreBeanBaseAdapter { +public final class NoneDocStoreBeanAdapter extends DocStoreBeanBaseAdapter { public NoneDocStoreBeanAdapter(BeanDescriptor desc, DeployBeanDescriptor deploy) { super(desc, deploy); diff --git a/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreFactory.java b/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreFactory.java index 7a9d18568..8f0244cb5 100644 --- a/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreFactory.java +++ b/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreFactory.java @@ -12,7 +12,7 @@ import io.ebeanservice.docstore.api.DocStoreUpdateProcessor; /** * A stub implementation of DocStoreFactory that will barf if the docStore features are used. */ -public class NoneDocStoreFactory implements DocStoreFactory { +public final class NoneDocStoreFactory implements DocStoreFactory { @Override public DocStoreIntegration create(SpiServer server) { @@ -24,7 +24,7 @@ public class NoneDocStoreFactory implements DocStoreFactory { return new NoneDocStoreBeanAdapter<>(desc, deploy); } - static class NoneIntegration implements DocStoreIntegration { + static final class NoneIntegration implements DocStoreIntegration { @Override public DocStoreUpdateProcessor updateProcessor() { diff --git a/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreUpdateProcessor.java b/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreUpdateProcessor.java index c5c3d7854..b6a642718 100644 --- a/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreUpdateProcessor.java +++ b/ebean-core/src/main/java/io/ebeanservice/docstore/none/NoneDocStoreUpdateProcessor.java @@ -11,7 +11,7 @@ import java.io.IOException; /** * DocStoreUpdateProcessor that barfs if it is used. */ -class NoneDocStoreUpdateProcessor implements DocStoreUpdateProcessor { +final class NoneDocStoreUpdateProcessor implements DocStoreUpdateProcessor { @Override public DocStoreQueryUpdate createQueryUpdate(BeanType beanType, int bulkBatchSize) throws IOException { From 16a05528b76a3e1c96d8449e2c1f40c23a062160 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 17 Aug 2021 19:00:55 +1200 Subject: [PATCH 107/120] #2318 - Refactor internals - final classes in deploy packages etc --- .../deploy/AssocOneHelpRefExported.java | 2 +- .../server/deploy/AssocOneHelpRefInherit.java | 2 +- .../server/deploy/AssocOneHelpRefSimple.java | 2 +- .../server/deploy/BeanCascadeInfo.java | 2 +- .../server/deploy/BeanChangeJson.java | 5 +--- .../deploy/BeanCollectionHelpFactory.java | 7 ++---- .../server/deploy/BeanCollectionUtil.java | 3 +-- .../server/deploy/BeanDescriptorJsonHelp.java | 14 +---------- .../server/deploy/BeanDescriptorManager.java | 2 +- .../server/deploy/BeanEmbeddedMeta.java | 3 +-- .../deploy/BeanEmbeddedMetaFactory.java | 2 +- .../server/deploy/BeanFinderManager.java | 2 +- .../server/deploy/BeanFkeyProperty.java | 1 - .../server/deploy/BeanIudMetrics.java | 3 +-- .../deploy/BeanLifecycleAdapterFactory.java | 16 +++++-------- .../server/deploy/BeanListHelpElement.java | 2 +- .../server/deploy/BeanManager.java | 3 +-- .../server/deploy/BeanManagerFactory.java | 2 +- .../server/deploy/BeanMapHelpElement.java | 2 +- .../server/deploy/BeanMapQueryHelp.java | 2 +- .../server/deploy/BeanNaturalKey.java | 2 +- .../server/deploy/BeanPropertyIdClass.java | 2 +- .../deploy/BeanPropertyOrderColumn.java | 2 +- .../server/deploy/BeanPropertyOverride.java | 2 +- .../deploy/BeanPropertySimpleCollection.java | 2 +- .../deploy/BeanQueryAdapterManager.java | 2 +- .../server/deploy/BeanSetHelpElement.java | 2 +- .../server/deploy/BeanTable.java | 8 +------ .../deploy/ChainedBeanPersistController.java | 2 +- .../deploy/ChainedBeanPersistListener.java | 3 +-- .../ChainedBeanPostConstructListener.java | 3 +-- .../server/deploy/ChainedBeanPostLoad.java | 3 +-- .../deploy/ChainedBeanQueryAdapter.java | 3 +-- .../server/deploy/DCacheControl.java | 2 +- .../server/deploy/DCacheControlNone.java | 2 +- .../server/deploy/DCacheRegion.java | 2 +- .../server/deploy/DCacheRegionNone.java | 2 +- .../server/deploy/DbMigrationInfo.java | 2 +- .../deploy/DeployDocPropertyOptions.java | 5 +--- .../server/deploy/DetermineAggPath.java | 2 +- .../server/deploy/DetermineManyType.java | 5 +--- .../DynamicPropertyAggregationFormulaMTO.java | 2 +- .../server/deploy/ElementEntityBean.java | 4 +--- .../server/deploy/ElementHelpList.java | 2 +- .../server/deploy/ElementHelpMap.java | 2 +- .../server/deploy/ElementHelpSet.java | 2 +- .../server/deploy/ExportedProperty.java | 4 +--- .../server/deploy/IdentityMode.java | 2 +- .../server/deploy/IndexDefinition.java | 2 +- .../server/deploy/InheritInfo.java | 24 +------------------ .../server/deploy/IntersectionBuilder.java | 2 +- .../server/deploy/IntersectionRow.java | 5 +--- .../server/deploy/IntersectionTable.java | 2 +- .../server/deploy/PartitionMeta.java | 3 +-- .../deploy/PersistControllerManager.java | 2 +- .../server/deploy/PersistListenerManager.java | 2 +- .../server/deploy/PersistenceContextUtil.java | 2 +- .../server/deploy/PostConstructManager.java | 2 +- .../server/deploy/PostLoadManager.java | 2 +- .../server/deploy/PropertyForeignKey.java | 2 +- .../server/deploy/TableJoinColumn.java | 2 +- .../meta/BeanPropertyElementSetter.java | 2 +- .../deploy/meta/DeployBeanEmbedded.java | 2 +- .../deploy/meta/DeployBeanObtainJackson.java | 2 +- .../meta/DeployBeanPropertyAssocOne.java | 2 +- .../deploy/meta/DeployBeanPropertyLists.java | 2 +- .../DeployBeanPropertySimpleCollection.java | 2 +- .../server/deploy/meta/DeployBeanTable.java | 2 +- .../deploy/meta/DeployIdentityMode.java | 2 +- .../server/deploy/meta/DeployOrderColumn.java | 2 +- .../server/deploy/meta/DeployTableJoin.java | 8 +++---- .../deploy/meta/DeployTableJoinColumn.java | 2 +- .../deploy/parse/AnnotationAssocManys.java | 2 +- .../deploy/parse/AnnotationAssocOnes.java | 2 +- .../server/deploy/parse/AnnotationClass.java | 2 +- .../server/deploy/parse/AnnotationFields.java | 2 +- .../server/deploy/parse/AnnotationFind.java | 2 +- .../server/deploy/parse/AnnotationSql.java | 2 +- .../server/deploy/parse/DeployBeanInfo.java | 2 +- .../deploy/parse/DeployCreateProperties.java | 2 +- .../server/deploy/parse/DeployInherit.java | 2 +- .../deploy/parse/DeployInheritInfo.java | 2 +- .../server/deploy/parse/DeployUtil.java | 2 +- .../parse/InitMetaJacksonAnnotation.java | 2 +- .../deploy/parse/ReadAnnotationConfig.java | 2 +- .../server/deploy/parse/ReadAnnotations.java | 2 +- .../ReadValidationAnnotationsJakarta.java | 2 +- .../parse/ReadValidationAnnotationsJavax.java | 2 +- .../deploy/parse/TransientProperties.java | 8 +------ .../server/rawsql/DRawSqlService.java | 2 +- .../ebeaninternal/server/util/ArrayStack.java | 2 +- .../deploy/parse/AnnotationClassTest.java | 9 ++++--- .../model/visitor/VisitAllUsing.java | 2 +- 93 files changed, 106 insertions(+), 182 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefExported.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefExported.java index 874231645..0aad172c3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefExported.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefExported.java @@ -5,7 +5,7 @@ import io.ebeaninternal.server.query.SqlJoinType; /** * Helper for BeanPropertyAssocOne for OneToOne exported reference - not so common. */ -class AssocOneHelpRefExported extends AssocOneHelp { +final class AssocOneHelpRefExported extends AssocOneHelp { private final boolean softDelete; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefInherit.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefInherit.java index 1d619507b..7204a2cf1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefInherit.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefInherit.java @@ -9,7 +9,7 @@ import java.sql.SQLException; /** * Helper for BeanPropertyAssocOne imported reference but with inheritance. */ -class AssocOneHelpRefInherit extends AssocOneHelp { +final class AssocOneHelpRefInherit extends AssocOneHelp { private final InheritInfo inherit; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefSimple.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefSimple.java index 967d7d492..cf6b09798 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefSimple.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/AssocOneHelpRefSimple.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.deploy; /** * Helper for BeanPropertyAssocOne imported reference - this is the common case. */ -class AssocOneHelpRefSimple extends AssocOneHelp { +final class AssocOneHelpRefSimple extends AssocOneHelp { AssocOneHelpRefSimple(BeanPropertyAssocOne property, String embeddedPrefix) { super(property, embeddedPrefix); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCascadeInfo.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCascadeInfo.java index 36b7b2152..c5df36975 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCascadeInfo.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCascadeInfo.java @@ -8,7 +8,7 @@ import javax.persistence.CascadeType; * This is set to associated Beans, Table joins and List. *

*/ -public class BeanCascadeInfo { +public final class BeanCascadeInfo { private boolean delete; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanChangeJson.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanChangeJson.java index e2a6938ff..2e9b9cc69 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanChangeJson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanChangeJson.java @@ -11,16 +11,13 @@ import java.io.StringWriter; /** * Builds the 'new values' and 'old values' in JSON form for ChangeLog. */ -class BeanChangeJson implements BeanDiffVisitor { +final class BeanChangeJson implements BeanDiffVisitor { private final StringWriter newData; private final StringWriter oldData; - private final SpiJsonWriter newJson; private final SpiJsonWriter oldJson; - private final ArrayStack> stack = new ArrayStack<>(); - private BeanDescriptor descriptor; BeanChangeJson(BeanDescriptor descriptor, boolean statelessUpdate) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionHelpFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionHelpFactory.java index a3376cd2e..e46bd2908 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionHelpFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionHelpFactory.java @@ -9,7 +9,7 @@ import io.ebeaninternal.server.query.CQueryCollectionAdd; /** * Creates Helpers specific to the type of the property (List Set or Map). */ -public class BeanCollectionHelpFactory { +public final class BeanCollectionHelpFactory { @SuppressWarnings("rawtypes") private static final BeanListHelp LIST_HELP = new BeanListHelp(); @@ -21,7 +21,6 @@ public class BeanCollectionHelpFactory { * Create the helper based on the many property. */ public static BeanCollectionHelp create(BeanPropertyAssocMany many) { - boolean elementCollection = many.isElementCollection(); ManyType manyType = many.getManyType(); switch (manyType) { @@ -30,7 +29,7 @@ public class BeanCollectionHelpFactory { case SET: return elementCollection ? new BeanSetHelpElement<>(many) : new BeanSetHelp<>(many); case MAP: - return elementCollection ? new BeanMapHelpElement<>(many) :new BeanMapHelp<>(many); + return elementCollection ? new BeanMapHelpElement<>(many) : new BeanMapHelp<>(many); default: throw new RuntimeException("Invalid type " + manyType); } @@ -39,7 +38,6 @@ public class BeanCollectionHelpFactory { @SuppressWarnings("unchecked") public static CQueryCollectionAdd create(SpiQuery.Type manyType, OrmQueryRequest request) { - if (manyType == SpiQuery.Type.LIST) { return LIST_HELP; @@ -56,5 +54,4 @@ public class BeanCollectionHelpFactory { } } - } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionUtil.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionUtil.java index e632a729c..e1a0d352c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionUtil.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanCollectionUtil.java @@ -9,7 +9,7 @@ import java.util.Map; /** * Utility methods for BeanCollections. */ -public class BeanCollectionUtil { +public final class BeanCollectionUtil { /** * Return true if this is a bean collection and not considered dirty. @@ -66,7 +66,6 @@ public class BeanCollectionUtil { // returns a collection of beans return bc.getActualDetails(); } - if (o instanceof Map) { // yes, we want the entrySet (to set the keys) return ((Map) o).values(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorJsonHelp.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorJsonHelp.java index 059b368a0..d9b56f215 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorJsonHelp.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorJsonHelp.java @@ -16,10 +16,9 @@ import java.util.Map; import static io.ebeaninternal.server.persist.DmlUtil.isNullOrZero; -class BeanDescriptorJsonHelp { +final class BeanDescriptorJsonHelp { private final BeanDescriptor desc; - private final InheritInfo inheritInfo; BeanDescriptorJsonHelp(BeanDescriptor desc) { @@ -28,21 +27,16 @@ class BeanDescriptorJsonHelp { } void jsonWrite(SpiJsonWriter writeJson, EntityBean bean, String key) throws IOException { - writeJson.writeStartObject(key); - if (inheritInfo == null) { jsonWriteProperties(writeJson, bean); - } else { InheritInfo localInheritInfo = inheritInfo.readType(bean.getClass()); String discValue = localInheritInfo.getDiscriminatorStringValue(); String discColumn = localInheritInfo.getDiscriminatorColumn(); writeJson.gen().writeStringField(discColumn, discValue); - localInheritInfo.desc().jsonWriteProperties(writeJson, bean); } - writeJson.writeEndObject(); } @@ -59,7 +53,6 @@ class BeanDescriptorJsonHelp { } void jsonWriteDirtyProperties(SpiJsonWriter writeJson, EntityBean bean, boolean[] dirtyProps) throws IOException { - writeJson.writeStartObject(null); // render the dirty properties BeanProperty[] props = desc.propertiesNonTransient(); @@ -73,7 +66,6 @@ class BeanDescriptorJsonHelp { @SuppressWarnings("unchecked") T jsonRead(SpiJsonReader jsonRead, String path, boolean withInheritance) throws IOException { - JsonParser parser = jsonRead.getParser(); //noinspection StatementWithEmptyBody if (parser.getCurrentToken() == JsonToken.START_OBJECT) { @@ -115,21 +107,17 @@ class BeanDescriptorJsonHelp { } private T jsonReadObject(SpiJsonReader readJson, String path) throws IOException { - EntityBean bean = desc.createEntityBeanForJson(); return jsonReadProperties(readJson, bean, path); } @SuppressWarnings("unchecked") private T jsonReadProperties(SpiJsonReader readJson, EntityBean bean, String path) throws IOException { - if (path != null) { readJson.pushPath(path); } - // unmapped properties, send to JsonReadBeanVisitor later Map unmappedProperties = null; - do { JsonParser parser = readJson.getParser(); JsonToken event = parser.nextToken(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java index 84b412513..ef1117659 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java @@ -86,7 +86,7 @@ import java.util.concurrent.TimeUnit; /** * Creates BeanDescriptors. */ -public class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTypeManager { +public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTypeManager { private static final Logger logger = LoggerFactory.getLogger(BeanDescriptorManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMeta.java index cac179b62..57aed6cb3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMeta.java @@ -1,7 +1,6 @@ package io.ebeaninternal.server.deploy; -public class BeanEmbeddedMeta { - +public final class BeanEmbeddedMeta { private final BeanProperty[] properties; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMetaFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMetaFactory.java index 5def0dc64..d6ee56491 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMetaFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanEmbeddedMetaFactory.java @@ -10,7 +10,7 @@ import java.util.Map; * Creates BeanProperties for Embedded beans that have deployment information * such as the actual DB column name and table alias. */ -class BeanEmbeddedMetaFactory { +final class BeanEmbeddedMetaFactory { /** * Create BeanProperties for embedded beans using the deployment specific DB column name and table alias. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanFinderManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanFinderManager.java index a1e916310..bb85c3b76 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanFinderManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanFinderManager.java @@ -11,7 +11,7 @@ import java.util.List; /** * Default implementation for BeanFinderFactory. */ -class BeanFinderManager { +final class BeanFinderManager { private final Logger logger = LoggerFactory.getLogger(BeanFinderManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanFkeyProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanFkeyProperty.java index e651e7fc2..071a0f660 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanFkeyProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanFkeyProperty.java @@ -16,7 +16,6 @@ public final class BeanFkeyProperty implements ElPropertyValue { private final String name; private final String dbColumn; private final boolean containsMany; - private final int deployOrder; public BeanFkeyProperty(String name, String dbColumn, int deployOrder) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanIudMetrics.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanIudMetrics.java index 889716aa3..64e4deb8f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanIudMetrics.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanIudMetrics.java @@ -8,7 +8,7 @@ import io.ebeaninternal.server.core.PersistRequest; /** * Metrics for ORM Insert Update and Delete for a given bean type. */ -class BeanIudMetrics { +final class BeanIudMetrics { private final TimedMetric insert; private final TimedMetric update; @@ -21,7 +21,6 @@ class BeanIudMetrics { * Create for a given bean type. */ BeanIudMetrics(String beanShortName) { - MetricFactory metricFactory = MetricFactory.get(); String prefix = "iud." + beanShortName; this.insert = metricFactory.createTimedMetric(prefix + ".insert"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanLifecycleAdapterFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanLifecycleAdapterFactory.java index 7a581e1c8..f754c9060 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanLifecycleAdapterFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanLifecycleAdapterFactory.java @@ -30,7 +30,7 @@ import java.util.List; * lifecycle events. *

*/ -class BeanLifecycleAdapterFactory { +final class BeanLifecycleAdapterFactory { private final boolean postConstructPresent; @@ -42,20 +42,16 @@ class BeanLifecycleAdapterFactory { * Register a BeanPersistController for methods annotated with lifecycle events. */ void addLifecycleMethods(DeployBeanDescriptor deployDesc) { - Method[] methods = deployDesc.getBeanType().getMethods(); - // look for annotated methods MethodsHolder methodHolder = new MethodsHolder(); for (Method m : methods) { methodHolder.checkMethod(m, postConstructPresent); } - if (methodHolder.hasPersistMethods()) { // has pre/post persist annotated methods deployDesc.addPersistController(new PersistAdapter(new PersistMethodsHolder(methodHolder))); } - if (!methodHolder.postLoads.isEmpty()) { // has postLoad methods deployDesc.addPostLoad(new PostLoadAdapter(methodHolder.postLoads)); @@ -69,7 +65,7 @@ class BeanLifecycleAdapterFactory { /** * Holds Methods for the lifecycle events.s */ - private static class MethodsHolder { + private static final class MethodsHolder { private boolean hasPersistMethods; private final List preInserts = new ArrayList<>(); @@ -162,7 +158,7 @@ class BeanLifecycleAdapterFactory { /** * Holds Methods for the lifecycle events.s */ - private static class PersistMethodsHolder { + private static final class PersistMethodsHolder { private final Method[] preInserts; private final Method[] postInserts; @@ -188,7 +184,7 @@ class BeanLifecycleAdapterFactory { /** * BeanPersistAdapter using reflection to invoke lifecycle methods. */ - private static class PersistAdapter extends BeanPersistAdapter { + private static final class PersistAdapter extends BeanPersistAdapter { private final PersistMethodsHolder methodHolder; @@ -264,7 +260,7 @@ class BeanLifecycleAdapterFactory { /** * BeanPostLoad using reflection to invoke lifecycle methods. */ - private static class PostLoadAdapter implements BeanPostLoad { + private static final class PostLoadAdapter implements BeanPostLoad { private final Method[] postLoadMethods; @@ -297,7 +293,7 @@ class BeanLifecycleAdapterFactory { /** * PostConstructAdapter using reflection to invoke lifecycle methods. */ - private static class PostConstructAdapter implements BeanPostConstructListener { + private static final class PostConstructAdapter implements BeanPostConstructListener { private final Method[] postConstructMethods; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanListHelpElement.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanListHelpElement.java index 0e473e4eb..b5f3ae432 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanListHelpElement.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanListHelpElement.java @@ -7,7 +7,7 @@ import io.ebeaninternal.api.json.SpiJsonWriter; /** * Helper for element collection List. */ -public class BeanListHelpElement extends BeanListHelp { +public final class BeanListHelpElement extends BeanListHelp { BeanListHelpElement(BeanPropertyAssocMany many) { super(many); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanManager.java index 630c60b4e..d6d605313 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanManager.java @@ -5,10 +5,9 @@ import io.ebeaninternal.server.persist.BeanPersister; /** * Holds the BeanDescriptor and its associated BeanPersister. */ -public class BeanManager { +public final class BeanManager { private final BeanPersister persister; - private final BeanDescriptor descriptor; public BeanManager(BeanDescriptor descriptor, BeanPersister persister) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanManagerFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanManagerFactory.java index e80cff573..3f2f61e14 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanManagerFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanManagerFactory.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.persist.dml.DmlBeanPersisterFactory; /** * Creates BeanManagers. */ -class BeanManagerFactory { +final class BeanManagerFactory { private final BeanPersisterFactory persisterFactory; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanMapHelpElement.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanMapHelpElement.java index 71cdfb3fa..1c6fb7931 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanMapHelpElement.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanMapHelpElement.java @@ -5,7 +5,7 @@ import io.ebean.bean.EntityBean; import io.ebean.common.BeanMap; import io.ebeaninternal.api.json.SpiJsonWriter; -public class BeanMapHelpElement extends BeanMapHelp { +public final class BeanMapHelpElement extends BeanMapHelp { BeanMapHelpElement(BeanPropertyAssocMany many) { super(many); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanMapQueryHelp.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanMapQueryHelp.java index e78381b0b..b2e4f0f7d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanMapQueryHelp.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanMapQueryHelp.java @@ -6,7 +6,7 @@ import io.ebean.common.BeanMap; import io.ebeaninternal.server.el.ElPropertyValue; import io.ebeaninternal.server.query.CQueryCollectionAdd; -class BeanMapQueryHelp implements CQueryCollectionAdd { +final class BeanMapQueryHelp implements CQueryCollectionAdd { private final ElPropertyValue elGetValue; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanNaturalKey.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanNaturalKey.java index 57f6c2512..3d3ed9866 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanNaturalKey.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanNaturalKey.java @@ -6,7 +6,7 @@ import java.util.Set; /** * Natural key for a bean type. */ -public class BeanNaturalKey { +public final class BeanNaturalKey { private final String[] naturalKey; private final BeanProperty[] props; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyIdClass.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyIdClass.java index 45d3614c3..9e0d61684 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyIdClass.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyIdClass.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne; /** * Bean property for an IdClass embeddedId. */ -public class BeanPropertyIdClass extends BeanPropertyAssocOne { +public final class BeanPropertyIdClass extends BeanPropertyAssocOne { @SuppressWarnings("unchecked") public BeanPropertyIdClass(BeanDescriptorMap owner, BeanDescriptor descriptor, DeployBeanPropertyAssocOne deploy) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyOrderColumn.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyOrderColumn.java index 319c8830b..a6ac913b9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyOrderColumn.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyOrderColumn.java @@ -8,7 +8,7 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; * * The value of which is held on the entity bean intercept. */ -public class BeanPropertyOrderColumn extends BeanProperty { +public final class BeanPropertyOrderColumn extends BeanProperty { public BeanPropertyOrderColumn(BeanDescriptor descriptor, DeployBeanProperty deploy) { super(descriptor, deploy); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyOverride.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyOverride.java index d322c5074..fd938d0d2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyOverride.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyOverride.java @@ -9,7 +9,7 @@ import io.ebeaninternal.server.core.InternString; * Typically this is for Embedded Beans. *

*/ -class BeanPropertyOverride { +final class BeanPropertyOverride { private final String dbColumn; private final boolean dbNullable; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertySimpleCollection.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertySimpleCollection.java index d73574379..2fbf41dcc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertySimpleCollection.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanPropertySimpleCollection.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanPropertySimpleCollection; import java.io.IOException; -public class BeanPropertySimpleCollection extends BeanPropertyAssocMany { +public final class BeanPropertySimpleCollection extends BeanPropertyAssocMany { public BeanPropertySimpleCollection(BeanDescriptor descriptor, DeployBeanPropertySimpleCollection deploy) { super(descriptor, deploy); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanQueryAdapterManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanQueryAdapterManager.java index 7a50f2deb..2f8f05317 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanQueryAdapterManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanQueryAdapterManager.java @@ -11,7 +11,7 @@ import java.util.List; /** * Default implementation for creating BeanControllers. */ -class BeanQueryAdapterManager { +final class BeanQueryAdapterManager { private static final Logger logger = LoggerFactory.getLogger(BeanQueryAdapterManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelpElement.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelpElement.java index 94ac9e5a5..2201d69aa 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelpElement.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanSetHelpElement.java @@ -7,7 +7,7 @@ import io.ebeaninternal.api.json.SpiJsonWriter; /** * Helper for element collection List. */ -public class BeanSetHelpElement extends BeanSetHelp { +public final class BeanSetHelpElement extends BeanSetHelp { BeanSetHelpElement(BeanPropertyAssocMany many) { super(many); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanTable.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanTable.java index f2cc09e78..3ccdb8218 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanTable.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/BeanTable.java @@ -17,19 +17,13 @@ import org.slf4j.LoggerFactory; * in a BeanDescriptor. *

*/ -public class BeanTable { +public final class BeanTable { private static final Logger logger = LoggerFactory.getLogger(BeanTable.class); private final BeanDescriptorMap owner; - private final Class beanType; - - /** - * The base table. - */ private final String baseTable; - private final BeanProperty idProperty; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistController.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistController.java index 404336aca..dfb2c302a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistController.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistController.java @@ -14,7 +14,7 @@ import java.util.List; *

* Used when multiple BeanPersistController register for the same bean type. */ -public class ChainedBeanPersistController implements BeanPersistController { +public final class ChainedBeanPersistController implements BeanPersistController { private static final Sorter SORTER = new Sorter(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistListener.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistListener.java index b92aa4ec7..d49380577 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistListener.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPersistListener.java @@ -9,10 +9,9 @@ import java.util.Set; /** * Handles multiple BeanPersistListener's for a given entity type. */ -public class ChainedBeanPersistListener implements BeanPersistListener { +public final class ChainedBeanPersistListener implements BeanPersistListener { private final List list; - private final BeanPersistListener[] chain; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPostConstructListener.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPostConstructListener.java index e9ba81c95..c615f8b20 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPostConstructListener.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPostConstructListener.java @@ -8,10 +8,9 @@ import java.util.List; /** * Handles multiple BeanPostLoad's for a given entity type. */ -public class ChainedBeanPostConstructListener implements BeanPostConstructListener { +public final class ChainedBeanPostConstructListener implements BeanPostConstructListener { private final List list; - private final BeanPostConstructListener[] chain; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPostLoad.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPostLoad.java index 9da1fdd66..4d7cff8ef 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPostLoad.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanPostLoad.java @@ -8,10 +8,9 @@ import java.util.List; /** * Handles multiple BeanPostLoad's for a given entity type. */ -public class ChainedBeanPostLoad implements BeanPostLoad { +public final class ChainedBeanPostLoad implements BeanPostLoad { private final List list; - private final BeanPostLoad[] chain; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanQueryAdapter.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanQueryAdapter.java index 15501ef0e..ca67a0746 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanQueryAdapter.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ChainedBeanQueryAdapter.java @@ -11,12 +11,11 @@ import java.util.List; /** * Handles multiple BeanQueryAdapter for a given entity type. */ -public class ChainedBeanQueryAdapter implements BeanQueryAdapter { +public final class ChainedBeanQueryAdapter implements BeanQueryAdapter { private static final Sorter SORTER = new Sorter(); private final List list; - private final BeanQueryAdapter[] chain; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheControl.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheControl.java index a99dabf89..a43f9f749 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheControl.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheControl.java @@ -6,7 +6,7 @@ import io.ebeaninternal.api.SpiCacheRegion; /** * Default implementation of SpiCacheControl. */ -class DCacheControl implements SpiCacheControl { +final class DCacheControl implements SpiCacheControl { private final SpiCacheRegion region; private final boolean bean; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheControlNone.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheControlNone.java index 8f4797f47..1101c180b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheControlNone.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheControlNone.java @@ -5,7 +5,7 @@ import io.ebeaninternal.api.SpiCacheControl; /** * Cache control used when no caching is on the bean type. */ -class DCacheControlNone implements SpiCacheControl { +final class DCacheControlNone implements SpiCacheControl { static final SpiCacheControl INSTANCE = new DCacheControlNone(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheRegion.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheRegion.java index 2056833b7..9f1bd5d59 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheRegion.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheRegion.java @@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy; import io.ebeaninternal.api.SpiCacheRegion; -public class DCacheRegion implements SpiCacheRegion { +public final class DCacheRegion implements SpiCacheRegion { private boolean enabled = true; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheRegionNone.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheRegionNone.java index ff8dfeb17..c7b20095a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheRegionNone.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DCacheRegionNone.java @@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy; import io.ebeaninternal.api.SpiCacheRegion; -class DCacheRegionNone implements SpiCacheRegion { +final class DCacheRegionNone implements SpiCacheRegion { static final SpiCacheRegion INSTANCE = new DCacheRegionNone(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DbMigrationInfo.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DbMigrationInfo.java index 630ea953b..e6e4a3eef 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DbMigrationInfo.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DbMigrationInfo.java @@ -10,7 +10,7 @@ import io.ebean.annotation.Platform; * * @author Roland Praml, FOCONIS AG */ -public class DbMigrationInfo { +public final class DbMigrationInfo { private final List preAdd; private final List postAdd; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DeployDocPropertyOptions.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DeployDocPropertyOptions.java index 81d8ea3f8..e6e00b2e9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DeployDocPropertyOptions.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DeployDocPropertyOptions.java @@ -8,7 +8,7 @@ import io.ebeanservice.docstore.api.mapping.DocPropertyOptions; /** * The options for document property collected when reading deployment mapping. */ -public class DeployDocPropertyOptions { +public final class DeployDocPropertyOptions { private static final DocPropertyOptions EMPTY = new DocPropertyOptions(); @@ -24,7 +24,6 @@ public class DeployDocPropertyOptions { * Read the DocProperty deployment options. */ public void setDocProperty(DocProperty doc) { - createOptions(); mapping.apply(doc); } @@ -33,7 +32,6 @@ public class DeployDocPropertyOptions { * Read the DocSortable deployment options. */ public void setDocSortable(DocSortable doc) { - createOptions(); mapping.setSortable(true); setStore(doc.store()); @@ -45,7 +43,6 @@ public class DeployDocPropertyOptions { * Read the DocCode deployment options. */ public void setDocCode(DocCode doc) { - createOptions(); mapping.setCode(true); setStore(doc.store()); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DetermineAggPath.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DetermineAggPath.java index c2e576b0c..5790377db 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DetermineAggPath.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DetermineAggPath.java @@ -5,7 +5,7 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanProperty; import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocMany; import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne; -class DetermineAggPath { +final class DetermineAggPath { /** * Return the many path for the given aggregation formula. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DetermineManyType.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DetermineManyType.java index cfa560310..fc1859074 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DetermineManyType.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DetermineManyType.java @@ -7,10 +7,7 @@ import java.util.Set; /** * Determine the Many Type for a property. */ -public class DetermineManyType { - - public DetermineManyType() { - } +public final class DetermineManyType { public ManyType getManyType(Class type) { if (type.equals(List.class)) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DynamicPropertyAggregationFormulaMTO.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DynamicPropertyAggregationFormulaMTO.java index eb8ba9997..0021d9636 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DynamicPropertyAggregationFormulaMTO.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/DynamicPropertyAggregationFormulaMTO.java @@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy; import io.ebeaninternal.server.query.SqlBeanLoad; -public class DynamicPropertyAggregationFormulaMTO extends DynamicPropertyAggregationFormula { +public final class DynamicPropertyAggregationFormulaMTO extends DynamicPropertyAggregationFormula { private final BeanPropertyAssocOne prop; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementEntityBean.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementEntityBean.java index 49dfccdc8..2f6566bff 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementEntityBean.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementEntityBean.java @@ -3,14 +3,12 @@ package io.ebeaninternal.server.deploy; import io.ebean.bean.EntityBean; import io.ebean.bean.EntityBeanIntercept; -class ElementEntityBean implements EntityBean { +final class ElementEntityBean implements EntityBean { private static final long serialVersionUID = 8742536671024715601L; private final String[] properties; - private Object[] data; - private final EntityBeanIntercept intercept; ElementEntityBean(String[] properties) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpList.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpList.java index 5c48b4f19..a9e38699e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpList.java @@ -6,7 +6,7 @@ import io.ebean.common.BeanList; import java.util.ArrayList; import java.util.List; -class ElementHelpList implements ElementHelp { +final class ElementHelpList implements ElementHelp { @Override public ElementCollector createCollector() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpMap.java index 985ab4248..e00d2ef2f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpMap.java @@ -6,7 +6,7 @@ import io.ebean.common.BeanMap; import java.util.LinkedHashMap; import java.util.Map; -class ElementHelpMap implements ElementHelp { +final class ElementHelpMap implements ElementHelp { @Override public ElementCollector createCollector() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpSet.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpSet.java index 71c15aee3..e15e74e28 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpSet.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ElementHelpSet.java @@ -6,7 +6,7 @@ import io.ebean.common.BeanSet; import java.util.LinkedHashSet; import java.util.Set; -class ElementHelpSet implements ElementHelp { +final class ElementHelpSet implements ElementHelp { @Override public ElementCollector createCollector() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ExportedProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ExportedProperty.java index 8c4b789ab..b8ec305a4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ExportedProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/ExportedProperty.java @@ -9,12 +9,10 @@ import io.ebeaninternal.server.core.InternString; * Used to for Assoc Manys to create references etc. *

*/ -class ExportedProperty { +final class ExportedProperty { private final String foreignDbColumn; - private final BeanProperty property; - private final boolean embedded; ExportedProperty(boolean embedded, String foreignDbColumn, BeanProperty property) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IdentityMode.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IdentityMode.java index 0bea99393..9ffd2c2e5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IdentityMode.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IdentityMode.java @@ -4,7 +4,7 @@ import io.ebean.annotation.IdentityGenerated; import io.ebean.config.dbplatform.IdType; import io.ebeaninternal.server.deploy.meta.DeployIdentityMode; -public class IdentityMode { +public final class IdentityMode { public static IdentityMode NONE = new IdentityMode(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IndexDefinition.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IndexDefinition.java index 3fec7ecf4..032452574 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IndexDefinition.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IndexDefinition.java @@ -5,7 +5,7 @@ import io.ebean.annotation.Platform; /** * Holds multiple column unique constraints defined for an entity. */ -public class IndexDefinition { +public final class IndexDefinition { private final String[] columns; private final String name; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/InheritInfo.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/InheritInfo.java index a8a733a41..1f3e33797 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/InheritInfo.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/InheritInfo.java @@ -17,43 +17,30 @@ import java.util.Set; /** * Represents a node in the Inheritance tree. Holds information regarding Super Subclass support. */ -public class InheritInfo { +public final class InheritInfo { private final String discriminatorStringValue; private final Object discriminatorValue; - private final String discriminatorColumn; - private final int discriminatorType; - private final int discriminatorLength; - private final String columnDefn; - private final String where; - private final Class type; - private final List children = new ArrayList<>(); - /** * Map of discriminator values to InheritInfo. */ private final HashMap discMap; - /** * Map of class types to InheritInfo (taking into account subclass proxy classes). */ private final HashMap typeMap; - private final InheritInfo parent; - private final InheritInfo root; - private BeanDescriptor descriptor; public InheritInfo(InheritInfo r, InheritInfo parent, DeployInheritInfo deploy) { - this.parent = parent; this.type = deploy.getType(); this.discriminatorColumn = InternString.intern(deploy.getColumnName(parent)); @@ -85,7 +72,6 @@ public class InheritInfo { * Visit all the children in the inheritance tree. */ public void visitChildren(InheritInfoVisitor visitor) { - for (InheritInfo child : children) { visitor.visit(child); child.visitChildren(visitor); @@ -96,7 +82,6 @@ public class InheritInfo { * Append check constraint values for the entire inheritance hierarchy. */ public void appendCheckConstraintValues(final String propertyName, final Set checkConstraintValues) { - visitChildren(inheritInfo -> { BeanProperty prop = inheritInfo.desc().getBeanProperty(propertyName); if (prop != null) { @@ -190,9 +175,7 @@ public class InheritInfo { * Get the bean property additionally looking in the sub types. */ BeanProperty findSubTypeProperty(String propertyName) { - BeanProperty prop; - for (InheritInfo childInfo : children) { // recursively search this child bean descriptor prop = childInfo.desc().findProperty(propertyName); @@ -200,7 +183,6 @@ public class InheritInfo { return prop; } } - return null; } @@ -208,7 +190,6 @@ public class InheritInfo { * Add the local properties for each sub class below this one. */ public void addChildrenProperties(SqlTreeProperties selectProps) { - for (InheritInfo childInfo : children) { selectProps.add(childInfo.descriptor.propertiesLocal()); childInfo.addChildrenProperties(selectProps); @@ -226,11 +207,9 @@ public class InheritInfo { * Return the associated InheritInfo for this discriminator value. */ InheritInfo readType(String discValue) { - if (discValue == null) { return null; } - InheritInfo typeInfo = root.getType(discValue); if (typeInfo == null) { throw new PersistenceException("Inheritance type for discriminator value [" + discValue + "] was not found?"); @@ -242,7 +221,6 @@ public class InheritInfo { * Return the associated InheritInfo for this bean type. */ public InheritInfo readType(Class beanType) { - InheritInfo typeInfo = root.getTypeByClass(beanType); if (typeInfo == null) { throw new PersistenceException("Inheritance type for bean type [" + beanType.getName() + "] was not found?"); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionBuilder.java index 764c2c700..bbe133838 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionBuilder.java @@ -6,7 +6,7 @@ import java.util.List; /** * Helper to build IntersectionTable. */ -public class IntersectionBuilder { +public final class IntersectionBuilder { private final String publishTable; private final String draftTable; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionRow.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionRow.java index 46d677ad8..3284032bb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionRow.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionRow.java @@ -12,14 +12,11 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -public class IntersectionRow { +public final class IntersectionRow { private final String tableName; - private final BeanDescriptor targetDescriptor; - private final LinkedHashMap values = new LinkedHashMap<>(); - private List excludeIds; private BeanDescriptor excludeDescriptor; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionTable.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionTable.java index 8f10e3a92..1a3553ed4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionTable.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/IntersectionTable.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.deploy; import io.ebean.Database; import io.ebean.SqlUpdate; -public class IntersectionTable { +public final class IntersectionTable { private final String insertSql; private final String deleteSql; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PartitionMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PartitionMeta.java index d041ae0a1..f146dc86f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PartitionMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PartitionMeta.java @@ -2,10 +2,9 @@ package io.ebeaninternal.server.deploy; import io.ebean.annotation.PartitionMode; -public class PartitionMeta { +public final class PartitionMeta { private final PartitionMode mode; - private String property; public PartitionMeta(PartitionMode mode, String property) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistControllerManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistControllerManager.java index f552fc77f..a6d45a12e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistControllerManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistControllerManager.java @@ -11,7 +11,7 @@ import java.util.List; /** * Default implementation for creating BeanControllers. */ -class PersistControllerManager { +final class PersistControllerManager { private static final Logger logger = LoggerFactory.getLogger(PersistControllerManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistListenerManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistListenerManager.java index 0e9c261c7..13ca4e7a5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistListenerManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistListenerManager.java @@ -12,7 +12,7 @@ import java.util.List; * Manages the assignment/registration of BeanPersistListener with their * respective DeployBeanDescriptor's. */ -class PersistListenerManager { +final class PersistListenerManager { private static final Logger logger = LoggerFactory.getLogger(PersistListenerManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistenceContextUtil.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistenceContextUtil.java index 69ad243e8..1a1c5651f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistenceContextUtil.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PersistenceContextUtil.java @@ -5,7 +5,7 @@ import javax.persistence.Entity; /** * Utility to find the root bean type. */ -public class PersistenceContextUtil { +public final class PersistenceContextUtil { /** * Find and return the root bean type for the given class. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PostConstructManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PostConstructManager.java index 0ef7b7120..6e7bb97c5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PostConstructManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PostConstructManager.java @@ -11,7 +11,7 @@ import java.util.List; /** * Default implementation for creating BeanControllers. */ -class PostConstructManager { +final class PostConstructManager { private static final Logger logger = LoggerFactory.getLogger(PostConstructManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PostLoadManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PostLoadManager.java index 0648d788f..f30826b90 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PostLoadManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PostLoadManager.java @@ -11,7 +11,7 @@ import java.util.List; /** * Default implementation for creating BeanControllers. */ -class PostLoadManager { +final class PostLoadManager { private static final Logger logger = LoggerFactory.getLogger(PostLoadManager.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PropertyForeignKey.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PropertyForeignKey.java index 480362e2a..6f66d3ed2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PropertyForeignKey.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/PropertyForeignKey.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.deploy; import io.ebean.annotation.ConstraintMode; import io.ebean.annotation.DbForeignKey; -public class PropertyForeignKey { +public final class PropertyForeignKey { private final boolean noIndex; private final boolean noConstraint; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/TableJoinColumn.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/TableJoinColumn.java index a04d72ed6..4878557b2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/TableJoinColumn.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/TableJoinColumn.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.deploy.meta.DeployTableJoinColumn; /** * A join pair of local and foreign properties. */ -public class TableJoinColumn { +public final class TableJoinColumn { /** * The local database column name. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/BeanPropertyElementSetter.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/BeanPropertyElementSetter.java index f20ee47cf..c8a362b60 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/BeanPropertyElementSetter.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/BeanPropertyElementSetter.java @@ -6,7 +6,7 @@ import io.ebeaninternal.server.properties.BeanPropertySetter; /** * Setter used for "element beans" with ElementCollection. */ -class BeanPropertyElementSetter implements BeanPropertySetter { +final class BeanPropertyElementSetter implements BeanPropertySetter { private final int pos; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanEmbedded.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanEmbedded.java index 72b541cef..ad70b8d30 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanEmbedded.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanEmbedded.java @@ -10,7 +10,7 @@ import java.util.Map; * Typically collects the overridden column names mapped * to the Embedded bean. */ -public class DeployBeanEmbedded { +public final class DeployBeanEmbedded { /** * A map of property names to dbColumns. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanObtainJackson.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanObtainJackson.java index 20beef7eb..9bbfb6007 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanObtainJackson.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanObtainJackson.java @@ -8,7 +8,7 @@ import io.ebean.config.DatabaseConfig; /** * Used to obtain the Jackson AnnotatedClass for a given bean type utlimately to obtain field level Jackson annotations. */ -class DeployBeanObtainJackson { +final class DeployBeanObtainJackson { private final DatabaseConfig config; private final Class beanType; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyAssocOne.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyAssocOne.java index 79f253b86..1444c69de 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyAssocOne.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyAssocOne.java @@ -7,7 +7,7 @@ import javax.persistence.CascadeType; /** * Property mapped to a joined bean. */ -public class DeployBeanPropertyAssocOne extends DeployBeanPropertyAssoc { +public final class DeployBeanPropertyAssocOne extends DeployBeanPropertyAssoc { private boolean oneToOne; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java index 5466d5bca..a6ed9c330 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertyLists.java @@ -15,7 +15,7 @@ import java.util.List; /** * Helper object to classify BeanProperties into appropriate lists. */ -public class DeployBeanPropertyLists { +public final class DeployBeanPropertyLists { private static final Logger logger = LoggerFactory.getLogger(DeployBeanPropertyLists.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertySimpleCollection.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertySimpleCollection.java index 6777dcc4c..870bae89f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertySimpleCollection.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanPropertySimpleCollection.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.deploy.meta; import io.ebean.bean.BeanCollection.ModifyListenMode; import io.ebeaninternal.server.deploy.ManyType; -public class DeployBeanPropertySimpleCollection extends DeployBeanPropertyAssocMany { +public final class DeployBeanPropertySimpleCollection extends DeployBeanPropertyAssocMany { public DeployBeanPropertySimpleCollection(DeployBeanDescriptor desc, Class targetType, ManyType manyType) { super(desc, targetType, manyType); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanTable.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanTable.java index de0166876..960205e0f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanTable.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployBeanTable.java @@ -13,7 +13,7 @@ import io.ebeaninternal.server.deploy.BeanPropertyAssocOne; * in a BeanDescriptor. *

*/ -public class DeployBeanTable { +public final class DeployBeanTable { private final Class beanType; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployIdentityMode.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployIdentityMode.java index 5915dc873..6a20d9145 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployIdentityMode.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployIdentityMode.java @@ -5,7 +5,7 @@ import io.ebean.annotation.IdentityGenerated; import io.ebean.annotation.IdentityType; import io.ebean.config.dbplatform.IdType; -public class DeployIdentityMode { +public final class DeployIdentityMode { public static DeployIdentityMode auto() { return new DeployIdentityMode(IdType.AUTO); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployOrderColumn.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployOrderColumn.java index 26a8402b6..4a8943a8e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployOrderColumn.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployOrderColumn.java @@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy.meta; import javax.persistence.OrderColumn; -public class DeployOrderColumn { +public final class DeployOrderColumn { /** * Logical property name used for order by and available for expression language. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployTableJoin.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployTableJoin.java index c3451f9f4..2a4608358 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployTableJoin.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployTableJoin.java @@ -15,7 +15,7 @@ import java.util.Set; * This gets converted into a immutable TableJoin when complete. *

*/ -public class DeployTableJoin { +public final class DeployTableJoin { /** * The joined table. @@ -33,7 +33,7 @@ public class DeployTableJoin { private ArrayList columns = new ArrayList<>(4); private InheritInfo inheritInfo; - + private String extraWhere; /** @@ -146,11 +146,11 @@ public class DeployTableJoin { public String getExtraWhere() { return extraWhere; } - + public void setExtraWhere(String extraWhere) { this.extraWhere = extraWhere; } - + public DeployTableJoin createInverse(String tableName) { DeployTableJoin inverse = new DeployTableJoin(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployTableJoinColumn.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployTableJoinColumn.java index da4bf0339..df5c4e0d5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployTableJoinColumn.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/meta/DeployTableJoinColumn.java @@ -8,7 +8,7 @@ import javax.persistence.JoinColumn; /** * A join pair of local and foreign properties. */ -public class DeployTableJoinColumn { +public final class DeployTableJoinColumn { /** * The local database column name. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java index 1ca59dbc8..a98867a54 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java @@ -41,7 +41,7 @@ import java.util.Set; /** * Read the deployment annotation for Assoc Many beans. */ -class AnnotationAssocManys extends AnnotationAssoc { +final class AnnotationAssocManys extends AnnotationAssoc { AnnotationAssocManys(DeployBeanInfo info, ReadAnnotationConfig readConfig, BeanDescriptorManager factory) { super(info, readConfig, factory); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java index 36fa99b57..727fe7c83 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java @@ -30,7 +30,7 @@ import javax.persistence.PrimaryKeyJoinColumn; /** * Read the deployment annotations for Associated One beans. */ -public class AnnotationAssocOnes extends AnnotationAssoc { +final class AnnotationAssocOnes extends AnnotationAssoc { private static final Logger log = LoggerFactory.getLogger(AnnotationAssocOnes.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java index 8985fb4ac..44a9d2113 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java @@ -36,7 +36,7 @@ import static io.ebean.util.AnnotationUtil.typeGet; /** * Read the class level deployment annotations. */ -public class AnnotationClass extends AnnotationParser { +final class AnnotationClass extends AnnotationParser { private static final Logger logger = LoggerFactory.getLogger(AnnotationClass.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFields.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFields.java index 5a0caa287..b6d570817 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFields.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFields.java @@ -76,7 +76,7 @@ import java.util.UUID; /** * Read the field level deployment annotations. */ -public class AnnotationFields extends AnnotationParser { +final class AnnotationFields extends AnnotationParser { /** * If present read Jackson JsonIgnore. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFind.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFind.java index 0faf59837..386e08e64 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFind.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFind.java @@ -15,7 +15,7 @@ import java.util.Set; import static io.ebean.util.AnnotationUtil.get; -public class AnnotationFind { +final class AnnotationFind { public static Set joinColumns(Field field) { final JoinColumn col = get(field, JoinColumn.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationSql.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationSql.java index 5001f2f70..955c119db 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationSql.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationSql.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.deploy.BeanDescriptor; /** * Read the class level deployment annotations. */ -class AnnotationSql extends AnnotationParser { +final class AnnotationSql extends AnnotationParser { AnnotationSql(DeployBeanInfo info, ReadAnnotationConfig readConfig) { super(info, readConfig); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployBeanInfo.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployBeanInfo.java index 002cb5e0e..e87ff7754 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployBeanInfo.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployBeanInfo.java @@ -9,7 +9,7 @@ import io.ebeaninternal.server.rawsql.SpiRawSql; /** * Wraps information about a bean during deployment parsing. */ -public class DeployBeanInfo { +public final class DeployBeanInfo { private final DeployUtil util; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java index 6fb54b46d..d3d7ddb7d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java @@ -35,7 +35,7 @@ import java.lang.reflect.WildcardType; * one or normal scalar property. *

*/ -public class DeployCreateProperties { +public final class DeployCreateProperties { private static final Logger logger = LoggerFactory.getLogger(DeployCreateProperties.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInherit.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInherit.java index fd9e4641b..7bc0ebd1b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInherit.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInherit.java @@ -15,7 +15,7 @@ import java.util.Map; /** * Builds the InheritInfo deployment information. */ -public class DeployInherit { +public final class DeployInherit { private final Map, DeployInheritInfo> deployMap = new LinkedHashMap<>(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInheritInfo.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInheritInfo.java index fb1a65a54..d1af77c8c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInheritInfo.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInheritInfo.java @@ -12,7 +12,7 @@ import java.util.List; * Represents a node in the Inheritance tree. * Holds information regarding Super Subclass support. */ -public class DeployInheritInfo { +public final class DeployInheritInfo { /** * the default discriminator column according to the JPA 1.0 spec. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java index 68cb1c741..276ff8d33 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/DeployUtil.java @@ -26,7 +26,7 @@ import java.sql.Types; /** * Utility object to help processing deployment information. */ -public class DeployUtil { +public final class DeployUtil { /** * Assumes CLOB rather than LONGVARCHAR. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaJacksonAnnotation.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaJacksonAnnotation.java index 08435de62..f283055ae 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaJacksonAnnotation.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaJacksonAnnotation.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.deploy.parse; -class InitMetaJacksonAnnotation { +final class InitMetaJacksonAnnotation { static void init(ReadAnnotationConfig readConfig) { readConfig.addMetaAnnotation(com.fasterxml.jackson.annotation.JacksonAnnotation.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotationConfig.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotationConfig.java index 1daf37564..81b5576e9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotationConfig.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotationConfig.java @@ -15,7 +15,7 @@ import java.util.Set; /** * Configuration used when reading the deployment annotations. */ -class ReadAnnotationConfig { +final class ReadAnnotationConfig { private final GeneratedPropertyFactory generatedPropFactory; private final String asOfViewSuffix; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotations.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotations.java index da2bc6030..c4ab55a1b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotations.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotations.java @@ -8,7 +8,7 @@ import io.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory /** * Read the deployment annotations for the bean. */ -public class ReadAnnotations { +public final class ReadAnnotations { private final ReadAnnotationConfig readConfig; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadValidationAnnotationsJakarta.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadValidationAnnotationsJakarta.java index 016e9f13a..95046f25d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadValidationAnnotationsJakarta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadValidationAnnotationsJakarta.java @@ -12,7 +12,7 @@ import java.util.List; /** * Jakarta validation annotations reader. */ -class ReadValidationAnnotationsJakarta implements ReadValidationAnnotations { +final class ReadValidationAnnotationsJakarta implements ReadValidationAnnotations { ReadValidationAnnotationsJakarta(ReadAnnotationConfig readConfig) { readConfig.addMetaAnnotation(Size.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadValidationAnnotationsJavax.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadValidationAnnotationsJavax.java index a690e69de..4704bf766 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadValidationAnnotationsJavax.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/ReadValidationAnnotationsJavax.java @@ -12,7 +12,7 @@ import java.util.List; /** * Javax validation annotations reader. */ -class ReadValidationAnnotationsJavax implements ReadValidationAnnotations { +final class ReadValidationAnnotationsJavax implements ReadValidationAnnotations { ReadValidationAnnotationsJavax(ReadAnnotationConfig readConfig) { readConfig.addMetaAnnotation(Size.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/TransientProperties.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/TransientProperties.java index e7896b96a..be5b10aee 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/TransientProperties.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/TransientProperties.java @@ -8,28 +8,22 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne; /** * Mark transient properties. */ -public class TransientProperties { - - public TransientProperties() { - } +public final class TransientProperties { /** * Mark any additional properties as transient. */ public void process(DeployBeanDescriptor desc) { - for (DeployBeanProperty prop : desc.propertiesBase()) { if (!prop.isDbRead() && !prop.isDbInsertable() && !prop.isDbUpdateable()) { prop.setTransient(); } } - for (DeployBeanPropertyAssocOne prop : desc.propertiesAssocOne()) { if (prop.getBeanTable() == null && !prop.isEmbedded()) { prop.setTransient(); } } - for (DeployBeanPropertyAssocMany prop : desc.propertiesAssocMany()) { if (prop.getBeanTable() == null) { prop.setTransient(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlService.java b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlService.java index 11b80da38..8ffef8a33 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlService.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlService.java @@ -11,7 +11,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; -final class DRawSqlService implements SpiRawSqlService { +public final class DRawSqlService implements SpiRawSqlService { @Override public RawSql resultSet(ResultSet resultSet, String... propertyNames) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/ArrayStack.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/ArrayStack.java index 8e824f664..4e76caea8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/util/ArrayStack.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/ArrayStack.java @@ -7,7 +7,7 @@ import java.util.List; /** * Stack based on ArrayList. */ -public final class ArrayStack { +public class ArrayStack { private final List list; diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/deploy/parse/AnnotationClassTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/deploy/parse/AnnotationClassTest.java index 73aa23ced..5b543e764 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/deploy/parse/AnnotationClassTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/deploy/parse/AnnotationClassTest.java @@ -1,12 +1,16 @@ package io.ebeaninternal.server.deploy.parse; +import io.ebean.config.DatabaseConfig; import io.ebean.config.ServerConfig; import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform; import io.ebeaninternal.server.core.bootup.BootupClasses; +import io.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory; import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor; import io.ebeaninternal.server.type.DefaultTypeManager; import org.junit.Test; +import java.util.Collections; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -46,9 +50,8 @@ public class AnnotationClassTest { DeployUtil deployUtil = new DeployUtil(new DefaultTypeManager(config, new BootupClasses()), config); - DeployBeanInfo deployBeanInfo = new DeployBeanInfo(deployUtil, mock(DeployBeanDescriptor.class)); - ReadAnnotationConfig readAnnotationConfig = mock(ReadAnnotationConfig.class); - + DeployBeanInfo deployBeanInfo = new DeployBeanInfo(deployUtil, new DeployBeanDescriptor<>(null, null, null)); + ReadAnnotationConfig readAnnotationConfig = new ReadAnnotationConfig(new GeneratedPropertyFactory(true, new DatabaseConfig(), Collections.emptyList()), "","", new DatabaseConfig()); return new AnnotationClass(deployBeanInfo, readAnnotationConfig); } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/visitor/VisitAllUsing.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/visitor/VisitAllUsing.java index 6ffbe1fd4..0cb6db92d 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/visitor/VisitAllUsing.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/model/visitor/VisitAllUsing.java @@ -11,7 +11,7 @@ import java.util.List; * Makes use of BeanVisitor and PropertyVisitor to navigate BeanDescriptors * and their properties. */ -public class VisitAllUsing extends VisitProperties { +public final class VisitAllUsing extends VisitProperties { private final BeanVisitor visitor; From 285a94e5fe96d8f540da94afbe8c3cefec9797ce Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 17 Aug 2021 19:06:54 +1200 Subject: [PATCH 108/120] #2318 - Refactor internals - final classes in dto packages --- .../io/ebeaninternal/server/dto/DtoBeanDescriptor.java | 5 +---- .../java/io/ebeaninternal/server/dto/DtoBeanManager.java | 5 ++--- .../main/java/io/ebeaninternal/server/dto/DtoColumn.java | 2 +- .../io/ebeaninternal/server/dto/DtoMappingRequest.java | 7 +------ .../main/java/io/ebeaninternal/server/dto/DtoMeta.java | 8 +------- .../java/io/ebeaninternal/server/dto/DtoMetaBuilder.java | 5 +---- .../io/ebeaninternal/server/dto/DtoMetaConstructor.java | 5 +---- .../java/io/ebeaninternal/server/dto/DtoMetaProperty.java | 2 +- .../java/io/ebeaninternal/server/dto/DtoNamedQueries.java | 4 ++-- .../io/ebeaninternal/server/dto/DtoQueryPlanConPlus.java | 4 +--- .../ebeaninternal/server/dto/DtoQueryPlanConSetter.java | 4 +--- .../ebeaninternal/server/dto/DtoQueryPlanConstructor.java | 2 +- .../io/ebeaninternal/server/dto/DtoReadSetColumnSkip.java | 2 +- 13 files changed, 15 insertions(+), 40 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoBeanDescriptor.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoBeanDescriptor.java index 10f2a2cdc..041ac7d45 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoBeanDescriptor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoBeanDescriptor.java @@ -8,14 +8,11 @@ import java.util.concurrent.ConcurrentHashMap; /** * Manages the query plans for a given DTO bean type. */ -public class DtoBeanDescriptor { +public final class DtoBeanDescriptor { private final Map plans = new ConcurrentHashMap<>(); - private final Class dtoType; - private final DtoMeta meta; - private final Map namedQueries; DtoBeanDescriptor(Class dtoType, DtoMeta meta, Map namedQueries) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoBeanManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoBeanManager.java index 4388a180d..c11f79843 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoBeanManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoBeanManager.java @@ -10,14 +10,13 @@ import java.util.concurrent.ConcurrentHashMap; /** * Manages all the DTO bean descriptors. */ -public class DtoBeanManager { +@SuppressWarnings("rawtypes") +public final class DtoBeanManager { private static final Map EMPTY_NAMED_QUERIES = new HashMap<>(); private final TypeManager typeManager; - private final Map, DtoNamedQueries> namedQueries; - private final Map descriptorMap = new ConcurrentHashMap<>(); public DtoBeanManager(TypeManager typeManager, Map, DtoNamedQueries> namedQueries) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoColumn.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoColumn.java index 187caf97f..9f42f2d0f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoColumn.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoColumn.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.dto; /** * A column in the resultSet that we want to map to a bean property. */ -public class DtoColumn { +public final class DtoColumn { private final String label; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMappingRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMappingRequest.java index b2a72db61..8c882599c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMappingRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMappingRequest.java @@ -8,18 +8,13 @@ import io.ebeaninternal.api.SpiDtoQuery; /** * Request to map a resultSet columns for a query into a DTO bean. */ -public class DtoMappingRequest { +public final class DtoMappingRequest { private final Class type; - private final String label; - private final ProfileLocation profileLocation; - private final String sql; - private final boolean relaxedMode; - private final DtoColumn[] columnMeta; public DtoMappingRequest(SpiDtoQuery query, String sql, DtoColumn[] columnMeta) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMeta.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMeta.java index 09bc441e9..9582c160e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMeta.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMeta.java @@ -10,23 +10,19 @@ import java.util.Map; * * Uses this to map a mapping request (columns) to a 'query plan' (constructor and setters). */ -class DtoMeta { +final class DtoMeta { private final Class dtoType; private final Map propMap = new LinkedHashMap<>(); - private final Map constructorMap = new LinkedHashMap<>(); - private final DtoMetaConstructor defaultConstructor; private final DtoMetaConstructor maxArgConstructor; DtoMeta(Class dtoType, List constructors, List properties) { this.dtoType = dtoType; - for (DtoMetaProperty property : properties) { propMap.put(property.getName().toUpperCase(), property); } - int maxArg = 0; DtoMetaConstructor defaultConstructor = null; @@ -47,9 +43,7 @@ class DtoMeta { } public DtoQueryPlan match(DtoMappingRequest request) { - DtoColumn[] cols = request.getColumnMeta(); - int colLen = cols.length; DtoMetaConstructor constructor = constructorMap.get(colLen); if (constructor != null) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java index bc5f900ed..0241c2747 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaBuilder.java @@ -15,16 +15,13 @@ import java.util.List; *

* Use TypeManager to map bean property types to ScalarTypes. */ -class DtoMetaBuilder { +final class DtoMetaBuilder { private static final Logger log = LoggerFactory.getLogger(DtoMetaBuilder.class); private final TypeManager typeManager; - private final Class dtoType; - private final List properties = new ArrayList<>(); - private final List constructorList = new ArrayList<>(); DtoMetaBuilder(Class dtoType, TypeManager typeManager) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaConstructor.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaConstructor.java index 35a736346..efd7c97d2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaConstructor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaConstructor.java @@ -10,22 +10,19 @@ import java.lang.invoke.MethodType; import java.lang.reflect.Constructor; import java.sql.SQLException; -class DtoMetaConstructor { +final class DtoMetaConstructor { private final Class[] types; private final MethodHandle handle; - private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); private final ScalarType[] scalarTypes; DtoMetaConstructor(TypeManager typeManager, Constructor constructor, Class someClass) throws NoSuchMethodException, IllegalAccessException { - this.types = constructor.getParameterTypes(); this.scalarTypes = new ScalarType[types.length]; for (int i = 0; i < types.length; i++) { scalarTypes[i] = typeManager.getScalarType(types[i]); } - this.handle = LOOKUP.findConstructor(someClass, typeFor(types)); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaProperty.java index c4beae172..fe7d794a1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoMetaProperty.java @@ -10,7 +10,7 @@ import java.lang.invoke.MethodType; import java.lang.reflect.Method; import java.sql.SQLException; -class DtoMetaProperty implements DtoReadSet { +final class DtoMetaProperty implements DtoReadSet { private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoNamedQueries.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoNamedQueries.java index 7b455de3d..6e92b010a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoNamedQueries.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoNamedQueries.java @@ -6,9 +6,9 @@ import java.util.Map; /** * Collection of named queries for a single Dto bean type. */ -public class DtoNamedQueries { +public final class DtoNamedQueries { - private Map namedRawSql = new HashMap<>(); + private final Map namedRawSql = new HashMap<>(); /** * Add the named query from deployment XML. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConPlus.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConPlus.java index 1bc530b78..3ea144604 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConPlus.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConPlus.java @@ -7,10 +7,9 @@ import java.sql.SQLException; /** * Plan based on Constructor plus some setter methods. */ -class DtoQueryPlanConPlus extends DtoQueryPlanBase { +final class DtoQueryPlanConPlus extends DtoQueryPlanBase { private final DtoMetaConstructor maxArgConstructor; - private final DtoReadSet[] setterProps; DtoQueryPlanConPlus(DtoMappingRequest request, DtoMetaConstructor maxArgConstructor, DtoReadSet[] setterProps) { @@ -21,7 +20,6 @@ class DtoQueryPlanConPlus extends DtoQueryPlanBase { @Override public Object readRow(DataReader dataReader) throws SQLException { - Object bean = maxArgConstructor.process(dataReader); for (DtoReadSet setterProp : setterProps) { setterProp.readSet(bean, dataReader); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConSetter.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConSetter.java index 70629e8da..a5aa905a9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConSetter.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConSetter.java @@ -7,10 +7,9 @@ import java.sql.SQLException; /** * Plan based on default constructor and setter methods. */ -class DtoQueryPlanConSetter extends DtoQueryPlanBase { +final class DtoQueryPlanConSetter extends DtoQueryPlanBase { private final DtoMetaConstructor defaultConstructor; - private final DtoReadSet[] setterProps; DtoQueryPlanConSetter(DtoMappingRequest request, DtoMetaConstructor defaultConstructor, DtoReadSet[] setterProps) { @@ -21,7 +20,6 @@ class DtoQueryPlanConSetter extends DtoQueryPlanBase { @Override public Object readRow(DataReader dataReader) throws SQLException { - Object bean = defaultConstructor.defaultConstructor(); for (DtoReadSet setterProp : setterProps) { setterProp.readSet(bean, dataReader); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConstructor.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConstructor.java index 912b41cd2..e0d39faa7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConstructor.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoQueryPlanConstructor.java @@ -7,7 +7,7 @@ import java.sql.SQLException; /** * Plan based on mapping via single constructor only. */ -class DtoQueryPlanConstructor extends DtoQueryPlanBase { +final class DtoQueryPlanConstructor extends DtoQueryPlanBase { private final DtoMetaConstructor constructor; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoReadSetColumnSkip.java b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoReadSetColumnSkip.java index 9fda8b81f..d2743e59d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoReadSetColumnSkip.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/dto/DtoReadSetColumnSkip.java @@ -5,7 +5,7 @@ import io.ebean.core.type.DataReader; /** * Placeholder to skip reading a column that isn't mapped to a bean property. */ -class DtoReadSetColumnSkip implements DtoReadSet { +final class DtoReadSetColumnSkip implements DtoReadSet { static final DtoReadSet INSTANCE = new DtoReadSetColumnSkip(); From 55587b12aa5456c98db619a630efc6f1078aa33c Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 17 Aug 2021 19:15:35 +1200 Subject: [PATCH 109/120] #2318 - Refactor internals - final classes in el packages --- .../server/el/ElComparatorNoop.java | 2 +- .../server/el/ElComparatorProperty.java | 2 -- .../io/ebeaninternal/server/el/ElFilter.java | 3 -- .../server/el/ElMatchBuilder.java | 36 +++++++++---------- .../server/el/ElPropertyChain.java | 16 +-------- .../server/el/ElPropertyChainBuilder.java | 5 +-- .../executor/DaemonScheduleThreadPool.java | 2 -- .../server/executor/DaemonThreadFactory.java | 3 +- .../executor/DefaultBackgroundExecutor.java | 2 +- .../readaudit/DefaultReadAuditLogger.java | 13 ------- 10 files changed, 22 insertions(+), 62 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElComparatorNoop.java b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElComparatorNoop.java index 9377aa91c..9fa68b481 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElComparatorNoop.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElComparatorNoop.java @@ -6,7 +6,7 @@ package io.ebeaninternal.server.el; * @author Roland Praml, FOCONIS AG * */ -public class ElComparatorNoop implements ElComparator { +public final class ElComparatorNoop implements ElComparator { private static final long serialVersionUID = -9060871822183687180L; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElComparatorProperty.java b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElComparatorProperty.java index a1093473f..56576d947 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElComparatorProperty.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElComparatorProperty.java @@ -12,9 +12,7 @@ public final class ElComparatorProperty implements Comparator, ElComparato private static final long serialVersionUID = -2735738237263956073L; private final ElPropertyValue elGetValue; - private final int nullOrder; - private final int asc; public ElComparatorProperty(ElPropertyValue elGetValue, boolean ascending, boolean nullsHigh) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElFilter.java b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElFilter.java index 4b205fb19..470345a31 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElFilter.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElFilter.java @@ -14,11 +14,8 @@ import java.util.regex.Pattern; public final class ElFilter implements Filter { private final BeanDescriptor beanDescriptor; - private final ArrayList> matches = new ArrayList<>(); - private int maxRows; - private String sortByClause; public ElFilter(BeanDescriptor beanDescriptor) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElMatchBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElMatchBuilder.java index 0cccfb9f4..66e966cfb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElMatchBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElMatchBuilder.java @@ -8,12 +8,12 @@ import java.util.regex.Pattern; /** * Contains the various ElMatcher implementations. */ -class ElMatchBuilder { +final class ElMatchBuilder { /** * Case insensitive equals. */ - static class RegularExpr implements ElMatcher { + static final class RegularExpr implements ElMatcher { final ElPropertyValue elGetValue; final String value; @@ -49,7 +49,7 @@ class ElMatchBuilder { public abstract boolean isMatch(T bean); } - static class Ieq extends BaseString { + static final class Ieq extends BaseString { Ieq(ElPropertyValue elGetValue, String value) { super(elGetValue, value); } @@ -64,7 +64,7 @@ class ElMatchBuilder { /** * Case insensitive starts with matcher. */ - static class IStartsWith implements ElMatcher { + static final class IStartsWith implements ElMatcher { final ElPropertyValue elGetValue; final CharMatch charMatch; @@ -85,7 +85,7 @@ class ElMatchBuilder { /** * Case insensitive ends with matcher. */ - static class IEndsWith implements ElMatcher { + static final class IEndsWith implements ElMatcher { final ElPropertyValue elGetValue; final CharMatch charMatch; @@ -103,7 +103,7 @@ class ElMatchBuilder { } } - static class StartsWith extends BaseString { + static final class StartsWith extends BaseString { StartsWith(ElPropertyValue elGetValue, String value) { super(elGetValue, value); } @@ -115,7 +115,7 @@ class ElMatchBuilder { } } - static class EndsWith extends BaseString { + static final class EndsWith extends BaseString { EndsWith(ElPropertyValue elGetValue, String value) { super(elGetValue, value); } @@ -127,7 +127,7 @@ class ElMatchBuilder { } } - static class IsNull implements ElMatcher { + static final class IsNull implements ElMatcher { final ElPropertyValue elGetValue; @@ -141,7 +141,7 @@ class ElMatchBuilder { } } - static class IsNotNull implements ElMatcher { + static final class IsNotNull implements ElMatcher { final ElPropertyValue elGetValue; @@ -170,7 +170,7 @@ class ElMatchBuilder { public abstract boolean isMatch(T value); } - static class InSet implements ElMatcher { + static final class InSet implements ElMatcher { final Set set; final ElPropertyValue elGetValue; @@ -183,7 +183,6 @@ class ElMatchBuilder { @Override public boolean isMatch(T bean) { - Object value = elGetValue.pathGet(bean); return value != null && set.contains(value); } @@ -192,7 +191,7 @@ class ElMatchBuilder { /** * Equal To. */ - static class Eq extends Base { + static final class Eq extends Base { public Eq(Object filterValue, ElComparator comparator) { super(filterValue, comparator); @@ -207,7 +206,7 @@ class ElMatchBuilder { /** * Not Equal To. */ - static class Ne extends Base { + static final class Ne extends Base { public Ne(Object filterValue, ElComparator comparator) { super(filterValue, comparator); @@ -222,7 +221,7 @@ class ElMatchBuilder { /** * Between. */ - static class Between implements ElMatcher { + static final class Between implements ElMatcher { final Object min; final Object max; @@ -236,7 +235,6 @@ class ElMatchBuilder { @Override public boolean isMatch(T value) { - return (comparator.compareValue(min, value) <= 0 && comparator.compareValue(max, value) >= 0); } @@ -245,7 +243,7 @@ class ElMatchBuilder { /** * Greater Than. */ - static class Gt extends Base { + static final class Gt extends Base { Gt(Object filterValue, ElComparator comparator) { super(filterValue, comparator); } @@ -259,7 +257,7 @@ class ElMatchBuilder { /** * Greater Than or Equal To. */ - static class Ge extends Base { + static final class Ge extends Base { Ge(Object filterValue, ElComparator comparator) { super(filterValue, comparator); } @@ -273,7 +271,7 @@ class ElMatchBuilder { /** * Less Than or Equal To. */ - static class Le extends Base { + static final class Le extends Base { Le(Object filterValue, ElComparator comparator) { super(filterValue, comparator); } @@ -287,7 +285,7 @@ class ElMatchBuilder { /** * Less Than. */ - static class Lt extends Base { + static final class Lt extends Base { Lt(Object filterValue, ElComparator comparator) { super(filterValue, comparator); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElPropertyChain.java b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElPropertyChain.java index 2effb1703..16d0e3808 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElPropertyChain.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElPropertyChain.java @@ -22,30 +22,22 @@ import java.util.Arrays; * no further processing of the chain occurs. *

*/ -public class ElPropertyChain implements ElPropertyValue { +public final class ElPropertyChain implements ElPropertyValue { private final String prefix; - private final String placeHolder; private final String placeHolderEncrypted; - private final String name; - private final String expression; - private final boolean containsMany; - private final ElPropertyValue[] chain; - private final boolean assocId; private final int last; private final BeanProperty lastBeanProperty; private final ScalarType scalarType; - private final ElPropertyValue lastElPropertyValue; public ElPropertyChain(boolean containsMany, boolean embedded, String expression, ElPropertyValue[] chain) { - this.containsMany = containsMany; this.chain = chain; this.expression = expression; @@ -119,15 +111,12 @@ public class ElPropertyChain implements ElPropertyValue { if (!expression.startsWith(sinceProperty)) { return containsMany; } - int i = 1 + SplitName.count(sinceProperty); - for (; i < chain.length; i++) { if (chain[i].getBeanProperty().containsMany()) { return true; } } - return false; } @@ -281,7 +270,6 @@ public class ElPropertyChain implements ElPropertyValue { @Override public Object pathGetNested(Object bean) { - Object prevBean = bean; for (int i = 0; i < last; i++) { // always return non null prevBean @@ -293,7 +281,6 @@ public class ElPropertyChain implements ElPropertyValue { @Override public void pathSet(Object bean, Object value) { - Object prevBean = bean; for (int i = 0; i < last; i++) { prevBean = chain[i].pathGetNested(prevBean); @@ -310,5 +297,4 @@ public class ElPropertyChain implements ElPropertyValue { } } - } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElPropertyChainBuilder.java b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElPropertyChainBuilder.java index 93b17b708..fd69bdd9c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/el/ElPropertyChainBuilder.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/el/ElPropertyChainBuilder.java @@ -13,14 +13,11 @@ import java.util.List; * order.customer.name. *

*/ -public class ElPropertyChainBuilder { +public final class ElPropertyChainBuilder { private final String expression; - private final List chain = new ArrayList<>(); - private boolean embedded; - private boolean containsMany; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/executor/DaemonScheduleThreadPool.java b/ebean-core/src/main/java/io/ebeaninternal/server/executor/DaemonScheduleThreadPool.java index 3bdf15777..983800061 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/executor/DaemonScheduleThreadPool.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/executor/DaemonScheduleThreadPool.java @@ -15,9 +15,7 @@ public final class DaemonScheduleThreadPool extends ScheduledThreadPoolExecutor private static final Logger logger = LoggerFactory.getLogger(DaemonScheduleThreadPool.class); private final ReentrantLock lock = new ReentrantLock(); - private final String namePrefix; - private final int shutdownWaitSeconds; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/executor/DaemonThreadFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/executor/DaemonThreadFactory.java index d1bbf3ee1..c2e14195b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/executor/DaemonThreadFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/executor/DaemonThreadFactory.java @@ -13,10 +13,9 @@ import java.util.concurrent.atomic.AtomicInteger; * on shutdown or register with the JVM shutdown hook to perform a nice shutdown * of the daemon threads etc. */ -public class DaemonThreadFactory implements ThreadFactory { +public final class DaemonThreadFactory implements ThreadFactory { private final AtomicInteger threadNumber = new AtomicInteger(1); - private final String namePrefix; public DaemonThreadFactory(String namePrefix) { 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 28bb50765..305da21ca 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 @@ -13,7 +13,7 @@ import java.util.concurrent.TimeUnit; /** * The default implementation of the BackgroundExecutor. */ -public class DefaultBackgroundExecutor implements SpiBackgroundExecutor { +public final class DefaultBackgroundExecutor implements SpiBackgroundExecutor { private final ScheduledExecutorService executor; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/readaudit/DefaultReadAuditLogger.java b/ebean-core/src/main/java/io/ebeaninternal/server/readaudit/DefaultReadAuditLogger.java index 64a9072eb..9e1403836 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/readaudit/DefaultReadAuditLogger.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/readaudit/DefaultReadAuditLogger.java @@ -19,15 +19,11 @@ import java.util.Map; public class DefaultReadAuditLogger implements ReadAuditLogger { private static final Logger appLogger = LoggerFactory.getLogger(DefaultReadAuditLogger.class); - private static final Logger queryLogger = LoggerFactory.getLogger("io.ebean.ReadAuditQuery"); - private static final Logger auditLogger = LoggerFactory.getLogger("io.ebean.ReadAudit"); protected final JsonFactory jsonFactory = new JsonFactory(); - protected int defaultQueryBuffer = 500; - protected int defaultReadBuffer = 150; /** @@ -37,7 +33,6 @@ public class DefaultReadAuditLogger implements ReadAuditLogger { public void queryPlan(ReadAuditQueryPlan queryPlan) { StringWriter writer = new StringWriter(defaultQueryBuffer); try (JsonGenerator gen = jsonFactory.createGenerator(writer)) { - gen.writeStartObject(); String beanType = queryPlan.getBeanType(); if (beanType != null) { @@ -53,9 +48,7 @@ public class DefaultReadAuditLogger implements ReadAuditLogger { } gen.writeEndObject(); gen.flush(); - queryLogger.info(writer.toString()); - } catch (IOException e) { appLogger.error("Error writing Read audit event", e); } @@ -66,7 +59,6 @@ public class DefaultReadAuditLogger implements ReadAuditLogger { */ @Override public void auditBean(ReadEvent beanEvent) { - writeEvent(beanEvent); } @@ -79,14 +71,11 @@ public class DefaultReadAuditLogger implements ReadAuditLogger { } protected void writeEvent(ReadEvent event) { - try { StringWriter writer = new StringWriter(defaultReadBuffer); JsonGenerator gen = jsonFactory.createGenerator(writer); writeDetails(gen, event); - auditLogger.info(writer.toString()); - } catch (IOException e) { appLogger.error("Error writing Read audit event", e); } @@ -96,7 +85,6 @@ public class DefaultReadAuditLogger implements ReadAuditLogger { * Write the details for the read bean or read many beans event. */ protected void writeDetails(JsonGenerator gen, ReadEvent event) throws IOException { - gen.writeStartObject(); String source = event.getSource(); if (source != null) { @@ -130,7 +118,6 @@ public class DefaultReadAuditLogger implements ReadAuditLogger { gen.writeFieldName("ids"); EJson.writeCollection(event.getIds(), gen); } - gen.writeEndObject(); gen.flush(); gen.close(); From 826e8518eadb21d9befc11a7a3ca133faa940931 Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 17 Aug 2021 19:46:08 +1200 Subject: [PATCH 110/120] #2318 - Refactor internals - final classes in type packages --- .../type/AttributeConverterAdapter.java | 2 +- .../ebeaninternal/server/type/DataBind.java | 45 +++++++++---------- .../server/type/DataBindCapture.java | 2 +- .../server/type/DataEncryptSupport.java | 2 +- .../server/type/DecimalUtils.java | 5 --- .../server/type/DefaultTypeFactory.java | 4 +- .../server/type/EnumToDbIntegerMap.java | 2 +- .../server/type/EnumToDbStringMap.java | 2 +- .../server/type/EnumToDbValueMap.java | 4 -- .../server/type/InitObjectMapper.java | 2 +- .../server/type/IsoJsonDateTimeParser.java | 2 +- .../server/type/JacksonTypeHelper.java | 2 +- .../server/type/LongToTimestampConverter.java | 5 +-- .../server/type/PostgresHelper.java | 3 +- .../server/type/RsetDataReaderIndexed.java | 2 +- .../ebeaninternal/server/type/ScalarHelp.java | 4 +- .../server/type/bindcapture/BindCapture.java | 2 +- .../bindcapture/BindCaptureStatement.java | 2 +- .../type/bindcapture/BindCaptureTypes.java | 39 ++++++++-------- 19 files changed, 56 insertions(+), 75 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/AttributeConverterAdapter.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/AttributeConverterAdapter.java index e358dd891..242b657f3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/AttributeConverterAdapter.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/AttributeConverterAdapter.java @@ -7,7 +7,7 @@ import javax.persistence.AttributeConverter; /** * Adapter from ScalarTypeConverter to AttributeConverter. */ -class AttributeConverterAdapter implements ScalarTypeConverter { +final class AttributeConverterAdapter implements ScalarTypeConverter { private final AttributeConverter converter; private final B nullValue; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java index a1a9ec8cf..89603122b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBind.java @@ -26,15 +26,10 @@ public class DataBind implements DataBinder { private static final Logger log = LoggerFactory.getLogger(DataBind.class); private final DataTimeZone dataTimeZone; - private final PreparedStatement pstmt; - private final Connection connection; - private final StringBuilder bindLog = new StringBuilder(); - private List inputStreams; - protected int pos; private String json; @@ -45,35 +40,35 @@ public class DataBind implements DataBinder { } @Override - public void pushJson(String json) { + public final void pushJson(String json) { assert this.json == null; // we can only push one value this.json = json; } @Override - public String popJson() { + public final String popJson() { String ret = json; json = null; return ret; } @Override - public StringBuilder append(Object entry) { + public final StringBuilder append(Object entry) { return bindLog.append(entry); } @Override - public StringBuilder log() { + public final StringBuilder log() { return bindLog; } @Override - public void close() throws SQLException { + public final void close() throws SQLException { pstmt.close(); } @Override - public int currentPos() { + public final int currentPos() { return pos; } @@ -83,7 +78,7 @@ public class DataBind implements DataBinder { } @Override - public void setObject(Object value, int sqlType) throws SQLException { + public final void setObject(Object value, int sqlType) throws SQLException { pstmt.setObject(++pos, value, sqlType); } @@ -93,17 +88,17 @@ public class DataBind implements DataBinder { } @Override - public int nextPos() { + public final int nextPos() { return ++pos; } @Override - public void decrementPos() { + public final void decrementPos() { --pos; } @Override - public int executeUpdate() throws SQLException { + public final int executeUpdate() throws SQLException { try { return pstmt.executeUpdate(); } finally { @@ -125,7 +120,7 @@ public class DataBind implements DataBinder { } @Override - public PreparedStatement getPstmt() { + public final PreparedStatement getPstmt() { return pstmt; } @@ -135,37 +130,37 @@ public class DataBind implements DataBinder { } @Override - public void setInt(int i) throws SQLException { + public final void setInt(int i) throws SQLException { pstmt.setInt(++pos, i); } @Override - public void setLong(long i) throws SQLException { + public final void setLong(long i) throws SQLException { pstmt.setLong(++pos, i); } @Override - public void setShort(short i) throws SQLException { + public final void setShort(short i) throws SQLException { pstmt.setShort(++pos, i); } @Override - public void setFloat(float i) throws SQLException { + public final void setFloat(float i) throws SQLException { pstmt.setFloat(++pos, i); } @Override - public void setDouble(double i) throws SQLException { + public final void setDouble(double i) throws SQLException { pstmt.setDouble(++pos, i); } @Override - public void setBigDecimal(BigDecimal v) throws SQLException { + public final void setBigDecimal(BigDecimal v) throws SQLException { pstmt.setBigDecimal(++pos, v); } @Override - public void setDate(java.sql.Date v) throws SQLException { + public final void setDate(java.sql.Date v) throws SQLException { Calendar timeZone = dataTimeZone.getDateTimeZone(); if (timeZone != null) { pstmt.setDate(++pos, v, timeZone); @@ -175,7 +170,7 @@ public class DataBind implements DataBinder { } @Override - public void setTimestamp(Timestamp v) throws SQLException { + public final void setTimestamp(Timestamp v) throws SQLException { Calendar timeZone = dataTimeZone.getTimeZone(); if (timeZone != null) { pstmt.setTimestamp(++pos, v, timeZone); @@ -185,7 +180,7 @@ public class DataBind implements DataBinder { } @Override - public void setTime(Time v) throws SQLException { + public final void setTime(Time v) throws SQLException { Calendar timeZone = dataTimeZone.getTimeZone(); if (timeZone != null) { pstmt.setTime(++pos, v, timeZone); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBindCapture.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBindCapture.java index e87ebf471..659d0ef06 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBindCapture.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataBindCapture.java @@ -7,7 +7,7 @@ import io.ebeaninternal.server.type.bindcapture.BindCaptureStatement; /** * Special DataBind used to capture bind values for obtaining explain plans. */ -public class DataBindCapture extends DataBind { +public final class DataBindCapture extends DataBind { private final BindCaptureStatement captureStatement; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataEncryptSupport.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataEncryptSupport.java index 32d87cd91..791d3e78e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DataEncryptSupport.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DataEncryptSupport.java @@ -4,7 +4,7 @@ import io.ebean.config.EncryptKey; import io.ebean.config.EncryptKeyManager; import io.ebean.config.Encryptor; -public class DataEncryptSupport { +public final class DataEncryptSupport { private final EncryptKeyManager encryptKeyManager; private final Encryptor encryptor; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DecimalUtils.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DecimalUtils.java index 60e3f6d6e..72f2d4e96 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DecimalUtils.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DecimalUtils.java @@ -38,10 +38,8 @@ public final class DecimalUtils { } public static Duration toDuration(BigDecimal value) { - long seconds = value.longValue(); int nanoseconds = extractNanosecondDecimal(value, seconds); - return Duration.ofSeconds(seconds, nanoseconds); } @@ -50,10 +48,8 @@ public final class DecimalUtils { } public static Timestamp toTimestamp(BigDecimal value) { - long seconds = value.longValue(); int nanoseconds = extractNanosecondDecimal(value, seconds); - Timestamp ts = new Timestamp(seconds * 1000); ts.setNanos(nanoseconds); return ts; @@ -66,7 +62,6 @@ public final class DecimalUtils { } public static Instant toInstant(BigDecimal value) { - long seconds = value.longValue(); int nanoseconds = extractNanosecondDecimal(value, seconds); return Instant.ofEpochSecond(seconds, nanoseconds); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeFactory.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeFactory.java index 22f50b937..6c2f3b860 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeFactory.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/DefaultTypeFactory.java @@ -14,7 +14,7 @@ import java.util.Date; * Helper to create some default ScalarType objects for Booleans, * java.util.Date, java.util.Calendar etc. */ -public class DefaultTypeFactory { +public final class DefaultTypeFactory { private final DatabaseConfig config; @@ -22,7 +22,7 @@ public class DefaultTypeFactory { this.config = config; } - protected ScalarTypeBool createBoolean(String trueValue, String falseValue) { + ScalarTypeBool createBoolean(String trueValue, String falseValue) { try { // first try Integer based boolean Integer intTrue = BasicTypeConverter.toInteger(trueValue); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbIntegerMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbIntegerMap.java index 7d62a8391..419d8f53a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbIntegerMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbIntegerMap.java @@ -10,7 +10,7 @@ import java.sql.Types; /** * Used to map enum values to database integer values. */ -public class EnumToDbIntegerMap extends EnumToDbValueMap { +public final class EnumToDbIntegerMap extends EnumToDbValueMap { @Override public int getDbType() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbStringMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbStringMap.java index 05b0f8991..c7dc4bc89 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbStringMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbStringMap.java @@ -9,7 +9,7 @@ import java.sql.Types; /** * Used to map Enum values to database string/varchar values. */ -public class EnumToDbStringMap extends EnumToDbValueMap { +public final class EnumToDbStringMap extends EnumToDbValueMap { @Override public int getDbType() { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbValueMap.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbValueMap.java index 08240cabc..57ab47ef5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbValueMap.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/EnumToDbValueMap.java @@ -22,13 +22,9 @@ public abstract class EnumToDbValueMap { } final LinkedHashMap keyMap; - final LinkedHashMap valueMap; - final HashMap nameMap; - final boolean allowNulls; - final boolean isIntegerType; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/InitObjectMapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/InitObjectMapper.java index 90a86ec79..7daee8bd5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/InitObjectMapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/InitObjectMapper.java @@ -9,7 +9,7 @@ import java.util.Set; /** * Initialise the Jackson ObjectMapper. */ -class InitObjectMapper { +final class InitObjectMapper { /** * Create and return the default ObjectMapper. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/IsoJsonDateTimeParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/IsoJsonDateTimeParser.java index a6f8a8636..fd4373062 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/IsoJsonDateTimeParser.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/IsoJsonDateTimeParser.java @@ -4,7 +4,7 @@ import java.time.Instant; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; -class IsoJsonDateTimeParser { +final class IsoJsonDateTimeParser { private static final DateTimeFormatter ISO_MILLIS = new DateTimeFormatterBuilder() .parseCaseInsensitive() diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/JacksonTypeHelper.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/JacksonTypeHelper.java index 1e1db244d..7d2d5b3e1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/JacksonTypeHelper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/JacksonTypeHelper.java @@ -3,7 +3,7 @@ package io.ebeaninternal.server.type; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.introspect.AnnotatedField; -class JacksonTypeHelper { +final class JacksonTypeHelper { private final AnnotatedField field; private final ObjectMapper objectMapper; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/LongToTimestampConverter.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/LongToTimestampConverter.java index e396602d4..83d55871d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/LongToTimestampConverter.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/LongToTimestampConverter.java @@ -4,7 +4,7 @@ import io.ebean.config.ScalarTypeConverter; import java.sql.Timestamp; -public class LongToTimestampConverter implements ScalarTypeConverter { +public final class LongToTimestampConverter implements ScalarTypeConverter { @Override public Long getNullValue() { @@ -13,15 +13,12 @@ public class LongToTimestampConverter implements ScalarTypeConverter entries = new ArrayList<>(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/bindcapture/BindCaptureStatement.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/bindcapture/BindCaptureStatement.java index e8cda7b13..916c1c355 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/bindcapture/BindCaptureStatement.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/bindcapture/BindCaptureStatement.java @@ -12,7 +12,7 @@ import java.util.Calendar; /** * Special PreparedStatement used to capture bind values used to obtain explain plans. */ -public class BindCaptureStatement extends BindCaptureStatementBase implements PreparedStatement { +public final class BindCaptureStatement extends BindCaptureStatementBase implements PreparedStatement { private final BindCapture capture = new BindCapture(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/bindcapture/BindCaptureTypes.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/bindcapture/BindCaptureTypes.java index 1c859c8fb..b2e36f828 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/bindcapture/BindCaptureTypes.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/bindcapture/BindCaptureTypes.java @@ -13,9 +13,9 @@ import java.sql.Timestamp; import java.util.Arrays; import java.util.Calendar; -class BindCaptureTypes { +final class BindCaptureTypes { - static class Null implements BindCaptureEntry { + static final class Null implements BindCaptureEntry { private final int parameterIndex; private final int sqlType; @@ -36,7 +36,7 @@ class BindCaptureTypes { } } - static class Boolean implements BindCaptureEntry { + static final class Boolean implements BindCaptureEntry { private final int parameterIndex; private final boolean x; @@ -57,7 +57,7 @@ class BindCaptureTypes { } } - static class Byte implements BindCaptureEntry { + static final class Byte implements BindCaptureEntry { private final int parameterIndex; private final byte x; @@ -78,7 +78,7 @@ class BindCaptureTypes { } } - static class Bytes implements BindCaptureEntry { + static final class Bytes implements BindCaptureEntry { private final int parameterIndex; private final byte[] x; @@ -99,7 +99,7 @@ class BindCaptureTypes { } } - static class TShort implements BindCaptureEntry { + static final class TShort implements BindCaptureEntry { private final int parameterIndex; private final short value; @@ -120,7 +120,7 @@ class BindCaptureTypes { } } - static class TInt implements BindCaptureEntry { + static final class TInt implements BindCaptureEntry { private final int parameterIndex; private final int value; @@ -141,7 +141,7 @@ class BindCaptureTypes { } } - static class TLong implements BindCaptureEntry { + static final class TLong implements BindCaptureEntry { private final int parameterIndex; private final long value; @@ -162,7 +162,7 @@ class BindCaptureTypes { } } - static class TFloat implements BindCaptureEntry { + static final class TFloat implements BindCaptureEntry { private final int parameterIndex; private final float value; @@ -183,7 +183,7 @@ class BindCaptureTypes { } } - static class TDouble implements BindCaptureEntry { + static final class TDouble implements BindCaptureEntry { private final int parameterIndex; private final double value; @@ -204,7 +204,7 @@ class BindCaptureTypes { } } - static class TBigDecimal implements BindCaptureEntry { + static final class TBigDecimal implements BindCaptureEntry { private final int parameterIndex; private final BigDecimal value; @@ -226,7 +226,7 @@ class BindCaptureTypes { } - static class TString implements BindCaptureEntry { + static final class TString implements BindCaptureEntry { private final int parameterIndex; private final String value; @@ -247,7 +247,7 @@ class BindCaptureTypes { } } - static class TDate implements BindCaptureEntry { + static final class TDate implements BindCaptureEntry { private final int parameterIndex; private final Date value; @@ -268,7 +268,7 @@ class BindCaptureTypes { } } - static class TTime implements BindCaptureEntry { + static final class TTime implements BindCaptureEntry { private final int parameterIndex; private final Time value; @@ -289,7 +289,7 @@ class BindCaptureTypes { } } - static class TTimestamp implements BindCaptureEntry { + static final class TTimestamp implements BindCaptureEntry { private final int parameterIndex; private final Timestamp value; @@ -316,7 +316,7 @@ class BindCaptureTypes { } } - static class TObject implements BindCaptureEntry { + static final class TObject implements BindCaptureEntry { private final int parameterIndex; private final Object value; @@ -337,13 +337,12 @@ class BindCaptureTypes { } } - static class TArray implements BindCaptureEntry { + static final class TArray implements BindCaptureEntry { private final int parameterIndex; private final String arrayType; private final Object[] elements; - TArray(int parameterIndex, String arrayType, Object[] elements) { this.parameterIndex = parameterIndex; this.arrayType = arrayType; @@ -362,7 +361,7 @@ class BindCaptureTypes { } } - static class CharacterStream implements BindCaptureEntry { + static final class CharacterStream implements BindCaptureEntry { private static final String dummy = "hi"; @@ -383,7 +382,7 @@ class BindCaptureTypes { } } - static class BinaryStream implements BindCaptureEntry { + static final class BinaryStream implements BindCaptureEntry { private static final byte[] dummy = "hi".getBytes(Charset.defaultCharset()); From 183416a6402471230a094603d1eccd291e5df84c Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 17 Aug 2021 20:09:02 +1200 Subject: [PATCH 111/120] #2318 - Delete unused ScalarTypeLongToTimestamp --- .../server/type/ScalarTypeLongToTimestamp.java | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLongToTimestamp.java diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLongToTimestamp.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLongToTimestamp.java deleted file mode 100644 index 3a48dd786..000000000 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLongToTimestamp.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.ebeaninternal.server.type; - -import io.ebean.config.JsonConfig; - -import java.sql.Timestamp; - -public class ScalarTypeLongToTimestamp extends ScalarTypeWrapper { - - public ScalarTypeLongToTimestamp(JsonConfig.DateTime mode) { - super(Long.class, new ScalarTypeTimestamp(mode), new LongToTimestampConverter()); - } -} From dde9b507ceaf60e5f070cbc8a3e47ac87af7d79a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Tue, 17 Aug 2021 20:09:27 +1200 Subject: [PATCH 112/120] #2318 - Refactor internals - final classes in type packages --- .../server/type/ScalarTypeArrayListH2.java | 2 +- .../server/type/ScalarTypeArraySetH2.java | 2 +- .../server/type/ScalarTypeBoolean.java | 10 +++++----- .../server/type/ScalarTypeByte.java | 2 +- .../server/type/ScalarTypeBytesBinary.java | 2 +- .../server/type/ScalarTypeBytesBlob.java | 2 +- .../server/type/ScalarTypeBytesEncrypted.java | 3 +-- .../type/ScalarTypeBytesLongVarbinary.java | 2 +- .../server/type/ScalarTypeBytesVarbinary.java | 2 +- .../server/type/ScalarTypeCalendar.java | 2 +- .../server/type/ScalarTypeChar.java | 2 +- .../server/type/ScalarTypeCharArray.java | 2 +- .../server/type/ScalarTypeCidr.java | 4 ++-- .../server/type/ScalarTypeClass.java | 5 +---- .../server/type/ScalarTypeCurrency.java | 2 +- .../server/type/ScalarTypeDate.java | 2 +- .../server/type/ScalarTypeDayOfWeek.java | 2 +- .../server/type/ScalarTypeDouble.java | 2 +- .../type/ScalarTypeDurationWithNanos.java | 2 +- .../type/ScalarTypeEncryptedWrapper.java | 4 +--- .../server/type/ScalarTypeEnumStandard.java | 9 +++------ .../type/ScalarTypeEnumWithMapping.java | 2 -- .../server/type/ScalarTypeFile.java | 5 +---- .../server/type/ScalarTypeFloat.java | 2 +- .../server/type/ScalarTypeInet.java | 4 ++-- .../server/type/ScalarTypeInetAddress.java | 2 +- .../type/ScalarTypeInetAddressPostgres.java | 2 +- .../server/type/ScalarTypeInstant.java | 2 +- .../server/type/ScalarTypeInteger.java | 2 +- .../type/ScalarTypeJodaDateMidnight.java | 2 +- .../server/type/ScalarTypeJodaDateTime.java | 2 +- .../server/type/ScalarTypeJodaLocalDate.java | 2 +- .../type/ScalarTypeJodaLocalDateTime.java | 2 +- .../type/ScalarTypeJodaLocalTimeUTC.java | 2 +- .../server/type/ScalarTypeJodaPeriod.java | 2 +- .../server/type/ScalarTypeJsonList.java | 2 +- .../server/type/ScalarTypeJsonNode.java | 4 ++-- .../type/ScalarTypeJsonNodePostgres.java | 4 ++-- .../type/ScalarTypeJsonObjectMapper.java | 2 +- .../server/type/ScalarTypeLocalDate.java | 2 +- .../server/type/ScalarTypeLocalDateTime.java | 2 +- .../type/ScalarTypeLocalTimeWithNanos.java | 2 +- .../server/type/ScalarTypeLocale.java | 2 +- .../server/type/ScalarTypeLong.java | 2 +- .../server/type/ScalarTypeLongVarchar.java | 2 +- .../server/type/ScalarTypeMathBigInteger.java | 2 +- .../server/type/ScalarTypeMonth.java | 2 +- .../server/type/ScalarTypeMonthDay.java | 14 ++------------ .../server/type/ScalarTypeOffsetDateTime.java | 4 ++-- .../server/type/ScalarTypeOffsetTime.java | 4 ++-- .../server/type/ScalarTypePath.java | 4 ++-- .../server/type/ScalarTypePeriod.java | 4 ++-- .../server/type/ScalarTypePostgresHstore.java | 4 ++-- .../server/type/ScalarTypeShort.java | 4 ++-- .../server/type/ScalarTypeString.java | 2 +- .../server/type/ScalarTypeStringBase.java | 2 +- .../server/type/ScalarTypeTime.java | 4 ++-- .../server/type/ScalarTypeTimeZone.java | 4 ++-- .../server/type/ScalarTypeTimestamp.java | 4 ++-- .../server/type/ScalarTypeURI.java | 4 ++-- .../server/type/ScalarTypeURL.java | 4 ++-- .../server/type/ScalarTypeUUIDBase.java | 4 ++-- .../server/type/ScalarTypeUUIDBinary.java | 4 ++-- .../server/type/ScalarTypeUUIDNative.java | 4 ++-- .../server/type/ScalarTypeUUIDVarchar.java | 4 ++-- .../server/type/ScalarTypeUtilDate.java | 10 +++++----- .../server/type/ScalarTypeWrapper.java | 3 --- .../server/type/ScalarTypeYear.java | 4 ++-- .../server/type/ScalarTypeYearMonthDate.java | 9 +++++---- .../server/type/ScalarTypeZoneId.java | 4 ++-- .../server/type/ScalarTypeZoneOffset.java | 4 ++-- .../server/type/ScalarTypeZonedDateTime.java | 4 ++-- .../server/type/SimpleAesEncryptor.java | 19 +------------------ .../server/type/TypeJsonManager.java | 2 +- .../server/type/TypeReflectHelper.java | 3 +-- .../server/type/TypeResolver.java | 6 +----- .../server/type/UtilDateParser.java | 2 +- 77 files changed, 113 insertions(+), 161 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeArrayListH2.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeArrayListH2.java index f8b30a7a0..c9bc3a3f2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeArrayListH2.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeArrayListH2.java @@ -19,7 +19,7 @@ import static java.util.Collections.EMPTY_LIST; * H2 database support for DB ARRAY. */ @SuppressWarnings("rawtypes") -class ScalarTypeArrayListH2 extends ScalarTypeArrayList { +final class ScalarTypeArrayListH2 extends ScalarTypeArrayList { static PlatformArrayTypeFactory factory() { return new ScalarTypeArrayListH2.Factory(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeArraySetH2.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeArraySetH2.java index cd7f7cf98..1d5c78553 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeArraySetH2.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeArraySetH2.java @@ -19,7 +19,7 @@ import static java.util.Collections.EMPTY_SET; * H2 database support for DB ARRAY. */ @SuppressWarnings("rawtypes") -class ScalarTypeArraySetH2 extends ScalarTypeArraySet { +final class ScalarTypeArraySetH2 extends ScalarTypeArraySet { static PlatformArrayTypeFactory factory() { return new ScalarTypeArraySetH2.Factory(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBoolean.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBoolean.java index 93a688e94..56bc180a9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBoolean.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBoolean.java @@ -21,9 +21,9 @@ import java.sql.Types; * This may or may not be a native jdbc type depending on the database and jdbc driver. *

*/ -public class ScalarTypeBoolean { +public final class ScalarTypeBoolean { - public static class Native extends BooleanBase { + public static final class Native extends BooleanBase { /** * Native Boolean database type. @@ -75,7 +75,7 @@ public class ScalarTypeBoolean { * type.boolean.dbtype="bit" in the ebean configuration *

*/ - static class BitBoolean extends BooleanBase { + static final class BitBoolean extends BooleanBase { /** * Native Boolean database type. @@ -124,7 +124,7 @@ public class ScalarTypeBoolean { /** * Converted to/from an Integer in the Database. */ - static class IntBoolean extends BooleanBase { + static final class IntBoolean extends BooleanBase { private final Integer trueValue; private final Integer falseValue; @@ -211,7 +211,7 @@ public class ScalarTypeBoolean { /** * Converted to/from an Integer in the Database. */ - static class StringBoolean extends BooleanBase { + static final class StringBoolean extends BooleanBase { private final String trueValue; private final String falseValue; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeByte.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeByte.java index 5d0660930..3a64f421f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeByte.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeByte.java @@ -18,7 +18,7 @@ import java.sql.Types; /** * ScalarType for Byte. */ -public class ScalarTypeByte extends ScalarTypeBase { +public final class ScalarTypeByte extends ScalarTypeBase { public ScalarTypeByte() { super(Byte.class, true, Types.TINYINT); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesBinary.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesBinary.java index 8567c808f..18cdb096e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesBinary.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesBinary.java @@ -8,7 +8,7 @@ import java.sql.Types; /** * ScalarType for Types.BINARY to byte[]. */ -public class ScalarTypeBytesBinary extends ScalarTypeBytesBase { +public final class ScalarTypeBytesBinary extends ScalarTypeBytesBase { public ScalarTypeBytesBinary() { super(true, Types.BINARY); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesBlob.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesBlob.java index 5ad02618f..5cc3e2afc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesBlob.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesBlob.java @@ -8,7 +8,7 @@ import java.sql.Types; /** * ScalarType for BLOB. */ -public class ScalarTypeBytesBlob extends ScalarTypeBytesBase { +public final class ScalarTypeBytesBlob extends ScalarTypeBytesBase { public ScalarTypeBytesBlob() { super(true, Types.BLOB); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesEncrypted.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesEncrypted.java index 9b81acfde..df8b32ba9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesEncrypted.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesEncrypted.java @@ -16,10 +16,9 @@ import java.sql.SQLException; /** * Encrypted ScalarType that wraps a byte[] types. */ -public class ScalarTypeBytesEncrypted implements ScalarType { +public final class ScalarTypeBytesEncrypted implements ScalarType { private final ScalarTypeBytesBase baseType; - private final DataEncryptSupport dataEncryptSupport; public ScalarTypeBytesEncrypted(ScalarTypeBytesBase baseType, DataEncryptSupport dataEncryptSupport) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesLongVarbinary.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesLongVarbinary.java index 8d1b87cf9..fef593e12 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesLongVarbinary.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesLongVarbinary.java @@ -8,7 +8,7 @@ import java.sql.Types; /** * ScalarType for Longvarbinary. */ -public class ScalarTypeBytesLongVarbinary extends ScalarTypeBytesBase { +public final class ScalarTypeBytesLongVarbinary extends ScalarTypeBytesBase { public ScalarTypeBytesLongVarbinary() { super(true, Types.LONGVARBINARY); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesVarbinary.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesVarbinary.java index 3e9b68790..dea5cc1a1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesVarbinary.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeBytesVarbinary.java @@ -8,7 +8,7 @@ import java.sql.Types; /** * ScalarType for Types.VARBINARY to byte[]. */ -public class ScalarTypeBytesVarbinary extends ScalarTypeBytesBase { +public final class ScalarTypeBytesVarbinary extends ScalarTypeBytesBase { public ScalarTypeBytesVarbinary() { super(true, Types.VARBINARY); 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 c0c67e7f8..bbefa5a83 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 @@ -16,7 +16,7 @@ import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.formatIso; /** * ScalarType for java.util.Calendar. */ -public class ScalarTypeCalendar extends ScalarTypeBaseDateTime { +public final class ScalarTypeCalendar extends ScalarTypeBaseDateTime { public ScalarTypeCalendar(JsonConfig.DateTime mode, int jdbcType) { super(mode, Calendar.class, false, jdbcType); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeChar.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeChar.java index 509506298..f5fe00954 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeChar.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeChar.java @@ -10,7 +10,7 @@ import java.sql.Types; /** * ScalarType for char. */ -public class ScalarTypeChar extends ScalarTypeBaseVarchar { +public final class ScalarTypeChar extends ScalarTypeBaseVarchar { public ScalarTypeChar() { super(char.class, false, Types.VARCHAR); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCharArray.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCharArray.java index dedb38838..ebfd69a6f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCharArray.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCharArray.java @@ -13,7 +13,7 @@ import java.sql.Types; /** * ScalarType for char[]. */ -public class ScalarTypeCharArray extends ScalarTypeBaseVarchar { +public final class ScalarTypeCharArray extends ScalarTypeBaseVarchar { public ScalarTypeCharArray() { super(char[].class, false, Types.VARCHAR); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCidr.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCidr.java index 1d303a157..390ac22c7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCidr.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCidr.java @@ -42,7 +42,7 @@ public abstract class ScalarTypeCidr extends ScalarTypeBaseVarchar { /** * Cidr to Varchar. */ - public static class Varchar extends ScalarTypeCidr { + public static final class Varchar extends ScalarTypeCidr { @Override public void bind(DataBinder binder, Cidr value) throws SQLException { @@ -57,7 +57,7 @@ public abstract class ScalarTypeCidr extends ScalarTypeBaseVarchar { /** * Cidr to Postgres CIDR. */ - public static class Postgres extends ScalarTypeCidr { + public static final class Postgres extends ScalarTypeCidr { @Override public void bind(DataBinder binder, Cidr value) throws SQLException { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeClass.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeClass.java index 112e08459..78f4a19de 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeClass.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeClass.java @@ -4,12 +4,9 @@ import javax.persistence.PersistenceException; /** * ScalarType for Class that persists it to VARCHAR column. - * - * @author emcgreal - * @author rbygrave */ @SuppressWarnings({"rawtypes"}) -public class ScalarTypeClass extends ScalarTypeBaseVarchar { +public final class ScalarTypeClass extends ScalarTypeBaseVarchar { public ScalarTypeClass() { super(Class.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCurrency.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCurrency.java index 6ed58b133..0eaeb8602 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCurrency.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCurrency.java @@ -5,7 +5,7 @@ import java.util.Currency; /** * ScalarType for java.util.Currency which converts to and from a VARCHAR database column. */ -public class ScalarTypeCurrency extends ScalarTypeBaseVarchar { +public final class ScalarTypeCurrency extends ScalarTypeBaseVarchar { public ScalarTypeCurrency() { super(Currency.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDate.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDate.java index b9d49586f..b69571c11 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDate.java @@ -12,7 +12,7 @@ import java.sql.Types; /** * ScalarType for java.sql.Date. */ -public class ScalarTypeDate extends ScalarTypeBaseDate { +public final class ScalarTypeDate extends ScalarTypeBaseDate { public ScalarTypeDate(JsonConfig.Date mode) { super(mode, Date.class, true, Types.DATE); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDayOfWeek.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDayOfWeek.java index 39c8ada61..1cee17865 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDayOfWeek.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDayOfWeek.java @@ -11,7 +11,7 @@ import java.time.DayOfWeek; /** * ScalarType mapping for Month enum. */ -public class ScalarTypeDayOfWeek extends ScalarTypeEnumWithMapping { +public final class ScalarTypeDayOfWeek extends ScalarTypeEnumWithMapping { static final EnumToDbIntegerMap beanDbMap = new EnumToDbIntegerMap(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDouble.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDouble.java index 14f825413..02adb9de8 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDouble.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDouble.java @@ -16,7 +16,7 @@ import java.sql.Types; /** * ScalarType for Double and double. */ -public class ScalarTypeDouble extends ScalarTypeBase { +public final class ScalarTypeDouble extends ScalarTypeBase { public ScalarTypeDouble() { super(Double.class, true, Types.DOUBLE); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDurationWithNanos.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDurationWithNanos.java index faeca10a5..2f99708b3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDurationWithNanos.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDurationWithNanos.java @@ -15,7 +15,7 @@ import java.time.Duration; * Stored in the DB as DECIMAL value. *

*/ -public class ScalarTypeDurationWithNanos extends ScalarTypeDuration { +public final class ScalarTypeDurationWithNanos extends ScalarTypeDuration { public ScalarTypeDurationWithNanos() { super(Types.DECIMAL); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEncryptedWrapper.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEncryptedWrapper.java index ba9a44b20..1a552d11a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEncryptedWrapper.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEncryptedWrapper.java @@ -12,12 +12,10 @@ import java.io.DataOutput; import java.io.IOException; import java.sql.SQLException; -public class ScalarTypeEncryptedWrapper implements ScalarType, LocalEncryptedType { +public final class ScalarTypeEncryptedWrapper implements ScalarType, LocalEncryptedType { private final ScalarType wrapped; - private final DataEncryptSupport dataEncryptSupport; - private final ScalarTypeBytesBase byteArrayType; public ScalarTypeEncryptedWrapper(ScalarType wrapped, ScalarTypeBytesBase byteArrayType, DataEncryptSupport dataEncryptSupport) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEnumStandard.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEnumStandard.java index 4c8a5e645..dcdc8d42a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEnumStandard.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEnumStandard.java @@ -28,10 +28,10 @@ import java.util.Set; * Ebean specific @EnumMapping. *

*/ -public class ScalarTypeEnumStandard { +public final class ScalarTypeEnumStandard { @SuppressWarnings({"rawtypes", "unchecked"}) - public static class StringEnum extends EnumBase implements ScalarTypeEnum { + public static final class StringEnum extends EnumBase implements ScalarTypeEnum { private final int length; @@ -63,15 +63,12 @@ public class ScalarTypeEnumStandard { } private int maxValueLength(Class enumType) { - int maxLen = 0; - Object[] ea = enumType.getEnumConstants(); for (Object anEa : ea) { Enum e = (Enum) anEa; maxLen = Math.max(maxLen, e.name().length()); } - return maxLen; } @@ -120,7 +117,7 @@ public class ScalarTypeEnumStandard { } @SuppressWarnings({"rawtypes", "unchecked"}) - public static class OrdinalEnum extends EnumBase implements ScalarTypeEnum { + public static final class OrdinalEnum extends EnumBase implements ScalarTypeEnum { private final Object[] enumArray; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEnumWithMapping.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEnumWithMapping.java index 598889f49..6960d4d09 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEnumWithMapping.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeEnumWithMapping.java @@ -17,9 +17,7 @@ import java.util.Set; public class ScalarTypeEnumWithMapping extends ScalarTypeEnumStandard.EnumBase implements ScalarType, ScalarTypeEnum { private final EnumToDbValueMap beanDbMap; - private final int length; - private final boolean withConstraint; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeFile.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeFile.java index 4dfa68a24..d6f694672 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeFile.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeFile.java @@ -25,16 +25,13 @@ import java.sql.Types; /** * ScalarType for streaming between a File and the database. */ -public class ScalarTypeFile extends ScalarTypeBase { +public final class ScalarTypeFile extends ScalarTypeBase { private static final Logger logger = LoggerFactory.getLogger(ScalarTypeFile.class); private final String prefix; - private final String suffix; - private final File directory; - private final int bufferSize; /** diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeFloat.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeFloat.java index e9f8e1306..d468b74ef 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeFloat.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeFloat.java @@ -16,7 +16,7 @@ import java.sql.Types; /** * ScalarType for Float and float. */ -public class ScalarTypeFloat extends ScalarTypeBase { +public final class ScalarTypeFloat extends ScalarTypeBase { public ScalarTypeFloat() { super(Float.class, true, Types.REAL); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInet.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInet.java index 9252afe6e..9a7b884f4 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInet.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInet.java @@ -42,7 +42,7 @@ public abstract class ScalarTypeInet extends ScalarTypeBaseVarchar { /** * Inet to Varchar. */ - public static class Varchar extends ScalarTypeInet { + public static final class Varchar extends ScalarTypeInet { Varchar() { super(Types.VARCHAR); @@ -61,7 +61,7 @@ public abstract class ScalarTypeInet extends ScalarTypeBaseVarchar { /** * Inet to Postgres INET. */ - public static class Postgres extends ScalarTypeInet { + public static final class Postgres extends ScalarTypeInet { Postgres() { super(ExtraDbTypes.INET); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInetAddress.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInetAddress.java index 1de5e1db7..419f52cd3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInetAddress.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInetAddress.java @@ -7,7 +7,7 @@ import java.net.InetAddress; /** * ScalarType for java.net.URI which converts to and from a VARCHAR database column. */ -public class ScalarTypeInetAddress extends ScalarTypeBaseVarchar { +public final class ScalarTypeInetAddress extends ScalarTypeBaseVarchar { public ScalarTypeInetAddress() { super(InetAddress.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInetAddressPostgres.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInetAddressPostgres.java index 086f4fd45..aba3aa4c9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInetAddressPostgres.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInetAddressPostgres.java @@ -11,7 +11,7 @@ import java.sql.Types; /** * ScalarType for InetAddress to Postgres INET. */ -public class ScalarTypeInetAddressPostgres extends ScalarTypeBaseVarchar { +public final class ScalarTypeInetAddressPostgres extends ScalarTypeBaseVarchar { public ScalarTypeInetAddressPostgres() { super(InetAddress.class, false, ExtraDbTypes.INET); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInstant.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInstant.java index dd78f4a65..0d84af6e1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInstant.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInstant.java @@ -9,7 +9,7 @@ import java.time.Instant; /** * ScalarType for java.sql.Timestamp. */ -public class ScalarTypeInstant extends ScalarTypeBaseDateTime { +public final class ScalarTypeInstant extends ScalarTypeBaseDateTime { public ScalarTypeInstant(JsonConfig.DateTime mode) { super(mode, Instant.class, false, Types.TIMESTAMP); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInteger.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInteger.java index 0d343d05b..cae0de91b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInteger.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeInteger.java @@ -17,7 +17,7 @@ import java.sql.Types; /** * ScalarType for Integer and int. */ -public class ScalarTypeInteger extends ScalarTypeBase { +public final class ScalarTypeInteger extends ScalarTypeBase { public static ScalarTypeInteger INSTANCE = new ScalarTypeInteger(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaDateMidnight.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaDateMidnight.java index bebd64de7..c108b99f1 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaDateMidnight.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaDateMidnight.java @@ -11,7 +11,7 @@ import java.sql.Types; * ScalarType for Joda DateMidnight. This maps to a JDBC Date. */ @SuppressWarnings("deprecation") -public class ScalarTypeJodaDateMidnight extends ScalarTypeBaseDate { +public final class ScalarTypeJodaDateMidnight extends ScalarTypeBaseDate { /** * Instantiates a new scalar type joda date midnight. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaDateTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaDateTime.java index f8d9816ae..2ca296ed0 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaDateTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaDateTime.java @@ -11,7 +11,7 @@ import java.time.Instant; /** * ScalarType for Joda DateTime. This maps to a JDBC Timestamp. */ -public class ScalarTypeJodaDateTime extends ScalarTypeBaseDateTime { +public final class ScalarTypeJodaDateTime extends ScalarTypeBaseDateTime { public ScalarTypeJodaDateTime(JsonConfig.DateTime mode) { super(mode, DateTime.class, false, Types.TIMESTAMP); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalDate.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalDate.java index 4727f1d58..09acb797e 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalDate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalDate.java @@ -11,7 +11,7 @@ import java.sql.Types; /** * ScalarType for Joda LocalDate. This maps to a JDBC Date. */ -public class ScalarTypeJodaLocalDate extends ScalarTypeBaseDate { +public final class ScalarTypeJodaLocalDate extends ScalarTypeBaseDate { public ScalarTypeJodaLocalDate(JsonConfig.Date mode) { super(mode, LocalDate.class, false, Types.DATE); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalDateTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalDateTime.java index bb5db7e37..5d537dc9c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalDateTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalDateTime.java @@ -11,7 +11,7 @@ import java.time.Instant; /** * ScalarType for Joda LocalDateTime. This maps to a JDBC Timestamp. */ -public class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime { +public final class ScalarTypeJodaLocalDateTime extends ScalarTypeBaseDateTime { public ScalarTypeJodaLocalDateTime(JsonConfig.DateTime mode) { super(mode, LocalDateTime.class, false, Types.TIMESTAMP); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalTimeUTC.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalTimeUTC.java index 1cf2656a0..4de3c513a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalTimeUTC.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaLocalTimeUTC.java @@ -13,7 +13,7 @@ import java.sql.Types; /** * ScalarType for Joda LocalTime. This maps to a JDBC Time. */ -public class ScalarTypeJodaLocalTimeUTC extends ScalarTypeJodaLocalTime { +public final class ScalarTypeJodaLocalTimeUTC extends ScalarTypeJodaLocalTime { public ScalarTypeJodaLocalTimeUTC() { super(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaPeriod.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaPeriod.java index 5d3e3ee4e..2dc09a233 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaPeriod.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJodaPeriod.java @@ -5,7 +5,7 @@ import org.joda.time.Period; /** * ScalarType for Joda Period stored as DB VARCHAR */ -public class ScalarTypeJodaPeriod extends ScalarTypeBaseVarchar { +public final class ScalarTypeJodaPeriod extends ScalarTypeBaseVarchar { public ScalarTypeJodaPeriod() { super(Period.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java index d3c700443..71179dba7 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonList.java @@ -19,7 +19,7 @@ import java.util.List; /** * Types for mapping List in JSON format to DB types VARCHAR, JSON and JSONB. */ -class ScalarTypeJsonList { +final class ScalarTypeJsonList { /** * Return the appropriate ScalarType based requested dbType and if Postgres. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonNode.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonNode.java index 5ff3ef99a..9c3950b94 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonNode.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonNode.java @@ -27,7 +27,7 @@ public abstract class ScalarTypeJsonNode extends ScalarTypeBase { /** * Clob storage based implementation. */ - public static class Clob extends ScalarTypeJsonNode { + public static final class Clob extends ScalarTypeJsonNode { public Clob(ObjectMapper objectMapper) { super(objectMapper, Types.CLOB); @@ -46,7 +46,7 @@ public abstract class ScalarTypeJsonNode extends ScalarTypeBase { /** * Varchar storage based implementation. */ - public static class Varchar extends ScalarTypeJsonNode { + public static final class Varchar extends ScalarTypeJsonNode { public Varchar(ObjectMapper objectMapper) { super(objectMapper, Types.VARCHAR); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonNodePostgres.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonNodePostgres.java index f24178aab..94d46a67d 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonNodePostgres.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeJsonNodePostgres.java @@ -31,7 +31,7 @@ public abstract class ScalarTypeJsonNodePostgres extends ScalarTypeJsonNode { /** * ScalarType mapping JsonNode to Postgres JSON database type. */ - public static class JSON extends ScalarTypeJsonNodePostgres { + public static final class JSON extends ScalarTypeJsonNodePostgres { public JSON(ObjectMapper objectMapper) { super(objectMapper, DbPlatformType.JSON, PostgresHelper.JSON_TYPE); @@ -41,7 +41,7 @@ public abstract class ScalarTypeJsonNodePostgres extends ScalarTypeJsonNode { /** * ScalarType mapping JsonNode to Postgres JSONB database type. */ - public static class JSONB extends ScalarTypeJsonNodePostgres { + public static final class JSONB extends ScalarTypeJsonNodePostgres { public JSONB(ObjectMapper objectMapper) { super(objectMapper, DbPlatformType.JSONB, PostgresHelper.JSONB_TYPE); 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 65cb88cdc..5cda3f921 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 @@ -25,7 +25,7 @@ import java.sql.Types; /** * Supports @DbJson properties using Jackson ObjectMapper. */ -class ScalarTypeJsonObjectMapper { +final class ScalarTypeJsonObjectMapper { /** * Create and return the appropriate ScalarType. diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalDate.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalDate.java index eca6102fa..4fd228459 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalDate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalDate.java @@ -13,7 +13,7 @@ import java.time.ZonedDateTime; /** * ScalarType for java.time.LocalDate. This maps to a JDBC Date. */ -public class ScalarTypeLocalDate extends ScalarTypeBaseDate { +public final class ScalarTypeLocalDate extends ScalarTypeBaseDate { public ScalarTypeLocalDate(JsonConfig.Date mode) { super(mode, LocalDate.class, false, Types.DATE); 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 12b884e82..e03c67898 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 @@ -14,7 +14,7 @@ import java.time.ZoneId; /** * ScalarType for java.sql.Timestamp. */ -public class ScalarTypeLocalDateTime extends ScalarTypeBaseDateTime { +public final class ScalarTypeLocalDateTime extends ScalarTypeBaseDateTime { public ScalarTypeLocalDateTime(JsonConfig.DateTime mode) { super(mode, LocalDateTime.class, false, Types.TIMESTAMP); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanos.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanos.java index 0633fe19c..2a86abbfa 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanos.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocalTimeWithNanos.java @@ -11,7 +11,7 @@ import java.time.LocalTime; /** * ScalarType for java.time.LocalTime stored with Nanos as DB BIGINT type. */ -public class ScalarTypeLocalTimeWithNanos extends ScalarTypeLocalTime { +public final class ScalarTypeLocalTimeWithNanos extends ScalarTypeLocalTime { public ScalarTypeLocalTimeWithNanos() { super(Types.BIGINT); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocale.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocale.java index 438ddaf6a..cc1a4c166 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocale.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLocale.java @@ -5,7 +5,7 @@ import java.util.Locale; /** * ScalarType for java.util.Currency which converts to and from a VARCHAR database column. */ -public class ScalarTypeLocale extends ScalarTypeBaseVarchar { +public final class ScalarTypeLocale extends ScalarTypeBaseVarchar { public ScalarTypeLocale() { super(Locale.class); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLong.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLong.java index 26c272f54..697e84376 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLong.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLong.java @@ -16,7 +16,7 @@ import java.sql.Types; /** * ScalarType for Long and long. */ -public class ScalarTypeLong extends ScalarTypeBase { +public final class ScalarTypeLong extends ScalarTypeBase { public ScalarTypeLong() { super(Long.class, true, Types.BIGINT); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLongVarchar.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLongVarchar.java index 9bde5947f..9dd621d36 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLongVarchar.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeLongVarchar.java @@ -5,7 +5,7 @@ import java.sql.Types; /** * ScalarType for String. */ -public class ScalarTypeLongVarchar extends ScalarTypeClob { +public final class ScalarTypeLongVarchar extends ScalarTypeClob { public ScalarTypeLongVarchar() { super(true, Types.LONGVARCHAR); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMathBigInteger.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMathBigInteger.java index bb101706f..3c5b99255 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMathBigInteger.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMathBigInteger.java @@ -17,7 +17,7 @@ import java.sql.Types; /** * ScalarType for java.math.BigInteger. */ -public class ScalarTypeMathBigInteger extends ScalarTypeBase { +public final class ScalarTypeMathBigInteger extends ScalarTypeBase { public ScalarTypeMathBigInteger() { super(BigInteger.class, false, Types.BIGINT); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMonth.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMonth.java index 2707c88f1..a04925ebc 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMonth.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMonth.java @@ -11,7 +11,7 @@ import java.time.Month; /** * ScalarType mapping for Month enum. */ -public class ScalarTypeMonth extends ScalarTypeEnumWithMapping { +public final class ScalarTypeMonth extends ScalarTypeEnumWithMapping { static final EnumToDbIntegerMap beanDbMap = new EnumToDbIntegerMap(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMonthDay.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMonthDay.java index acebb04e9..eb26a84b9 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMonthDay.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeMonthDay.java @@ -21,24 +21,14 @@ import java.time.MonthDay; * Note that the year used should be a leap year. *

*/ -public class ScalarTypeMonthDay extends ScalarTypeBase { - - protected final int year; - - /** - * Construct with a year of 2000 (which is a leap year). - */ - public ScalarTypeMonthDay() { - this(2000); // Year 2000 is a leap year - } +final class ScalarTypeMonthDay extends ScalarTypeBase { /** * Construct with a base year. The year should be a leap year to * allow the 29th Feb value. */ - public ScalarTypeMonthDay(int year) { + ScalarTypeMonthDay() { super(MonthDay.class, false, Types.DATE); - this.year = year; } private MonthDay convertFromDate(Date ts) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java index b68f3eba9..f7e151238 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java @@ -13,11 +13,11 @@ import static io.ebeaninternal.server.type.IsoJsonDateTimeParser.formatIso; /** * ScalarType for java.sql.Timestamp. */ -public class ScalarTypeOffsetDateTime extends ScalarTypeBaseDateTime { +final class ScalarTypeOffsetDateTime extends ScalarTypeBaseDateTime { private final ZoneId zoneId; - public ScalarTypeOffsetDateTime(JsonConfig.DateTime mode, ZoneId zoneId) { + ScalarTypeOffsetDateTime(JsonConfig.DateTime mode, ZoneId zoneId) { super(mode, OffsetDateTime.class, false, Types.TIMESTAMP); this.zoneId = zoneId; } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetTime.java index 2cb3a6f35..e1f241b51 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetTime.java @@ -5,9 +5,9 @@ import java.time.OffsetTime; /** * ScalarType for java.time.OffsetTime stored as DB VARCHAR */ -public class ScalarTypeOffsetTime extends ScalarTypeBaseVarchar { +final class ScalarTypeOffsetTime extends ScalarTypeBaseVarchar { - public ScalarTypeOffsetTime() { + ScalarTypeOffsetTime() { super(OffsetTime.class); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePath.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePath.java index c5ca8951d..a5e318881 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePath.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePath.java @@ -8,9 +8,9 @@ import java.nio.file.Paths; /** * ScalarType for java.nio.file.Path which converts to and from a VARCHAR database column. */ -public class ScalarTypePath extends ScalarTypeBaseVarchar { +final class ScalarTypePath extends ScalarTypeBaseVarchar { - public ScalarTypePath() { + ScalarTypePath() { super(Path.class); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePeriod.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePeriod.java index 573ba6e5c..9b0175173 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePeriod.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePeriod.java @@ -5,9 +5,9 @@ import java.time.Period; /** * ScalarType for Joda Period stored as DB VARCHAR */ -public class ScalarTypePeriod extends ScalarTypeBaseVarchar { +final class ScalarTypePeriod extends ScalarTypeBaseVarchar { - public ScalarTypePeriod() { + ScalarTypePeriod() { super(Period.class); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePostgresHstore.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePostgresHstore.java index 14d2c50d3..69b3d8a5b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePostgresHstore.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypePostgresHstore.java @@ -20,9 +20,9 @@ import java.util.Map; * Postgres Hstore type which maps Map to a single 'HStore column' in the DB. */ @SuppressWarnings("rawtypes") -public class ScalarTypePostgresHstore extends ScalarTypeBase { +final class ScalarTypePostgresHstore extends ScalarTypeBase { - public ScalarTypePostgresHstore() { + ScalarTypePostgresHstore() { super(Map.class, false, DbPlatformType.HSTORE); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeShort.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeShort.java index 43d7dac80..b3205b747 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeShort.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeShort.java @@ -17,9 +17,9 @@ import java.sql.Types; /** * ScalarType for Short and short. */ -public class ScalarTypeShort extends ScalarTypeBase { +final class ScalarTypeShort extends ScalarTypeBase { - public ScalarTypeShort() { + ScalarTypeShort() { super(Short.class, true, Types.SMALLINT); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeString.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeString.java index 3ee87d9d9..d57bf253b 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeString.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeString.java @@ -5,7 +5,7 @@ import java.sql.Types; /** * ScalarType for String. */ -public class ScalarTypeString extends ScalarTypeStringBase { +public final class ScalarTypeString extends ScalarTypeStringBase { public static final ScalarTypeString INSTANCE = new ScalarTypeString(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeStringBase.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeStringBase.java index 50b0d980d..d0ea5a278 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeStringBase.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeStringBase.java @@ -16,7 +16,7 @@ import java.sql.Types; /** * Base ScalarType for String type using Varchar, Clob and LongVarchar. */ -public abstract class ScalarTypeStringBase extends ScalarTypeBase { +abstract class ScalarTypeStringBase extends ScalarTypeBase { ScalarTypeStringBase(boolean jdbcNative, int jdbcType) { super(String.class, jdbcNative, jdbcType); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeTime.java index 4664d79ed..8328edfbe 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeTime.java @@ -17,9 +17,9 @@ import java.sql.Types; /** * ScalarType for java.sql.Time. */ -public class ScalarTypeTime extends ScalarTypeBase