Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 25F44200C3A for ; Fri, 31 Mar 2017 16:02:12 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 24606160B8C; Fri, 31 Mar 2017 14:02:12 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id C77BB160B79 for ; Fri, 31 Mar 2017 16:02:09 +0200 (CEST) Received: (qmail 51486 invoked by uid 500); 31 Mar 2017 14:02:09 -0000 Mailing-List: contact commits-help@cayenne.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cayenne.apache.org Delivered-To: mailing list commits@cayenne.apache.org Received: (qmail 51477 invoked by uid 99); 31 Mar 2017 14:02:08 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 31 Mar 2017 14:02:08 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id C9D8EDFE59; Fri, 31 Mar 2017 14:02:08 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ntimofeev@apache.org To: commits@cayenne.apache.org Date: Fri, 31 Mar 2017 14:02:08 -0000 Message-Id: <3f2db98ca05443d08706027a5a265eb6@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/2] cayenne git commit: CAY-2210 Query cache: incorrect cache key for queries with custom value objects archived-at: Fri, 31 Mar 2017 14:02:12 -0000 Repository: cayenne Updated Branches: refs/heads/master 4911ad11d -> 5e9f0e0f6 http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java index 61ba17b..74b8109 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java @@ -35,13 +35,14 @@ import org.apache.cayenne.access.translator.batch.DefaultBatchTranslatorFactory; import org.apache.cayenne.access.translator.select.DefaultSelectTranslatorFactory; import org.apache.cayenne.access.translator.select.SelectTranslatorFactory; import org.apache.cayenne.access.types.BigDecimalType; -import org.apache.cayenne.access.types.BigIntegerType; +import org.apache.cayenne.access.types.BigIntegerValueType; import org.apache.cayenne.access.types.BooleanType; import org.apache.cayenne.access.types.ByteArrayType; import org.apache.cayenne.access.types.ByteType; import org.apache.cayenne.access.types.CalendarType; import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.DateType; +import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry; import org.apache.cayenne.access.types.DoubleType; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; @@ -51,8 +52,9 @@ import org.apache.cayenne.access.types.LongType; import org.apache.cayenne.access.types.ShortType; import org.apache.cayenne.access.types.TimeType; import org.apache.cayenne.access.types.TimestampType; -import org.apache.cayenne.access.types.UUIDType; +import org.apache.cayenne.access.types.UUIDValueType; import org.apache.cayenne.access.types.UtilDateType; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.access.types.VoidType; import org.apache.cayenne.ashwood.AshwoodEntitySorter; import org.apache.cayenne.cache.MapQueryCacheProvider; @@ -101,6 +103,7 @@ import org.apache.cayenne.event.EventManager; import org.apache.cayenne.log.CommonsJdbcEventLogger; import org.apache.cayenne.log.JdbcEventLogger; import org.apache.cayenne.map.EntitySorter; +import org.apache.cayenne.access.types.ValueObjectType; import org.apache.cayenne.resource.ClassLoaderResourceLocator; import org.apache.cayenne.resource.ResourceLocator; import org.apache.cayenne.tx.DefaultTransactionFactory; @@ -245,6 +248,16 @@ public class ServerModule implements Module { } /** + * + * @param binder DI binder passed to module during injector startup + * @return ListBuilder for user-contributed ValueObjectTypes + * @since 4.0 + */ + public static ListBuilder contributeValueObjectTypes(Binder binder) { + return binder.bindList(ValueObjectType.class); + } + + /** * Creates a new {@link ServerModule}. * * @since 4.0 @@ -300,16 +313,24 @@ public class ServerModule implements Module { contributeDomainListeners(binder); // configure extended types - contributeDefaultTypes(binder).add(new VoidType()).add(new BigDecimalType()) - .add(new BigIntegerType()).add(new BooleanType()).add(new ByteArrayType(false, true)) - .add(new ByteType(false)).add(new CharType(false, true)).add(new DateType()).add(new DoubleType()) - .add(new FloatType()).add(new IntegerType()).add(new LongType()).add(new ShortType(false)) - .add(new TimeType()).add(new TimestampType()).add(new UtilDateType()) - .add(new CalendarType(GregorianCalendar.class)) - .add(new CalendarType(Calendar.class)).add(new UUIDType()); + contributeDefaultTypes(binder) + .add(new VoidType()) + .add(new BigDecimalType()) + .add(new BooleanType()).add(new ByteType(false)).add(new CharType(false, true)) + .add(new DoubleType()).add(new FloatType()).add(new IntegerType()).add(new LongType()).add(new ShortType(false)) + .add(new ByteArrayType(false, true)) + .add(new DateType()).add(new TimeType()).add(new TimestampType()) + // should be converted from ExtendedType to ValueType + .add(new UtilDateType()).add(new CalendarType<>(GregorianCalendar.class)).add(new CalendarType<>(Calendar.class)); contributeUserTypes(binder); contributeTypeFactories(binder); + // Custom ValueObjects types contribution + contributeValueObjectTypes(binder) + .add(BigIntegerValueType.class) + .add(UUIDValueType.class); + binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class); + // configure explicit configurations ListBuilder locationsListBuilder = contributeProjectLocations(binder); for (String location : configurationLocations) { http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java index 01e244e..b163a88 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcAdapter.java @@ -32,6 +32,8 @@ import org.apache.cayenne.access.translator.select.SelectTranslator; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeFactory; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.di.Inject; @@ -78,8 +80,7 @@ public class JdbcAdapter implements DbAdapter { /** * @since 3.1 - * @deprecated since 4.0 BatchQueryBuilderfactory is attached to the - * DataNode. + * @deprecated since 4.0 BatchQueryBuilderfactory is attached to the DataNode. */ @Inject protected BatchTranslatorFactory batchQueryBuilderFactory; @@ -94,7 +95,8 @@ public class JdbcAdapter implements DbAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { // init defaults this.setSupportsBatchUpdates(false); @@ -108,7 +110,7 @@ public class JdbcAdapter implements DbAdapter { this.ejbqlTranslatorFactory = createEJBQLTranslatorFactory(); this.typesHandler = TypesHandler.getHandler(findResource("/types.xml")); this.extendedTypes = new ExtendedTypeMap(); - initExtendedTypes(defaultExtendedTypes, userExtendedTypes, extendedTypeFactories); + initExtendedTypes(defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, valueObjectTypeRegistry); } /** @@ -159,7 +161,7 @@ public class JdbcAdapter implements DbAdapter { } /** - * Called from {@link #initExtendedTypes(List, List, List)} to load + * Called from {@link #initExtendedTypes(List, List, List, ValueObjectTypeRegistry)} to load * adapter-specific types into the ExtendedTypeMap right after the default * types are loaded, but before the DI overrides are. This method has * specific implementations in JdbcAdapter subclasses. @@ -172,7 +174,8 @@ public class JdbcAdapter implements DbAdapter { * @since 3.1 */ protected void initExtendedTypes(List defaultExtendedTypes, List userExtendedTypes, - List extendedTypeFactories) { + List extendedTypeFactories, + ValueObjectTypeRegistry valueObjectTypeRegistry) { for (ExtendedType type : defaultExtendedTypes) { extendedTypes.registerType(type); } @@ -186,6 +189,7 @@ public class JdbcAdapter implements DbAdapter { for (ExtendedTypeFactory typeFactory : extendedTypeFactories) { extendedTypes.addFactory(typeFactory); } + extendedTypes.addFactory(new ValueObjectTypeFactory(extendedTypes, valueObjectTypeRegistry)); } /** @@ -285,11 +289,7 @@ public class JdbcAdapter implements DbAdapter { */ @Override public Collection dropTableStatements(DbEntity table) { - - StringBuilder buf = new StringBuilder("DROP TABLE "); - buf.append(quotingStrategy.quotedFullyQualifiedName(table)); - - return Collections.singleton(buf.toString()); + return Collections.singleton("DROP TABLE " + quotingStrategy.quotedFullyQualifiedName(table)); } /** http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java index d1415bf..7ac6dec 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2Adapter.java @@ -36,6 +36,7 @@ import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -67,8 +68,9 @@ public class DB2Adapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); setSupportsGeneratedKeys(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java index bca04a1..d2bb67e 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java @@ -31,6 +31,7 @@ import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; import org.apache.cayenne.access.types.ShortType; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -72,13 +73,15 @@ public class DerbyAdapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { super( runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, - resourceLocator); + resourceLocator, + valueObjectTypeRegistry); setSupportsGeneratedKeys(true); setSupportsBatchUpdates(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java index ae754d5..a878be2 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/firebird/FirebirdAdapter.java @@ -28,6 +28,7 @@ import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -58,13 +59,15 @@ public class FirebirdAdapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { super( runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, - resourceLocator); + resourceLocator, + valueObjectTypeRegistry); setSupportsBatchUpdates(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseAdapter.java index 564e0ed..69b9876 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/frontbase/FrontBaseAdapter.java @@ -26,6 +26,7 @@ import org.apache.cayenne.access.translator.select.SelectTranslator; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -72,8 +73,9 @@ public class FrontBaseAdapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); setSupportsBatchUpdates(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java index 0d99869..6b47636 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2Adapter.java @@ -21,6 +21,7 @@ package org.apache.cayenne.dba.h2; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -50,8 +51,9 @@ public class H2Adapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); setSupportsGeneratedKeys(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java index 314de60..64c59b3 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBAdapter.java @@ -31,6 +31,7 @@ import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -72,8 +73,9 @@ public class HSQLDBAdapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); setSupportsGeneratedKeys(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBNoSchemaAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBNoSchemaAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBNoSchemaAdapter.java index d963f27..e8b6641 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBNoSchemaAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/hsqldb/HSQLDBNoSchemaAdapter.java @@ -21,6 +21,7 @@ package org.apache.cayenne.dba.hsqldb; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.di.Inject; @@ -42,8 +43,9 @@ public class HSQLDBNoSchemaAdapter extends HSQLDBAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); } /** http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java index 3fc8f07..2c76b2a 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresAdapter.java @@ -29,6 +29,7 @@ import org.apache.cayenne.access.translator.select.TrimmingQualifierTranslator; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -67,8 +68,9 @@ public class IngresAdapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); setSupportsUniqueConstraints(true); setSupportsGeneratedKeys(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java index 1981c2a..6e9529a 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java @@ -32,6 +32,7 @@ import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.DefaultQuotingStrategy; @@ -88,11 +89,12 @@ public class MySQLAdapter extends JdbcAdapter { protected String storageEngine; public MySQLAdapter(@Inject RuntimeProperties runtimeProperties, - @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, - @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, - @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, + @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, + @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); // init defaults this.storageEngine = DEFAULT_STORAGE_ENGINE; http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java index 04d54cc..1a30779 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/openbase/OpenBaseAdapter.java @@ -35,6 +35,7 @@ import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -68,8 +69,9 @@ public class OpenBaseAdapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); // init defaults this.setSupportsUniqueConstraints(false); http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8Adapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8Adapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8Adapter.java index 13ef0f7..60f820e 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8Adapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/Oracle8Adapter.java @@ -25,6 +25,7 @@ import org.apache.cayenne.access.translator.select.QueryAssembler; import org.apache.cayenne.access.translator.select.SelectTranslator; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.di.Inject; @@ -54,11 +55,12 @@ public class Oracle8Adapter extends OracleAdapter { } public Oracle8Adapter(@Inject RuntimeProperties runtimeProperties, - @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, - @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, - @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, + @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, + @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); } private static void initOracle8DriverInformation() { http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java index 00ff222..f6528c9 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java @@ -31,6 +31,7 @@ import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; import org.apache.cayenne.access.types.ShortType; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -158,11 +159,12 @@ public class OracleAdapter extends JdbcAdapter { } public OracleAdapter(@Inject RuntimeProperties runtimeProperties, - @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, - @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, - @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, + @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, + @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); // enable batch updates by default setSupportsBatchUpdates(true); http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java index b43eb7e..bf3f6b9 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresAdapter.java @@ -29,6 +29,7 @@ import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -69,11 +70,12 @@ public class PostgresAdapter extends JdbcAdapter { public static final String BYTEA = "bytea"; public PostgresAdapter(@Inject RuntimeProperties runtimeProperties, - @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, - @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, - @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, + @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, + @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); setSupportsBatchUpdates(true); setSupportsGeneratedKeys(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java index 1796700..2542282 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteAdapter.java @@ -24,6 +24,7 @@ import org.apache.cayenne.access.translator.select.QueryAssembler; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.JdbcAdapter; @@ -61,13 +62,15 @@ public class SQLiteAdapter extends JdbcAdapter { @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { super( runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, - resourceLocator); + resourceLocator, + valueObjectTypeRegistry); this.setSupportsUniqueConstraints(false); this.setSupportsGeneratedKeys(true); } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java index 3faec45..1a32cf4 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java @@ -25,6 +25,7 @@ import org.apache.cayenne.access.translator.select.QueryAssembler; import org.apache.cayenne.access.translator.select.SelectTranslator; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.sybase.SybaseAdapter; @@ -80,11 +81,12 @@ public class SQLServerAdapter extends SybaseAdapter { public static final String TRIM_FUNCTION = "RTRIM"; public SQLServerAdapter(@Inject RuntimeProperties runtimeProperties, - @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, - @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, - @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, + @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, + @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); // TODO: i wonder if Sybase supports generated keys... // in this case we need to move this to the super. http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseAdapter.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseAdapter.java index 28e948c..886308a 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybaseAdapter.java @@ -36,6 +36,7 @@ import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; import org.apache.cayenne.access.types.ExtendedTypeMap; import org.apache.cayenne.access.types.ShortType; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.DefaultQuotingStrategy; @@ -54,11 +55,12 @@ import org.apache.cayenne.resource.ResourceLocator; public class SybaseAdapter extends JdbcAdapter { public SybaseAdapter(@Inject RuntimeProperties runtimeProperties, - @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, - @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, - @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, - @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) { - super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator); + @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List defaultExtendedTypes, + @Inject(Constants.SERVER_USER_TYPES_LIST) List userExtendedTypes, + @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List extendedTypeFactories, + @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator, + @Inject ValueObjectTypeRegistry valueObjectTypeRegistry) { + super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator, valueObjectTypeRegistry); } @Override http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/map/EntityResolver.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/EntityResolver.java b/cayenne-server/src/main/java/org/apache/cayenne/map/EntityResolver.java index e7f93d8..2458361 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/map/EntityResolver.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/map/EntityResolver.java @@ -21,6 +21,7 @@ package org.apache.cayenne.map; import org.apache.cayenne.ObjectId; import org.apache.cayenne.Persistent; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.query.Query; import org.apache.cayenne.reflect.ClassDescriptor; import org.apache.cayenne.reflect.ClassDescriptorMap; @@ -69,6 +70,8 @@ public class EntityResolver implements MappingNamespace, Serializable { // callbacks are not serializable protected transient LifecycleCallbackRegistry callbackRegistry; + protected transient ValueObjectTypeRegistry valueObjectTypeRegistry; + /** * Creates new empty EntityResolver. */ @@ -661,4 +664,12 @@ public class EntityResolver implements MappingNamespace, Serializable { in.defaultReadObject(); refreshMappingCache(); } + + public ValueObjectTypeRegistry getValueObjectTypeRegistry() { + return valueObjectTypeRegistry; + } + + public void setValueObjectTypeRegistry(ValueObjectTypeRegistry valueObjectTypeRegistry) { + this.valueObjectTypeRegistry = valueObjectTypeRegistry; + } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java index 85de9a8..1c5b04e 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQueryMetadata.java @@ -18,7 +18,6 @@ ****************************************************************/ package org.apache.cayenne.query; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -28,10 +27,17 @@ import java.util.Map; import java.util.Set; import org.apache.cayenne.CayenneRuntimeException; +import org.apache.cayenne.ObjectId; +import org.apache.cayenne.Persistent; +import org.apache.cayenne.access.types.ValueObjectType; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.cayenne.exp.Property; +import org.apache.cayenne.exp.TraversalHandler; import org.apache.cayenne.exp.parser.ASTDbPath; +import org.apache.cayenne.exp.parser.ASTFunctionCall; +import org.apache.cayenne.exp.parser.ASTScalar; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.DbEntity; import org.apache.cayenne.map.DbJoin; @@ -67,14 +73,12 @@ class SelectQueryMetadata extends BaseQueryMetadata { this.pathSplitAliases = new HashMap<>(info.getPathSplitAliases()); } - boolean resolve(Object root, EntityResolver resolver, SelectQuery query) { + boolean resolve(Object root, EntityResolver resolver, SelectQuery query) { if (super.resolve(root, resolver, null)) { - // generate unique cache key, but only if we are caching.. - if (cacheStrategy != null && cacheStrategy != QueryCacheStrategy.NO_CACHE) { - this.cacheKey = makeCacheKey(query); + this.cacheKey = makeCacheKey(query, resolver); } resolveAutoAliases(query); @@ -87,12 +91,14 @@ class SelectQueryMetadata extends BaseQueryMetadata { return false; } - private String makeCacheKey(SelectQuery query) { + private String makeCacheKey(SelectQuery query, EntityResolver resolver) { - // create a unique key based on entity, qualifier, ordering and - // fetch offset and limit + // create a unique key based on entity or columns, qualifier, ordering, fetch offset and limit StringBuilder key = new StringBuilder(); + // handler to create string out of expressions, created lazily + TraversalHandler traversalHandler = null; + ObjEntity entity = getObjEntity(); if (entity != null) { key.append(entity.getName()); @@ -102,23 +108,19 @@ class SelectQueryMetadata extends BaseQueryMetadata { if(query.getColumns() != null && !query.getColumns().isEmpty()) { key.append("/"); + traversalHandler = new ToCacheKeyTraversalHandler(resolver.getValueObjectTypeRegistry(), key); for(Property property : query.getColumns()) { key.append("c:"); - try { - property.getExpression().appendAsString(key); - } catch (IOException e) { - throw new CayenneRuntimeException("Unexpected IO Exception appending to StringBuilder", e); - } + property.getExpression().traverse(traversalHandler); } } if (query.getQualifier() != null) { key.append('/'); - try { - query.getQualifier().appendAsString(key); - } catch (IOException e) { - throw new CayenneRuntimeException("Unexpected IO Exception appending to StringBuilder", e); + if(traversalHandler == null) { + traversalHandler = new ToCacheKeyTraversalHandler(resolver.getValueObjectTypeRegistry(), key); } + query.getQualifier().traverse(traversalHandler); } if (!query.getOrderings().isEmpty()) { @@ -145,10 +147,9 @@ class SelectQueryMetadata extends BaseQueryMetadata { } return key.toString(); - } - private void resolveAutoAliases(SelectQuery query) { + private void resolveAutoAliases(SelectQuery query) { Expression qualifier = query.getQualifier(); if (qualifier != null) { resolveAutoAliases(qualifier); @@ -399,4 +400,79 @@ class SelectQueryMetadata extends BaseQueryMetadata { public void setSuppressingDistinct(boolean suppressingDistinct) { this.suppressingDistinct = suppressingDistinct; } + + /** + * Expression traverse handler to create cache key string out of Expression. + * {@link Expression#appendAsString(Appendable)} where previously used for that, + * but it can't handle custom value objects properly (see CAY-2210). + * + * @see ValueObjectTypeRegistry + * + * @since 4.0 + */ + static class ToCacheKeyTraversalHandler implements TraversalHandler { + + private ValueObjectTypeRegistry registry; + private StringBuilder out; + + ToCacheKeyTraversalHandler(ValueObjectTypeRegistry registry, StringBuilder out) { + this.registry = registry; + this.out = out; + } + + @Override + public void finishedChild(Expression node, int childIndex, boolean hasMoreChildren) { + out.append(','); + } + + @Override + public void startNode(Expression node, Expression parentNode) { + if(node.getType() == Expression.FUNCTION_CALL) { + out.append(((ASTFunctionCall)node).getFunctionName()).append('('); + } else { + out.append(node.getType()).append('('); + } + } + + @Override + public void endNode(Expression node, Expression parentNode) { + out.append(')'); + } + + @Override + public void objectNode(Object leaf, Expression parentNode) { + if(leaf == null) { + out.append("null"); + return; + } + + if(leaf instanceof ASTScalar) { + leaf = ((ASTScalar) leaf).getValue(); + } else if(leaf instanceof Object[]) { + for(Object value : (Object[])leaf) { + objectNode(value, parentNode); + out.append(','); + } + return; + } + + if (leaf instanceof Persistent) { + ObjectId id = ((Persistent) leaf).getObjectId(); + Object encode = (id != null) ? id : leaf; + out.append(encode); + } else if (leaf instanceof Enum) { + Enum e = (Enum) leaf; + out.append("e:").append(leaf.getClass().getName()).append(':').append(e.ordinal()); + } else { + ValueObjectType valueObjectType; + if (registry == null || (valueObjectType = registry.getValueType(leaf.getClass())) == null) { + // Registry will be null in cayenne-client context. + // Maybe we shouldn't create cache key at all in that case... + out.append(leaf); + } else { + out.append(valueObjectType.toCacheKey(leaf)); + } + } + } + }; } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java new file mode 100644 index 0000000..28c7467 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java @@ -0,0 +1,82 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.access.types; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @since 4.0 + */ +public class DefaultValueObjectTypeRegistryTest { + + DefaultValueObjectTypeRegistry registry; + ValueObjectType valueObjectType1, valueObjectType2; + + @Before + public void setUpRegistry() { + valueObjectType1 = mock(ValueObjectType.class); + when(valueObjectType1.getValueType()).thenReturn(Integer.class); + when(valueObjectType1.getTargetType()).thenReturn(Integer.class); + + valueObjectType2 = mock(ValueObjectType.class); + when(valueObjectType2.getValueType()).thenReturn(Number.class); + when(valueObjectType2.getTargetType()).thenReturn(Integer.class); + + List> list = new ArrayList<>(); + list.add(valueObjectType1); + list.add(valueObjectType2); + + registry = new DefaultValueObjectTypeRegistry(list); + } + + @Test + public void testInitialState() { + assertEquals(2, registry.typeCache.size()); + assertTrue(registry.typeCache.containsKey(Integer.class.getName())); + assertTrue(registry.typeCache.containsKey(Number.class.getName())); + assertFalse(registry.typeCache.containsKey(String.class.getName())); + assertFalse(registry.typeCache.containsKey(Float.class.getName())); + } + + @Test + public void getValueType() throws Exception { + ValueObjectType valueObjectType = registry.getValueType(Integer.class); + assertSame(valueObjectType1, valueObjectType); + + valueObjectType = registry.getValueType(Float.class); + assertSame(valueObjectType2, valueObjectType); + + valueObjectType = registry.getValueType(String.class); + assertNull(valueObjectType); + + assertEquals(4, registry.typeCache.size()); + assertTrue(registry.typeCache.containsKey(String.class.getName())); + assertTrue(registry.typeCache.containsKey(Float.class.getName())); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java index af236eb..8a30ae8 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java @@ -36,6 +36,8 @@ import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory; import org.apache.cayenne.access.translator.batch.DefaultBatchTranslatorFactory; import org.apache.cayenne.access.translator.select.DefaultSelectTranslatorFactory; import org.apache.cayenne.access.translator.select.SelectTranslatorFactory; +import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.annotation.PostLoad; import org.apache.cayenne.ashwood.AshwoodEntitySorter; import org.apache.cayenne.cache.QueryCache; @@ -205,6 +207,9 @@ public class DataDomainProviderTest { binder.bind(EventBridge.class).toProvider(NoopEventBridgeProvider.class); binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); + + ServerModule.contributeValueObjectTypes(binder); + binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class); } }; http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDbAdapterFactoryTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDbAdapterFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDbAdapterFactoryTest.java index d03e2e3..a4709c1 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDbAdapterFactoryTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DefaultDbAdapterFactoryTest.java @@ -21,6 +21,8 @@ package org.apache.cayenne.configuration.server; import com.mockrunner.mock.jdbc.MockConnection; import com.mockrunner.mock.jdbc.MockDataSource; import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory; +import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.DataNodeDescriptor; import org.apache.cayenne.configuration.DefaultRuntimeProperties; @@ -119,6 +121,9 @@ public class DefaultDbAdapterFactoryTest { binder.bind(Key.get(ResourceLocator.class, Constants.SERVER_RESOURCE_LOCATOR)).to(ClassLoaderResourceLocator.class); binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); binder.bind(BatchTranslatorFactory.class).toInstance(mock(BatchTranslatorFactory.class)); + + ServerModule.contributeValueObjectTypes(binder); + binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class); } }; @@ -156,6 +161,9 @@ public class DefaultDbAdapterFactoryTest { binder.bind(Key.get(ResourceLocator.class, Constants.SERVER_RESOURCE_LOCATOR)).to(ClassLoaderResourceLocator.class); binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); binder.bind(BatchTranslatorFactory.class).toInstance(mock(BatchTranslatorFactory.class)); + + ServerModule.contributeValueObjectTypes(binder); + binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class); } }; http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/test/java/org/apache/cayenne/dba/PerAdapterProviderTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/dba/PerAdapterProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/dba/PerAdapterProviderTest.java index fb2ebcb..505aefb 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/dba/PerAdapterProviderTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/dba/PerAdapterProviderTest.java @@ -20,6 +20,7 @@ package org.apache.cayenne.dba; import org.apache.cayenne.access.types.ExtendedType; import org.apache.cayenne.access.types.ExtendedTypeFactory; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.configuration.RuntimeProperties; import org.apache.cayenne.dba.derby.DerbyAdapter; import org.apache.cayenne.dba.oracle.OracleAdapter; @@ -49,18 +50,19 @@ public class PerAdapterProviderTest { ResourceLocator locator = new ClassLoaderResourceLocator(new DefaultClassLoaderManager()); RuntimeProperties runtimeProperties = mock(RuntimeProperties.class); + ValueObjectTypeRegistry valueObjectTypeRegistry = mock(ValueObjectTypeRegistry.class); this.oracleAdapter = new OracleAdapter(runtimeProperties, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), - locator); + locator, valueObjectTypeRegistry); this.derbyAdapter = new DerbyAdapter(runtimeProperties, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), - locator); + locator, valueObjectTypeRegistry); this.autoDerbyAdapter = new AutoAdapter(new Provider() { @Override http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryCacheKeyIT.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryCacheKeyIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryCacheKeyIT.java index 6f6a4d1..701ca7b 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryCacheKeyIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryCacheKeyIT.java @@ -30,6 +30,7 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -170,7 +171,7 @@ public class SelectQueryCacheKeyIT extends ServerCase { assertNotNull(q1.getMetaData(resolver).getCacheKey()); assertEquals(q1.getMetaData(resolver).getCacheKey(), q2.getMetaData(resolver).getCacheKey()); - assertFalse(q1.getMetaData(resolver).getCacheKey().equals(q3.getMetaData(resolver).getCacheKey())); + assertNotEquals(q1.getMetaData(resolver).getCacheKey(), q3.getMetaData(resolver).getCacheKey()); } @Test @@ -191,7 +192,7 @@ public class SelectQueryCacheKeyIT extends ServerCase { assertNotNull(q1.getMetaData(resolver).getCacheKey()); assertEquals(q1.getMetaData(resolver).getCacheKey(), q2.getMetaData(resolver).getCacheKey()); - assertFalse(q1.getMetaData(resolver).getCacheKey().equals(q3.getMetaData(resolver).getCacheKey())); + assertNotEquals(q1.getMetaData(resolver).getCacheKey(), q3.getMetaData(resolver).getCacheKey()); } @Test @@ -215,7 +216,7 @@ public class SelectQueryCacheKeyIT extends ServerCase { assertNotNull(q1.getMetaData(resolver).getCacheKey()); assertEquals(q1.getMetaData(resolver).getCacheKey(), q2.getMetaData(resolver).getCacheKey()); - assertFalse(q1.getMetaData(resolver).getCacheKey().equals(q3.getMetaData(resolver).getCacheKey())); - assertFalse(q1.getMetaData(resolver).getCacheKey().equals(q4.getMetaData(resolver).getCacheKey())); + assertNotEquals(q1.getMetaData(resolver).getCacheKey(), q3.getMetaData(resolver).getCacheKey()); + assertNotEquals(q1.getMetaData(resolver).getCacheKey(), q4.getMetaData(resolver).getCacheKey()); } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryMetadataCacheKeyTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryMetadataCacheKeyTest.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryMetadataCacheKeyTest.java new file mode 100644 index 0000000..efd03c4 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryMetadataCacheKeyTest.java @@ -0,0 +1,262 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.query; + +import org.apache.cayenne.ObjectId; +import org.apache.cayenne.Persistent; +import org.apache.cayenne.access.types.ValueObjectType; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; +import org.apache.cayenne.exp.ExpressionFactory; +import org.apache.cayenne.exp.TraversalHandler; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * This class is testing converting Expressions to cache key part. + * + * @since 4.0 + */ +public class SelectQueryMetadataCacheKeyTest { + + private ValueObjectTypeRegistry registry; + private StringBuilder cacheKey; + + @SuppressWarnings("unchecked") + @Before + public void createObjects() { + registry = mock(ValueObjectTypeRegistry.class); + + // mock value type for Double class + ValueObjectType mockType = mock(ValueObjectType.class); + when(mockType.getValueType()).thenReturn(Double.class); + when(mockType.toCacheKey(any())).thenReturn(""); + when(registry.getValueType(eq(Double.class))).thenReturn(mockType); + + // value type for TestValue class + ValueObjectType testType = new TestValueType(); + when(registry.getValueType(eq(TestValue.class))).thenReturn(testType); + } + + /** + * Simple expressions + */ + @Test + public void cacheKeySimple() { + ExpressionFactory.exp("field = 1").traverse(newHandler()); + String s1 = cacheKey.toString(); + + ExpressionFactory.exp("field = 1").traverse(newHandler()); + String s2 = cacheKey.toString(); + + ExpressionFactory.exp("field = 2").traverse(newHandler()); + String s3 = cacheKey.toString(); + + assertEquals(s1, s2); + assertNotEquals(s2, s3); + } + + /** + * Expressions with list of simple values + */ + @Test + public void cacheKeyWithList() { + ExpressionFactory.exp("field in (1,2,3)").traverse(newHandler()); + String s1 = cacheKey.toString(); + + ExpressionFactory.exp("field in (1,2,3)").traverse(newHandler()); + String s2 = cacheKey.toString(); + + ExpressionFactory.exp("field in (2,3,4)").traverse(newHandler()); + String s3 = cacheKey.toString(); + + assertEquals(s1, s2); + assertNotEquals(s2, s3); + } + + /** + * Simple test for custom value object, Double.class is marked as a custom value object. + */ + @Test + public void cacheKeyWithValueObjectSimple() { + ExpressionFactory.exp("field = 1.0").traverse(newHandler()); + String s1 = cacheKey.toString(); + + assertTrue(s1.contains("")); + } + + /** + * List of value objects, Double.class is marked as a custom value object. + */ + @Test + public void cacheKeyWithValueObjectList() { + ExpressionFactory.exp("field in (1.0,2.0,3.0)").traverse(newHandler()); + String s1 = cacheKey.toString(); + + assertTrue(s1.contains("")); + } + + @Test + public void cacheKeyWithEnumValue() { + ExpressionFactory.greaterOrEqualExp("testPath", TestEnum.VALUE_1).traverse(newHandler()); + String s1 = cacheKey.toString(); + + ExpressionFactory.greaterOrEqualExp("testPath", TestEnum.VALUE_1).traverse(newHandler()); + String s2 = cacheKey.toString(); + + ExpressionFactory.greaterOrEqualExp("testPath", TestEnum.VALUE_2).traverse(newHandler()); + String s3 = cacheKey.toString(); + + assertEquals(s1, s2); + assertNotEquals(s2, s3); + } + + @Test + public void cacheKeyWithValueObject() { + ExpressionFactory.greaterOrEqualExp("testPath", new TestValue(1)).traverse(newHandler()); + String s1 = cacheKey.toString(); + + ExpressionFactory.greaterOrEqualExp("testPath", new TestValue(1)).traverse(newHandler()); + String s2 = cacheKey.toString(); + + ExpressionFactory.greaterOrEqualExp("testPath", new TestValue(2)).traverse(newHandler()); + String s3 = cacheKey.toString(); + + assertEquals(s1, s2); + assertNotEquals(s2, s3); + } + + /** + * Persistent objects should be converted to their ObjectIds. + */ + @Test + public void cacheKeyWithPersistentObject() { + Persistent persistent1 = mock(Persistent.class); + ObjectId objectId1 = mock(ObjectId.class); + when(objectId1.toString()).thenReturn("objId1"); + when(persistent1.getObjectId()).thenReturn(objectId1); + + Persistent persistent2 = mock(Persistent.class); + ObjectId objectId2 = mock(ObjectId.class); + when(objectId2.toString()).thenReturn("objId2"); + when(persistent2.getObjectId()).thenReturn(objectId2); + + ExpressionFactory.greaterOrEqualExp("testPath", persistent1).traverse(newHandler()); + String s1 = cacheKey.toString(); + + ExpressionFactory.greaterOrEqualExp("testPath", persistent1).traverse(newHandler()); + String s2 = cacheKey.toString(); + + ExpressionFactory.greaterOrEqualExp("testPath", persistent2).traverse(newHandler()); + String s3 = cacheKey.toString(); + + assertTrue(s1.contains("objId1")); + assertTrue(s3.contains("objId2")); + assertEquals(s1, s2); + assertNotEquals(s2, s3); + } + + @Test + public void cacheKeyWithFunctionCall() { + ExpressionFactory.exp("length(testPath)").traverse(newHandler()); + String s1 = cacheKey.toString(); + + ExpressionFactory.exp("length(testPath)").traverse(newHandler()); + String s2 = cacheKey.toString(); + + ExpressionFactory.exp("count(testPath)").traverse(newHandler()); + String s3 = cacheKey.toString(); + + assertEquals(s1, s2); + assertNotEquals(s2, s3); + + ExpressionFactory.exp("substring(path, testPath)").traverse(newHandler()); + String s4 = cacheKey.toString(); + + ExpressionFactory.exp("substring(path2, testPath)").traverse(newHandler()); + String s5 = cacheKey.toString(); + + assertNotEquals(s4, s5); + + ExpressionFactory.exp("year(path)").traverse(newHandler()); + String s6 = cacheKey.toString(); + + ExpressionFactory.exp("hour(path)").traverse(newHandler()); + String s7 = cacheKey.toString(); + + assertNotEquals(s6, s7); + } + + private TraversalHandler newHandler() { + return new SelectQueryMetadata.ToCacheKeyTraversalHandler(registry, cacheKey = new StringBuilder()); + } + + /* ************* Test types *************** */ + + /** + * Test enum + */ + enum TestEnum { VALUE_1, VALUE_2 } + + /** + * Test value object + */ + static class TestValue { + int v = 0; + TestValue(int v) { + this.v = v; + } + } + + /** + * Test value object descriptor, we need only toCacheKey() method + */ + static class TestValueType implements ValueObjectType { + @Override + public Class getTargetType() { + throw new UnsupportedOperationException(); + } + + @Override + public Class getValueType() { + throw new UnsupportedOperationException(); + } + + @Override + public TestValue toJavaObject(Integer value) { + throw new UnsupportedOperationException(); + } + + @Override + public Integer fromJavaObject(TestValue object) { + throw new UnsupportedOperationException(); + } + + @Override + public String toCacheKey(TestValue object) { + return Integer.toString(object.v); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java index 553807f..7e1f2dd 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/unit/di/server/ServerCaseModule.java @@ -25,13 +25,14 @@ import org.apache.cayenne.access.DefaultObjectMapRetainStrategy; import org.apache.cayenne.access.ObjectMapRetainStrategy; import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory; import org.apache.cayenne.access.types.BigDecimalType; -import org.apache.cayenne.access.types.BigIntegerType; +import org.apache.cayenne.access.types.BigIntegerValueType; import org.apache.cayenne.access.types.BooleanType; import org.apache.cayenne.access.types.ByteArrayType; import org.apache.cayenne.access.types.ByteType; import org.apache.cayenne.access.types.CalendarType; import org.apache.cayenne.access.types.CharType; import org.apache.cayenne.access.types.DateType; +import org.apache.cayenne.access.types.DefaultValueObjectTypeRegistry; import org.apache.cayenne.access.types.DoubleType; import org.apache.cayenne.access.types.FloatType; import org.apache.cayenne.access.types.IntegerType; @@ -39,8 +40,9 @@ import org.apache.cayenne.access.types.LongType; import org.apache.cayenne.access.types.ShortType; import org.apache.cayenne.access.types.TimeType; import org.apache.cayenne.access.types.TimestampType; -import org.apache.cayenne.access.types.UUIDType; +import org.apache.cayenne.access.types.UUIDValueType; import org.apache.cayenne.access.types.UtilDateType; +import org.apache.cayenne.access.types.ValueObjectTypeRegistry; import org.apache.cayenne.access.types.VoidType; import org.apache.cayenne.configuration.ConfigurationNameMapper; import org.apache.cayenne.configuration.Constants; @@ -124,44 +126,28 @@ public class ServerCaseModule implements Module { // unit test injector. ServerRuntime injector contents are customized // inside ServerRuntimeProvider. - binder.bindMap(String.class, UnitDbAdapterProvider.TEST_ADAPTERS_MAP).put( - FirebirdAdapter.class.getName(), - FirebirdUnitDbAdapter.class.getName()).put( - OracleAdapter.class.getName(), - OracleUnitDbAdapter.class.getName()).put( - DerbyAdapter.class.getName(), - DerbyUnitDbAdapter.class.getName()).put( - Oracle8Adapter.class.getName(), - OracleUnitDbAdapter.class.getName()).put( - SybaseAdapter.class.getName(), - SybaseUnitDbAdapter.class.getName()).put( - MySQLAdapter.class.getName(), - MySQLUnitDbAdapter.class.getName()).put( - PostgresAdapter.class.getName(), - PostgresUnitDbAdapter.class.getName()).put( - OpenBaseAdapter.class.getName(), - OpenBaseUnitDbAdapter.class.getName()).put( - SQLServerAdapter.class.getName(), - SQLServerUnitDbAdapter.class.getName()).put( - DB2Adapter.class.getName(), - DB2UnitDbAdapter.class.getName()).put( - HSQLDBAdapter.class.getName(), - HSQLDBUnitDbAdapter.class.getName()).put( - H2Adapter.class.getName(), - H2UnitDbAdapter.class.getName()).put( - FrontBaseAdapter.class.getName(), - FrontBaseUnitDbAdapter.class.getName()).put( - IngresAdapter.class.getName(), - IngresUnitDbAdapter.class.getName()).put( - SQLiteAdapter.class.getName(), - SQLiteUnitDbAdapter.class.getName()); + binder.bindMap(String.class, UnitDbAdapterProvider.TEST_ADAPTERS_MAP) + .put(FirebirdAdapter.class.getName(), FirebirdUnitDbAdapter.class.getName()) + .put(OracleAdapter.class.getName(), OracleUnitDbAdapter.class.getName()) + .put(DerbyAdapter.class.getName(), DerbyUnitDbAdapter.class.getName()) + .put(Oracle8Adapter.class.getName(), OracleUnitDbAdapter.class.getName()) + .put(SybaseAdapter.class.getName(), SybaseUnitDbAdapter.class.getName()) + .put(MySQLAdapter.class.getName(), MySQLUnitDbAdapter.class.getName()) + .put(PostgresAdapter.class.getName(), PostgresUnitDbAdapter.class.getName()) + .put(OpenBaseAdapter.class.getName(), OpenBaseUnitDbAdapter.class.getName()) + .put(SQLServerAdapter.class.getName(), SQLServerUnitDbAdapter.class.getName()) + .put(DB2Adapter.class.getName(), DB2UnitDbAdapter.class.getName()) + .put(HSQLDBAdapter.class.getName(), HSQLDBUnitDbAdapter.class.getName()) + .put(H2Adapter.class.getName(), H2UnitDbAdapter.class.getName()) + .put(FrontBaseAdapter.class.getName(), FrontBaseUnitDbAdapter.class.getName()) + .put(IngresAdapter.class.getName(), IngresUnitDbAdapter.class.getName()) + .put(SQLiteAdapter.class.getName(), SQLiteUnitDbAdapter.class.getName()); ServerModule.contributeProperties(binder); // configure extended types ServerModule.contributeDefaultTypes(binder) .add(new VoidType()) .add(new BigDecimalType()) - .add(new BigIntegerType()) .add(new BooleanType()) .add(new ByteArrayType(false, true)) .add(new ByteType(false)) @@ -175,24 +161,24 @@ public class ServerCaseModule implements Module { .add(new TimeType()) .add(new TimestampType()) .add(new UtilDateType()) - .add(new CalendarType(GregorianCalendar.class)) - .add(new CalendarType(Calendar.class)) - .add(new UUIDType()); + .add(new CalendarType<>(GregorianCalendar.class)) + .add(new CalendarType<>(Calendar.class)); ServerModule.contributeUserTypes(binder); ServerModule.contributeTypeFactories(binder); + ServerModule.contributeValueObjectTypes(binder) + .add(BigIntegerValueType.class) + .add(UUIDValueType.class); + binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class); binder.bind(SchemaBuilder.class).to(SchemaBuilder.class); binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class); binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); - binder.bind(ObjectMapRetainStrategy.class).to( - DefaultObjectMapRetainStrategy.class); + binder.bind(ObjectMapRetainStrategy.class).to(DefaultObjectMapRetainStrategy.class); // singleton objects - binder.bind(UnitTestLifecycleManager.class).toInstance( - new ServerCaseLifecycleManager(testScope)); + binder.bind(UnitTestLifecycleManager.class).toInstance(new ServerCaseLifecycleManager(testScope)); - binder.bind(DataSourceInfo.class).toProvider( - ServerCaseDataSourceInfoProvider.class); + binder.bind(DataSourceInfo.class).toProvider(ServerCaseDataSourceInfoProvider.class); binder.bind(DataSourceFactory.class).to(ServerCaseSharedDataSourceFactory.class); binder.bind(DbAdapter.class).toProvider(ServerCaseDbAdapterProvider.class); binder.bind(JdbcAdapter.class).toProvider(ServerCaseDbAdapterProvider.class); @@ -201,14 +187,10 @@ public class ServerCaseModule implements Module { // this factory is a hack that allows to inject to DbAdapters loaded outside of // server runtime... BatchQueryBuilderFactory is hardcoded and whatever is placed // in the ServerModule is ignored - binder.bind(BatchTranslatorFactory.class).toProvider( - ServerCaseBatchQueryBuilderFactoryProvider.class); - binder.bind(DataChannelInterceptor.class).to( - ServerCaseDataChannelInterceptor.class); - binder.bind(SQLTemplateCustomizer.class).toProvider( - SQLTemplateCustomizerProvider.class); - binder.bind(ServerCaseDataSourceFactory.class).to( - ServerCaseDataSourceFactory.class); + binder.bind(BatchTranslatorFactory.class).toProvider(ServerCaseBatchQueryBuilderFactoryProvider.class); + binder.bind(DataChannelInterceptor.class).to(ServerCaseDataChannelInterceptor.class); + binder.bind(SQLTemplateCustomizer.class).toProvider(SQLTemplateCustomizerProvider.class); + binder.bind(ServerCaseDataSourceFactory.class).to(ServerCaseDataSourceFactory.class); binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class); binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class); binder.bind(ResourceLocator.class).to(ClassLoaderResourceLocator.class); @@ -218,26 +200,13 @@ public class ServerCaseModule implements Module { binder.bind(ConfigurationNameMapper.class).to(DefaultConfigurationNameMapper.class); // test-scoped objects - binder.bind(EntityResolver.class).toProvider( - ServerCaseEntityResolverProvider.class).in(testScope); - binder.bind(DataNode.class).toProvider(ServerCaseDataNodeProvider.class).in( - testScope); - binder.bind(ServerCaseProperties.class).to(ServerCaseProperties.class).in( - testScope); - binder.bind(ServerRuntime.class).toProvider(ServerRuntimeProvider.class).in( - testScope); - binder - .bind(ObjectContext.class) - .toProvider(ServerCaseObjectContextProvider.class) - .withoutScope(); - binder - .bind(DataContext.class) - .toProvider(ServerCaseDataContextProvider.class) - .withoutScope(); - - binder.bind(DBHelper.class).toProvider(FlavoredDBHelperProvider.class).in( - testScope); - binder.bind(DBCleaner.class).toProvider(DBCleanerProvider.class).in( - testScope); + binder.bind(EntityResolver.class).toProvider(ServerCaseEntityResolverProvider.class).in(testScope); + binder.bind(DataNode.class).toProvider(ServerCaseDataNodeProvider.class).in(testScope); + binder.bind(ServerCaseProperties.class).to(ServerCaseProperties.class).in(testScope); + binder.bind(ServerRuntime.class).toProvider(ServerRuntimeProvider.class).in(testScope); + binder.bind(ObjectContext.class).toProvider(ServerCaseObjectContextProvider.class).withoutScope(); + binder.bind(DataContext.class).toProvider(ServerCaseDataContextProvider.class).withoutScope(); + binder.bind(DBHelper.class).toProvider(FlavoredDBHelperProvider.class).in(testScope); + binder.bind(DBCleaner.class).toProvider(DBCleanerProvider.class).in(testScope); } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/docs/doc/src/main/resources/RELEASE-NOTES.txt ---------------------------------------------------------------------- diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt index b07f2d0..20f6164 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -15,6 +15,7 @@ Changes/New Features: CAY-1873 Move DataDomain cache configuration from the Modeler and into DI CAY-2109 cayenne-crypto: add value authentication (HMAC) +CAY-2210 Query cache: incorrect cache key for queries with custom value objects CAY-2255 ObjectSelect improvement: columns as full entities CAY-2258 DI: type-safe binding of List and Map CAY-2266 Move EventBridge implementations into autoloadable modules