You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/03/31 14:02:08 UTC
[1/2] cayenne git commit: CAY-2210 Query cache: incorrect cache key
for queries with custom value objects
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<ValueObjectType> 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>(GregorianCalendar.class))
- .add(new CalendarType<Calendar>(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<String> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes, List<ExtendedType> userExtendedTypes,
- List<ExtendedTypeFactory> extendedTypeFactories) {
+ List<ExtendedTypeFactory> 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<String> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
- @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
- @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> extendedTypeFactories,
- @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) {
- super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator);
+ @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes,
+ @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
+ @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
- @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
- @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> extendedTypeFactories,
- @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) {
- super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator);
+ @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes,
+ @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
+ @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
- @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
- @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> extendedTypeFactories,
- @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) {
- super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator);
+ @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes,
+ @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
+ @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
- @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
- @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> extendedTypeFactories,
- @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) {
- super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator);
+ @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes,
+ @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
+ @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
@Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
@Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
- @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
- @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> extendedTypeFactories,
- @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) {
- super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator);
+ @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes,
+ @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
+ @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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<ExtendedType> defaultExtendedTypes,
- @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
- @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> extendedTypeFactories,
- @Inject(Constants.SERVER_RESOURCE_LOCATOR) ResourceLocator resourceLocator) {
- super(runtimeProperties, defaultExtendedTypes, userExtendedTypes, extendedTypeFactories, resourceLocator);
+ @Inject(Constants.SERVER_DEFAULT_TYPES_LIST) List<ExtendedType> defaultExtendedTypes,
+ @Inject(Constants.SERVER_USER_TYPES_LIST) List<ExtendedType> userExtendedTypes,
+ @Inject(Constants.SERVER_TYPE_FACTORIES_LIST) List<ExtendedTypeFactory> 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());
}
- <T> boolean resolve(Object root, EntityResolver resolver, SelectQuery<T> 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 <T> void resolveAutoAliases(SelectQuery<T> 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<Object, ?> 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<ValueObjectType<?, ?>> 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.<ExtendedType>emptyList(),
Collections.<ExtendedType>emptyList(),
Collections.<ExtendedTypeFactory>emptyList(),
- locator);
+ locator, valueObjectTypeRegistry);
this.derbyAdapter = new DerbyAdapter(runtimeProperties,
Collections.<ExtendedType>emptyList(),
Collections.<ExtendedType>emptyList(),
Collections.<ExtendedTypeFactory>emptyList(),
- locator);
+ locator, valueObjectTypeRegistry);
this.autoDerbyAdapter = new AutoAdapter(new Provider<DbAdapter>() {
@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("<value placeholder>");
+ 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("<value placeholder>"));
+ }
+
+ /**
+ * 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("<value placeholder>"));
+ }
+
+ @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<TestValue, Integer> {
+ @Override
+ public Class<Integer> getTargetType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Class<TestValue> 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>(GregorianCalendar.class))
- .add(new CalendarType<Calendar>(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
[2/2] cayenne git commit: CAY-2210 Query cache: incorrect cache key
for queries with custom value objects
Posted by nt...@apache.org.
CAY-2210 Query cache: incorrect cache key for queries with custom value objects
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/5e9f0e0f
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/5e9f0e0f
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/5e9f0e0f
Branch: refs/heads/master
Commit: 5e9f0e0f6dd23f34fb755dc5eef966652f1d3ded
Parents: 4911ad1
Author: Nikita Timofeev <st...@gmail.com>
Authored: Fri Mar 31 17:01:56 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Fri Mar 31 17:01:56 2017 +0300
----------------------------------------------------------------------
.../rop/client/ClientChannelProvider.java | 5 +-
.../apache/cayenne/remote/ClientChannel.java | 11 +-
.../reverse/configuration/ToolsModule.java | 4 +
.../java/org/apache/cayenne/di/spi/DIUtil.java | 20 +-
.../org/apache/cayenne/java8/Java8Module.java | 14 +-
.../java8/access/types/LocalDateTimeType.java | 62 -----
.../access/types/LocalDateTimeValueType.java | 56 ++++
.../java8/access/types/LocalDateType.java | 62 -----
.../java8/access/types/LocalDateValueType.java | 56 ++++
.../java8/access/types/LocalTimeType.java | 63 -----
.../java8/access/types/LocalTimeValueType.java | 56 ++++
.../cayenne/access/types/BigDecimalType.java | 6 +-
.../cayenne/access/types/BigIntegerType.java | 88 -------
.../access/types/BigIntegerValueType.java | 53 ++++
.../cayenne/access/types/BooleanType.java | 9 +-
.../access/types/ByteOrCharArrayFactory.java | 14 +-
.../apache/cayenne/access/types/ByteType.java | 9 +-
.../apache/cayenne/access/types/DateType.java | 6 +-
.../types/DefaultValueObjectTypeRegistry.java | 104 ++++++++
.../apache/cayenne/access/types/DoubleType.java | 6 +-
.../apache/cayenne/access/types/EnumType.java | 25 +-
.../cayenne/access/types/EnumTypeFactory.java | 9 +-
.../cayenne/access/types/ExtendedEnumType.java | 42 ++-
.../cayenne/access/types/ExtendedType.java | 2 +-
.../cayenne/access/types/ExtendedTypeMap.java | 7 +-
.../apache/cayenne/access/types/FloatType.java | 6 +-
.../cayenne/access/types/IntegerType.java | 6 +-
.../apache/cayenne/access/types/LongType.java | 6 +-
.../apache/cayenne/access/types/ObjectType.java | 6 +-
.../access/types/SerializableTypeFactory.java | 17 +-
.../apache/cayenne/access/types/ShortType.java | 10 +-
.../access/types/SubclassTypeFactory.java | 3 +-
.../apache/cayenne/access/types/TimeType.java | 6 +-
.../cayenne/access/types/TimestampType.java | 6 +-
.../apache/cayenne/access/types/UUIDType.java | 95 -------
.../cayenne/access/types/UUIDValueType.java | 59 +++++
.../cayenne/access/types/UtilDateType.java | 27 +-
.../cayenne/access/types/ValueObjectType.java | 63 +++++
.../access/types/ValueObjectTypeFactory.java | 101 +++++++
.../access/types/ValueObjectTypeRegistry.java | 39 +++
.../server/DataDomainProvider.java | 5 +
.../configuration/server/ServerModule.java | 39 ++-
.../org/apache/cayenne/dba/JdbcAdapter.java | 22 +-
.../org/apache/cayenne/dba/db2/DB2Adapter.java | 6 +-
.../apache/cayenne/dba/derby/DerbyAdapter.java | 7 +-
.../cayenne/dba/firebird/FirebirdAdapter.java | 7 +-
.../cayenne/dba/frontbase/FrontBaseAdapter.java | 6 +-
.../org/apache/cayenne/dba/h2/H2Adapter.java | 6 +-
.../cayenne/dba/hsqldb/HSQLDBAdapter.java | 6 +-
.../dba/hsqldb/HSQLDBNoSchemaAdapter.java | 6 +-
.../cayenne/dba/ingres/IngresAdapter.java | 6 +-
.../apache/cayenne/dba/mysql/MySQLAdapter.java | 12 +-
.../cayenne/dba/openbase/OpenBaseAdapter.java | 6 +-
.../cayenne/dba/oracle/Oracle8Adapter.java | 12 +-
.../cayenne/dba/oracle/OracleAdapter.java | 12 +-
.../cayenne/dba/postgres/PostgresAdapter.java | 12 +-
.../cayenne/dba/sqlite/SQLiteAdapter.java | 7 +-
.../cayenne/dba/sqlserver/SQLServerAdapter.java | 12 +-
.../cayenne/dba/sybase/SybaseAdapter.java | 12 +-
.../org/apache/cayenne/map/EntityResolver.java | 11 +
.../cayenne/query/SelectQueryMetadata.java | 114 ++++++--
.../DefaultValueObjectTypeRegistryTest.java | 82 ++++++
.../server/DataDomainProviderTest.java | 5 +
.../server/DefaultDbAdapterFactoryTest.java | 8 +
.../cayenne/dba/PerAdapterProviderTest.java | 6 +-
.../cayenne/query/SelectQueryCacheKeyIT.java | 9 +-
.../query/SelectQueryMetadataCacheKeyTest.java | 262 +++++++++++++++++++
.../unit/di/server/ServerCaseModule.java | 113 +++-----
docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 +
69 files changed, 1346 insertions(+), 705 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientChannelProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientChannelProvider.java b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientChannelProvider.java
index 7936a1e..e5cf674 100644
--- a/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientChannelProvider.java
+++ b/cayenne-client/src/main/java/org/apache/cayenne/configuration/rop/client/ClientChannelProvider.java
@@ -20,7 +20,6 @@ package org.apache.cayenne.configuration.rop.client;
import org.apache.cayenne.ConfigurationException;
import org.apache.cayenne.DataChannel;
-import org.apache.cayenne.configuration.Constants;
import org.apache.cayenne.configuration.RuntimeProperties;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.di.Provider;
@@ -41,9 +40,7 @@ public class ClientChannelProvider implements Provider<DataChannel> {
public DataChannel get() throws ConfigurationException {
- boolean channelEvents = properties.getBoolean(
- ClientConstants.ROP_CHANNEL_EVENTS_PROPERTY,
- false);
+ boolean channelEvents = properties.getBoolean(ClientConstants.ROP_CHANNEL_EVENTS_PROPERTY, false);
return new ClientChannel(connection, channelEvents, eventManager, channelEvents);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-client/src/main/java/org/apache/cayenne/remote/ClientChannel.java
----------------------------------------------------------------------
diff --git a/cayenne-client/src/main/java/org/apache/cayenne/remote/ClientChannel.java b/cayenne-client/src/main/java/org/apache/cayenne/remote/ClientChannel.java
index 8353bc4..11a14ce 100644
--- a/cayenne-client/src/main/java/org/apache/cayenne/remote/ClientChannel.java
+++ b/cayenne-client/src/main/java/org/apache/cayenne/remote/ClientChannel.java
@@ -19,7 +19,13 @@
package org.apache.cayenne.remote;
-import org.apache.cayenne.*;
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.DataChannel;
+import org.apache.cayenne.DataChannelSyncCallbackAction;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.QueryResponse;
import org.apache.cayenne.event.EventBridge;
import org.apache.cayenne.event.EventManager;
import org.apache.cayenne.event.EventSubject;
@@ -72,8 +78,7 @@ public class ClientChannel implements DataChannel {
} else {
try {
setupRemoteChannelListener();
- }
- catch (CayenneRuntimeException e) {}
+ } catch (CayenneRuntimeException ignored) {}
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
----------------------------------------------------------------------
diff --git a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
index bc5762e..8fcafa7 100644
--- a/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
+++ b/cayenne-dbsync/src/main/java/org/apache/cayenne/dbsync/reverse/configuration/ToolsModule.java
@@ -21,6 +21,8 @@ package org.apache.cayenne.dbsync.reverse.configuration;
import org.apache.cayenne.access.translator.batch.BatchTranslatorFactory;
import org.apache.cayenne.access.translator.batch.DefaultBatchTranslatorFactory;
+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.DefaultRuntimeProperties;
import org.apache.cayenne.configuration.RuntimeProperties;
@@ -84,6 +86,8 @@ public class ToolsModule implements Module {
ServerModule.contributeDefaultTypes(binder);
ServerModule.contributeUserTypes(binder);
ServerModule.contributeTypeFactories(binder);
+ ServerModule.contributeValueObjectTypes(binder);
+ binder.bind(ValueObjectTypeRegistry.class).to(DefaultValueObjectTypeRegistry.class);
binder.bind(ClassLoaderManager.class).to(DefaultClassLoaderManager.class);
binder.bind(AdhocObjectFactory.class).to(DefaultAdhocObjectFactory.class);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java
index 5363ba0..416eb61 100644
--- a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java
+++ b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIUtil.java
@@ -39,7 +39,7 @@ class DIUtil {
Type[] parameters = parameterizedType.getActualTypeArguments();
if (parameters.length == 1) {
- return (Class<?>) parameters[0];
+ return typeToClass(parameters[0]);
}
}
@@ -55,13 +55,7 @@ class DIUtil {
arr = new Class[parameters.length];
int i=0;
for(Type next : parameters) {
- if(next instanceof Class) {
- arr[i++] = (Class<?>) next;
- } else if(next instanceof ParameterizedType){
- arr[i++] = (Class<?>) ((ParameterizedType)next).getRawType();
- } else {
- arr[i++] = Object.class;
- }
+ arr[i++] = typeToClass(next);
}
}
@@ -86,4 +80,14 @@ class DIUtil {
return Key.get(type, bindingName);
}
+
+ static Class<?> typeToClass(Type type) {
+ if(type instanceof Class) {
+ return (Class<?>) type;
+ } else if(type instanceof ParameterizedType){
+ return (Class<?>) ((ParameterizedType)type).getRawType();
+ } else {
+ return Object.class;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8Module.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8Module.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8Module.java
index 2de3749..434595d 100644
--- a/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8Module.java
+++ b/cayenne-java8/src/main/java/org/apache/cayenne/java8/Java8Module.java
@@ -21,9 +21,9 @@ package org.apache.cayenne.java8;
import org.apache.cayenne.configuration.server.ServerModule;
import org.apache.cayenne.di.Binder;
import org.apache.cayenne.di.Module;
-import org.apache.cayenne.java8.access.types.LocalDateTimeType;
-import org.apache.cayenne.java8.access.types.LocalDateType;
-import org.apache.cayenne.java8.access.types.LocalTimeType;
+import org.apache.cayenne.java8.access.types.LocalDateTimeValueType;
+import org.apache.cayenne.java8.access.types.LocalDateValueType;
+import org.apache.cayenne.java8.access.types.LocalTimeValueType;
/**
* @since 4.0
@@ -32,9 +32,9 @@ public class Java8Module implements Module {
@Override
public void configure(Binder binder) {
- ServerModule.contributeDefaultTypes(binder)
- .add(new LocalDateType())
- .add(new LocalTimeType())
- .add(new LocalDateTimeType());
+ ServerModule.contributeValueObjectTypes(binder)
+ .add(LocalDateValueType.class)
+ .add(LocalTimeValueType.class)
+ .add(LocalDateTimeValueType.class);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateTimeType.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateTimeType.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateTimeType.java
deleted file mode 100644
index 6242574..0000000
--- a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateTimeType.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*****************************************************************
- * 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.java8.access.types;
-
-import org.apache.cayenne.access.types.ExtendedType;
-
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.Timestamp;
-import java.time.LocalDateTime;
-
-public class LocalDateTimeType implements ExtendedType<LocalDateTime> {
-
- @Override
- public String getClassName() {
- return LocalDateTime.class.getName();
- }
-
- @Override
- public void setJdbcObject(PreparedStatement statement, LocalDateTime value, int pos, int type, int scale) throws Exception {
- statement.setTimestamp(pos, Timestamp.valueOf(value));
- }
-
- @Override
- public LocalDateTime materializeObject(ResultSet rs, int index, int type) throws Exception {
- Timestamp timestamp = rs.getTimestamp(index);
- return timestamp != null ? timestamp.toLocalDateTime() : null;
- }
-
- @Override
- public LocalDateTime materializeObject(CallableStatement rs, int index, int type) throws Exception {
- Timestamp timestamp = rs.getTimestamp(index);
- return timestamp != null ? timestamp.toLocalDateTime() : null;
- }
-
- @Override
- public String toString(LocalDateTime value) {
- if (value == null) {
- return "NULL";
- }
-
- return '\'' + value.toString() + '\'';
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateTimeValueType.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateTimeValueType.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateTimeValueType.java
new file mode 100644
index 0000000..a877b7a
--- /dev/null
+++ b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateTimeValueType.java
@@ -0,0 +1,56 @@
+/*****************************************************************
+ * 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.java8.access.types;
+
+import java.sql.Timestamp;
+import java.time.LocalDateTime;
+
+import org.apache.cayenne.access.types.ValueObjectType;
+
+/**
+ * @since 4.0
+ */
+public class LocalDateTimeValueType implements ValueObjectType<LocalDateTime, Timestamp> {
+
+ @Override
+ public Class<Timestamp> getTargetType() {
+ return Timestamp.class;
+ }
+
+ @Override
+ public Class<LocalDateTime> getValueType() {
+ return LocalDateTime.class;
+ }
+
+ @Override
+ public LocalDateTime toJavaObject(Timestamp value) {
+ return value.toLocalDateTime();
+ }
+
+ @Override
+ public Timestamp fromJavaObject(LocalDateTime object) {
+ return Timestamp.valueOf(object);
+ }
+
+ @Override
+ public String toCacheKey(LocalDateTime object) {
+ return object.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateType.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateType.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateType.java
deleted file mode 100644
index 0d0b431..0000000
--- a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateType.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*****************************************************************
- * 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.java8.access.types;
-
-import org.apache.cayenne.access.types.ExtendedType;
-
-import java.sql.CallableStatement;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.time.LocalDate;
-
-public class LocalDateType implements ExtendedType<LocalDate> {
-
- @Override
- public String getClassName() {
- return LocalDate.class.getName();
- }
-
- @Override
- public void setJdbcObject(PreparedStatement statement, LocalDate value, int pos, int type, int scale) throws Exception {
- statement.setDate(pos, Date.valueOf(value));
- }
-
- @Override
- public LocalDate materializeObject(ResultSet rs, int index, int type) throws Exception {
- Date date = rs.getDate(index);
- return date != null ? date.toLocalDate() : null;
- }
-
- @Override
- public LocalDate materializeObject(CallableStatement rs, int index, int type) throws Exception {
- Date date = rs.getDate(index);
- return date != null ? date.toLocalDate() : null;
- }
-
- @Override
- public String toString(LocalDate value) {
- if (value == null) {
- return "NULL";
- }
-
- return '\'' + value.toString() + '\'';
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateValueType.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateValueType.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateValueType.java
new file mode 100644
index 0000000..03e259c
--- /dev/null
+++ b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalDateValueType.java
@@ -0,0 +1,56 @@
+/*****************************************************************
+ * 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.java8.access.types;
+
+import java.sql.Date;
+import java.time.LocalDate;
+
+import org.apache.cayenne.access.types.ValueObjectType;
+
+/**
+ * @since 4.0
+ */
+public class LocalDateValueType implements ValueObjectType<LocalDate, Date> {
+
+ @Override
+ public Class<Date> getTargetType() {
+ return Date.class;
+ }
+
+ @Override
+ public Class<LocalDate> getValueType() {
+ return LocalDate.class;
+ }
+
+ @Override
+ public LocalDate toJavaObject(Date value) {
+ return value.toLocalDate();
+ }
+
+ @Override
+ public Date fromJavaObject(LocalDate object) {
+ return Date.valueOf(object);
+ }
+
+ @Override
+ public String toCacheKey(LocalDate object) {
+ return object.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalTimeType.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalTimeType.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalTimeType.java
deleted file mode 100644
index 1b0afb4..0000000
--- a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalTimeType.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*****************************************************************
- * 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.java8.access.types;
-
-import org.apache.cayenne.access.types.ExtendedType;
-
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.Time;
-import java.time.LocalTime;
-
-public class LocalTimeType implements ExtendedType<LocalTime> {
-
- @Override
- public String getClassName() {
- return LocalTime.class.getName();
- }
-
- @Override
- public void setJdbcObject(PreparedStatement statement, LocalTime value, int pos, int type, int scale) throws Exception {
- statement.setTime(pos, Time.valueOf(value));
- }
-
- @Override
- public LocalTime materializeObject(ResultSet rs, int index, int type) throws Exception {
- Time time = rs.getTime(index);
- return time != null ? time.toLocalTime() : null;
- }
-
- @Override
- public LocalTime materializeObject(CallableStatement rs, int index, int type) throws Exception {
- Time time = rs.getTime(index);
- return time != null ? time.toLocalTime() : null;
- }
-
- @Override
- public String toString(LocalTime value) {
- if (value == null) {
- return "NULL";
- }
-
- return '\'' + value.toString() + '\'';
- }
-
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalTimeValueType.java
----------------------------------------------------------------------
diff --git a/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalTimeValueType.java b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalTimeValueType.java
new file mode 100644
index 0000000..7843a3d
--- /dev/null
+++ b/cayenne-java8/src/main/java/org/apache/cayenne/java8/access/types/LocalTimeValueType.java
@@ -0,0 +1,56 @@
+/*****************************************************************
+ * 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.java8.access.types;
+
+import java.sql.Time;
+import java.time.LocalTime;
+
+import org.apache.cayenne.access.types.ValueObjectType;
+
+/**
+ * @since 4.0
+ */
+public class LocalTimeValueType implements ValueObjectType<LocalTime, Time> {
+
+ @Override
+ public Class<Time> getTargetType() {
+ return Time.class;
+ }
+
+ @Override
+ public Class<LocalTime> getValueType() {
+ return LocalTime.class;
+ }
+
+ @Override
+ public LocalTime toJavaObject(Time value) {
+ return value.toLocalTime();
+ }
+
+ @Override
+ public Time fromJavaObject(LocalTime object) {
+ return Time.valueOf(object);
+ }
+
+ @Override
+ public String toCacheKey(LocalTime object) {
+ return object.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigDecimalType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigDecimalType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigDecimalType.java
index 626e794..5423442 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigDecimalType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigDecimalType.java
@@ -39,8 +39,7 @@ public class BigDecimalType implements ExtendedType<BigDecimal> {
}
@Override
- public BigDecimal materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public BigDecimal materializeObject(CallableStatement rs, int index, int type) throws Exception {
return rs.getBigDecimal(index);
}
@@ -54,8 +53,7 @@ public class BigDecimalType implements ExtendedType<BigDecimal> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setBigDecimal(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigIntegerType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigIntegerType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigIntegerType.java
deleted file mode 100644
index f6c10b1..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigIntegerType.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*****************************************************************
- * 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 org.apache.cayenne.dba.TypesMapping;
-
-import java.math.BigInteger;
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-
-/**
- * @since 3.0
- */
-public class BigIntegerType implements ExtendedType<BigInteger> {
-
- @Override
- public String getClassName() {
- return BigInteger.class.getName();
- }
-
- @Override
- public BigInteger materializeObject(ResultSet rs, int index, int type) throws Exception {
- Object object = rs.getObject(index);
- if (object == null) {
- return null;
- }
-
- return new BigInteger(object.toString());
- }
-
- @Override
- public BigInteger materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
- Object object = rs.getObject(index);
- if (object == null) {
- return null;
- }
-
- return new BigInteger(object.toString());
- }
-
- @Override
- public void setJdbcObject(
- PreparedStatement statement,
- BigInteger value,
- int pos,
- int type,
- int precision) throws Exception {
-
- if (value == null) {
- statement.setNull(pos, type);
- }
- else if (TypesMapping.isNumeric(type)) {
- statement.setLong(pos, ((BigInteger) value).longValue());
- }
- else {
- throw new IllegalArgumentException(
- "Can't map BigInteger to a non-numeric type: "
- + TypesMapping.getSqlNameByType(type));
- }
- }
-
- @Override
- public String toString(BigInteger value) {
- if (value == null) {
- return "NULL";
- }
-
- return value.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigIntegerValueType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigIntegerValueType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigIntegerValueType.java
new file mode 100644
index 0000000..890a4b2
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/BigIntegerValueType.java
@@ -0,0 +1,53 @@
+/*****************************************************************
+ * 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.math.BigInteger;
+
+/**
+ * @since 4.0
+ */
+public class BigIntegerValueType implements ValueObjectType<BigInteger, Long> {
+
+ @Override
+ public Class<Long> getTargetType() {
+ return Long.class;
+ }
+
+ @Override
+ public Class<BigInteger> getValueType() {
+ return BigInteger.class;
+ }
+
+ @Override
+ public BigInteger toJavaObject(Long value) {
+ return new BigInteger(value.toString());
+ }
+
+ @Override
+ public Long fromJavaObject(BigInteger object) {
+ return object.longValue();
+ }
+
+ @Override
+ public String toCacheKey(BigInteger object) {
+ return object.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/BooleanType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/BooleanType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/BooleanType.java
index 8de103d..d205240 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/BooleanType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/BooleanType.java
@@ -49,12 +49,10 @@ public class BooleanType implements ExtendedType<Boolean> {
if (val == null) {
st.setNull(pos, type);
- }
- else if (type == Types.BIT || type == Types.BOOLEAN) {
+ } else if (type == Types.BIT || type == Types.BOOLEAN) {
boolean flag = Boolean.TRUE.equals(val);
st.setBoolean(pos, flag);
- }
- else {
+ } else {
st.setObject(pos, val, type);
}
}
@@ -66,8 +64,7 @@ public class BooleanType implements ExtendedType<Boolean> {
}
@Override
- public Boolean materializeObject(CallableStatement st, int index, int type)
- throws Exception {
+ public Boolean materializeObject(CallableStatement st, int index, int type) throws Exception {
boolean b = st.getBoolean(index);
return (st.wasNull()) ? null : b ? Boolean.TRUE : Boolean.FALSE;
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteOrCharArrayFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteOrCharArrayFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteOrCharArrayFactory.java
index 2b1b83f..15ae4fb 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteOrCharArrayFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteOrCharArrayFactory.java
@@ -36,31 +36,25 @@ class ByteOrCharArrayFactory implements ExtendedTypeFactory {
this.map = map;
}
+ @SuppressWarnings("unchecked")
public ExtendedType getType(Class<?> objectClass) {
if (objectClass.isArray()) {
-
Class<?> elementType = objectClass.getComponentType();
-
if (Character.class.isAssignableFrom(elementType)) {
// can't use "getRegisteredType" as it causes infinite recursion
ExtendedType<String> stringType = map.getExplictlyRegisteredType("java.lang.String");
return new CharacterArrayType(stringType);
- }
- else if (Character.TYPE.isAssignableFrom(elementType)) {
-
+ } else if (Character.TYPE.isAssignableFrom(elementType)) {
// can't use "getRegisteredType" as it causes infinite recursion
ExtendedType<String> stringType = map.getExplictlyRegisteredType("java.lang.String");
return new CharArrayType(stringType);
- }
- else if (Byte.class.isAssignableFrom(elementType)) {
+ } else if (Byte.class.isAssignableFrom(elementType)) {
// can't use "getRegisteredType" as it causes infinite recursion
ExtendedType<byte[]> bytesType = map.getExplictlyRegisteredType("byte[]");
return new ByteWrapperArrayType(bytesType);
}
- }
- else if (Character.class.isAssignableFrom(objectClass)) {
-
+ } else if (Character.class.isAssignableFrom(objectClass)) {
// can't use "getRegisteredType" as it causes infinite recursion
ExtendedType<String> stringType = map.getExplictlyRegisteredType("java.lang.String");
return new CharacterType(stringType);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteType.java
index b363bbf..fab946c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ByteType.java
@@ -53,8 +53,7 @@ public class ByteType implements ExtendedType<Byte> {
}
@Override
- public Byte materializeObject(CallableStatement st, int index, int type)
- throws Exception {
+ public Byte materializeObject(CallableStatement st, int index, int type) throws Exception {
byte b = st.getByte(index);
return (st.wasNull()) ? null : b;
}
@@ -70,12 +69,10 @@ public class ByteType implements ExtendedType<Byte> {
if (value == null) {
statement.setNull(pos, type);
} else {
-
- Byte b = value;
if (widenBytes) {
- statement.setInt(pos, b.intValue());
+ statement.setInt(pos, value.intValue());
} else {
- statement.setByte(pos, b.byteValue());
+ statement.setByte(pos, value);
}
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java
index 654e1fe..1c732e9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java
@@ -39,8 +39,7 @@ public class DateType implements ExtendedType<Date> {
}
@Override
- public Date materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public Date materializeObject(CallableStatement rs, int index, int type) throws Exception {
return rs.getDate(index);
}
@@ -54,8 +53,7 @@ public class DateType implements ExtendedType<Date> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setDate(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java
new file mode 100644
index 0000000..3dda771
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java
@@ -0,0 +1,104 @@
+/*****************************************************************
+ * 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.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.cayenne.di.Inject;
+
+/**
+ * Default implementation of {@link ValueObjectTypeRegistry}
+ * @since 4.0
+ */
+public class DefaultValueObjectTypeRegistry implements ValueObjectTypeRegistry {
+
+ final Map<String, ValueObjectType<?,?>> typeCache;
+
+ public DefaultValueObjectTypeRegistry(@Inject List<ValueObjectType<?, ?>> valueObjectTypeList) {
+ typeCache = new ConcurrentHashMap<>();
+ buildTypeCache(valueObjectTypeList);
+ }
+
+ private void buildTypeCache(List<ValueObjectType<?, ?>> valueObjectTypeList) {
+ for(ValueObjectType<?, ?> valueObjectType : valueObjectTypeList) {
+ typeCache.put(valueObjectType.getValueType().getName(), valueObjectType);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> ValueObjectType<T, ?> getValueType(Class<? extends T> valueClass) {
+ ValueObjectType type = typeCache.get(valueClass.getName());
+ if(type == null) {
+ type = findBySuperclasses(valueClass);
+ } else if(type == NULL_DUMMY) {
+ return null;
+ }
+ return type;
+ }
+
+ protected ValueObjectType<?, ?> findBySuperclasses(final Class<?> baseClass) {
+ ValueObjectType<?,?> type = null;
+ Class<?> searchClass = baseClass.getSuperclass();
+
+ while(searchClass != null && !searchClass.equals(Object.class)) {
+ type = typeCache.get(searchClass.getName());
+ if(type != null) {
+ // cache it for faster search later
+ typeCache.put(baseClass.getName(), type);
+ break;
+ }
+ searchClass = searchClass.getSuperclass();
+ }
+ // as well cache null result
+ if(type == null) {
+ typeCache.put(baseClass.getName(), NULL_DUMMY);
+ }
+ return type;
+ }
+
+ private static final ValueObjectType<?, ?> NULL_DUMMY = new ValueObjectType() {
+ @Override
+ public Class<?> getTargetType() {
+ return null;
+ }
+ @Override
+ public Class<?> getValueType() {
+ return null;
+ }
+ @Override
+ public Object toJavaObject(Object value) {
+ return null;
+ }
+ @Override
+ public Object fromJavaObject(Object object) {
+ return null;
+ }
+ @Override
+ public String toCacheKey(Object object) {
+ return null;
+ }
+ };
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/DoubleType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DoubleType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DoubleType.java
index cfdd91f..28c6fe5 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DoubleType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DoubleType.java
@@ -39,8 +39,7 @@ public class DoubleType implements ExtendedType<Double> {
}
@Override
- public Double materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public Double materializeObject(CallableStatement rs, int index, int type) throws Exception {
double d = rs.getDouble(index);
return rs.wasNull() ? null : d;
}
@@ -55,8 +54,7 @@ public class DoubleType implements ExtendedType<Double> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setDouble(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java
index f8c4192..04182b2 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java
@@ -31,9 +31,6 @@ import java.sql.ResultSet;
* An ExtendedType that handles an enum class. If Enum is mapped to a character column,
* its name is used as persistent value; if it is mapped to a numeric column, its ordinal
* (i.e. a position in enum class) is used.
- * <p>
- * <i>Requires Java 1.5 or newer</i>
- * </p>
*
* @since 1.2
*/
@@ -54,11 +51,8 @@ public class EnumType<T extends Enum<T>> implements ExtendedType<T> {
try {
Method m = enumClass.getMethod("values");
this.values = (T[]) m.invoke(null);
- }
- catch (Exception e) {
- throw new IllegalArgumentException("Class "
- + enumClass.getName()
- + " is not an Enum", e);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Class " + enumClass.getName() + " is not an Enum", e);
}
}
@@ -78,12 +72,10 @@ public class EnumType<T extends Enum<T>> implements ExtendedType<T> {
if (value != null) {
if (TypesMapping.isNumeric(type)) {
statement.setInt(pos, value.ordinal());
- }
- else {
+ } else {
statement.setString(pos, value.name());
}
- }
- else {
+ } else {
statement.setNull(pos, type);
}
}
@@ -93,21 +85,18 @@ public class EnumType<T extends Enum<T>> implements ExtendedType<T> {
if (TypesMapping.isNumeric(type)) {
int i = rs.getInt(index);
return (rs.wasNull() || index < 0) ? null : values[i];
- }
- else {
+ } else {
String string = rs.getString(index);
return string != null ? Enum.valueOf(enumClass, string) : null;
}
}
@Override
- public T materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public T materializeObject(CallableStatement rs, int index, int type) throws Exception {
if (TypesMapping.isNumeric(type)) {
int i = rs.getInt(index);
return (rs.wasNull() || index < 0) ? null : values[i];
- }
- else {
+ } else {
String string = rs.getString(index);
return string != null ? Enum.valueOf(enumClass, string) : null;
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumTypeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumTypeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumTypeFactory.java
index 7d28bdb..e1e77ec 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumTypeFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumTypeFactory.java
@@ -22,7 +22,7 @@ package org.apache.cayenne.access.types;
import org.apache.cayenne.ExtendedEnumeration;
/**
- * ExtendedTypeFactory for handling JDK 1.5 Enums.
+ * ExtendedTypeFactory for handling Enum types.
*
* @since 3.0
*/
@@ -30,12 +30,13 @@ public class EnumTypeFactory implements ExtendedTypeFactory {
@SuppressWarnings("unchecked")
public ExtendedType getType(Class<?> objectClass) {
- if (ExtendedEnumeration.class.isAssignableFrom(objectClass))
+ if (ExtendedEnumeration.class.isAssignableFrom(objectClass)) {
return new ExtendedEnumType(objectClass);
- else if (objectClass.isEnum())
+ } else if (objectClass.isEnum()) {
return new EnumType(objectClass);
- else
+ } else {
return null;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedEnumType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedEnumType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedEnumType.java
index ed819fb..17151cb 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedEnumType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedEnumType.java
@@ -56,18 +56,12 @@ public class ExtendedEnumType<T extends Enum<T>> implements ExtendedType<T> {
try {
Method m = enumerationClass.getMethod("values");
-
values = (T[]) m.invoke(null);
-
- for (int i = 0; i < values.length; i++)
- register(values[i], ((ExtendedEnumeration) values[i])
- .getDatabaseValue());
-
- }
- catch (Exception e) {
- throw new IllegalArgumentException("Class "
- + enumerationClass.getName()
- + " is not an Enum", e);
+ for (T value : values) {
+ register(value, ((ExtendedEnumeration) value).getDatabaseValue());
+ }
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Class " + enumerationClass.getName() + " is not an Enum", e);
}
}
@@ -81,21 +75,18 @@ public class ExtendedEnumType<T extends Enum<T>> implements ExtendedType<T> {
if (TypesMapping.isNumeric(type)) {
int i = rs.getInt(index);
return (rs.wasNull() || index < 0) ? null : lookup(i);
- }
- else {
+ } else {
String string = rs.getString(index);
return string != null ? lookup(string) : null;
}
}
@Override
- public T materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public T materializeObject(CallableStatement rs, int index, int type) throws Exception {
if (TypesMapping.isNumeric(type)) {
int i = rs.getInt(index);
return (rs.wasNull() || index < 0) ? null : lookup(i);
- }
- else {
+ } else {
String string = rs.getString(index);
return string != null ? lookup(string) : null;
}
@@ -110,13 +101,12 @@ public class ExtendedEnumType<T extends Enum<T>> implements ExtendedType<T> {
int precision) throws Exception {
if (value instanceof ExtendedEnumeration) {
ExtendedEnumeration e = (ExtendedEnumeration) value;
-
- if (TypesMapping.isNumeric(type))
+ if (TypesMapping.isNumeric(type)) {
statement.setInt(pos, (Integer) e.getDatabaseValue());
- else
+ } else {
statement.setString(pos, (String) e.getDatabaseValue());
- }
- else {
+ }
+ } else {
statement.setNull(pos, type);
}
}
@@ -163,13 +153,15 @@ public class ExtendedEnumType<T extends Enum<T>> implements ExtendedType<T> {
buffer.append(value.name()).append("=");
if (value instanceof ExtendedEnumeration) {
Object dbValue = ((ExtendedEnumeration) value).getDatabaseValue();
- if (dbValue instanceof String)
+ if (dbValue instanceof String) {
buffer.append("'");
+ }
buffer.append(value);
- if (dbValue instanceof String)
+ if (dbValue instanceof String) {
buffer.append("'");
+ }
} else {
- buffer.append((value).ordinal());
+ buffer.append(value.ordinal());
// FIXME -- this isn't quite right
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedType.java
index b30f674..8ace896 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedType.java
@@ -70,7 +70,7 @@ public interface ExtendedType<T> {
/**
* Converts value of the supported type to a human-readable String representation.
*
- * @param value a vlue to convert to String.
+ * @param value a value to convert to String.
* @since 4.0
*/
String toString(T value);
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
index 387fe77..de620ec 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
@@ -55,9 +55,7 @@ public class ExtendedTypeMap {
Collection<ExtendedTypeFactory> extendedTypeFactories;
- // standard type factories registered by Cayenne that are consulted after
- // the user
- // factories.
+ // standard type factories registered by Cayenne that are consulted after the user factories.
Collection<ExtendedTypeFactory> internalTypeFactories;
/**
@@ -87,8 +85,7 @@ public class ExtendedTypeMap {
internalTypeFactories.add(new ByteOrCharArrayFactory(this));
// note that Serializable type should be used as a last resort after all
- // other
- // alternatives are exhausted.
+ // other alternatives are exhausted.
internalTypeFactories.add(new SerializableTypeFactory(this));
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/FloatType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/FloatType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/FloatType.java
index 51713db..1dc98ad 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/FloatType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/FloatType.java
@@ -39,8 +39,7 @@ public class FloatType implements ExtendedType<Float> {
}
@Override
- public Float materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public Float materializeObject(CallableStatement rs, int index, int type) throws Exception {
float f = rs.getFloat(index);
return rs.wasNull() ? null : f;
}
@@ -55,8 +54,7 @@ public class FloatType implements ExtendedType<Float> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setFloat(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/IntegerType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/IntegerType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/IntegerType.java
index 0d2ec62..8562b9a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/IntegerType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/IntegerType.java
@@ -39,8 +39,7 @@ public class IntegerType implements ExtendedType<Integer> {
}
@Override
- public Integer materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public Integer materializeObject(CallableStatement rs, int index, int type) throws Exception {
int value = rs.getInt(index);
return (rs.wasNull()) ? null : value;
}
@@ -55,8 +54,7 @@ public class IntegerType implements ExtendedType<Integer> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setInt(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/LongType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/LongType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/LongType.java
index 287190e..dcfdf66 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/LongType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/LongType.java
@@ -39,8 +39,7 @@ public class LongType implements ExtendedType<Long> {
}
@Override
- public Long materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public Long materializeObject(CallableStatement rs, int index, int type) throws Exception {
long value = rs.getLong(index);
return (rs.wasNull()) ? null : value;
}
@@ -55,8 +54,7 @@ public class LongType implements ExtendedType<Long> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setLong(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ObjectType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ObjectType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ObjectType.java
index 2473177..f4d7188 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ObjectType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ObjectType.java
@@ -35,8 +35,7 @@ public class ObjectType implements ExtendedType<Object> {
}
@Override
- public Object materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public Object materializeObject(CallableStatement rs, int index, int type) throws Exception {
return rs.getObject(index);
}
@@ -54,8 +53,7 @@ public class ObjectType implements ExtendedType<Object> {
int scale) throws Exception {
if (scale != -1) {
statement.setObject(pos, value, type, scale);
- }
- else {
+ } else {
statement.setObject(pos, value, type);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java
index e37eed5..5fe7d0d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/SerializableTypeFactory.java
@@ -52,13 +52,11 @@ class SerializableTypeFactory implements ExtendedTypeFactory {
logger.warn("SerializableType will be used for type conversion.");
// using a binary stream delegate instead of byte[] may actually
- // speed up
- // things in some dbs, but at least byte[] type works consistently
- // across
- // adapters...
+ // speed up things in some dbs, but at least byte[] type works consistently
+ // across adapters...
- // note - can't use "getRegisteredType" as it causes infinite
- // recursion
+ // note - can't use "getRegisteredType" as it causes infinite recursion
+ @SuppressWarnings("unchecked")
ExtendedType<byte[]> bytesType = map.getExplictlyRegisteredType("byte[]");
return new SerializableType(objectClass, bytesType);
}
@@ -86,7 +84,6 @@ class SerializableTypeFactory implements ExtendedTypeFactory {
@Override
byte[] fromJavaObject(Object object) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream() {
-
// avoid unneeded array copy...
@Override
public synchronized byte[] toByteArray() {
@@ -94,7 +91,7 @@ class SerializableTypeFactory implements ExtendedTypeFactory {
}
};
- try (ObjectOutputStream out = new ObjectOutputStream(bytes);) {
+ try (ObjectOutputStream out = new ObjectOutputStream(bytes)) {
out.writeObject(object);
} catch (Exception e) {
throw new CayenneRuntimeException("Error serializing object", e);
@@ -106,8 +103,8 @@ class SerializableTypeFactory implements ExtendedTypeFactory {
@Override
Object toJavaObject(byte[] bytes) {
try {
- return bytes != null && bytes.length > 0 ? new ObjectInputStream(new ByteArrayInputStream(bytes))
- .readObject() : null;
+ return bytes != null && bytes.length > 0
+ ? new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject() : null;
} catch (Exception e) {
throw new CayenneRuntimeException("Error deserializing object", e);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ShortType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ShortType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ShortType.java
index 257f7cc..2295c52 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ShortType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ShortType.java
@@ -51,8 +51,7 @@ public class ShortType implements ExtendedType<Short> {
}
@Override
- public Short materializeObject(CallableStatement st, int index, int type)
- throws Exception {
+ public Short materializeObject(CallableStatement st, int index, int type) throws Exception {
short s = st.getShort(index);
return (st.wasNull()) ? null : s;
}
@@ -67,13 +66,10 @@ public class ShortType implements ExtendedType<Short> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
-
+ } else {
if (widenShorts) {
statement.setInt(pos, value.intValue());
- }
- else {
+ } else {
statement.setShort(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
index d493259..6938759 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
@@ -43,8 +43,7 @@ class SubclassTypeFactory implements ExtendedTypeFactory {
|| javaClass.isPrimitive()) {
javaClass = null;
}
- }
- catch (ClassNotFoundException e) {
+ } catch (ClassNotFoundException e) {
// ignore.
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java
index 8966f82..78f1b78 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java
@@ -39,8 +39,7 @@ public class TimeType implements ExtendedType<Time> {
}
@Override
- public Time materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
+ public Time materializeObject(CallableStatement rs, int index, int type) throws Exception {
return rs.getTime(index);
}
@@ -54,8 +53,7 @@ public class TimeType implements ExtendedType<Time> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setTime(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java
index d6b6aca..ab25fa9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java
@@ -39,8 +39,7 @@ public class TimestampType implements ExtendedType<Timestamp> {
}
@Override
- public Timestamp materializeObject(CallableStatement cs, int index, int type)
- throws Exception {
+ public Timestamp materializeObject(CallableStatement cs, int index, int type) throws Exception {
return cs.getTimestamp(index);
}
@@ -54,8 +53,7 @@ public class TimestampType implements ExtendedType<Timestamp> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setTimestamp(pos, value);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/UUIDType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/UUIDType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/UUIDType.java
deleted file mode 100644
index fd700ea..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/UUIDType.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*****************************************************************
- * 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 org.apache.cayenne.CayenneRuntimeException;
-
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.UUID;
-
-/**
- * An ExtendedType to map Java UUIDs as persistent attributes.
- *
- * @since 3.0
- */
-public class UUIDType implements ExtendedType<UUID> {
-
- @Override
- public String getClassName() {
- return UUID.class.getName();
- }
-
- @Override
- public UUID materializeObject(ResultSet rs, int index, int type) throws Exception {
- String uuid = rs.getString(index);
- if (uuid == null) {
- return null;
- }
-
- try {
- return UUID.fromString(uuid);
- }
- catch (IllegalArgumentException e) {
- throw new CayenneRuntimeException("Invalid UUID value: " + uuid, e);
- }
- }
-
- @Override
- public UUID materializeObject(CallableStatement rs, int index, int type)
- throws Exception {
-
- String uuid = rs.getString(index);
- if (uuid == null) {
- return null;
- }
-
- try {
- return UUID.fromString(uuid);
- }
- catch (IllegalArgumentException e) {
- throw new CayenneRuntimeException("Invalid UUID value: " + uuid, e);
- }
- }
-
- @Override
- public void setJdbcObject(
- PreparedStatement statement,
- UUID value,
- int pos,
- int type,
- int scale) throws Exception {
-
- if (value == null) {
- statement.setNull(pos, type);
- } else {
- statement.setObject(pos, value.toString(), type);
- }
- }
-
- @Override
- public String toString(UUID value) {
- if (value == null) {
- return "NULL";
- }
-
- return value.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/UUIDValueType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/UUIDValueType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/UUIDValueType.java
new file mode 100644
index 0000000..6e63ac5
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/UUIDValueType.java
@@ -0,0 +1,59 @@
+/*****************************************************************
+ * 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.UUID;
+
+import org.apache.cayenne.CayenneRuntimeException;
+
+/**
+ * @since 4.0
+ */
+public class UUIDValueType implements ValueObjectType<UUID, String> {
+
+ @Override
+ public Class<String> getTargetType() {
+ return String.class;
+ }
+
+ @Override
+ public Class<UUID> getValueType() {
+ return UUID.class;
+ }
+
+ @Override
+ public UUID toJavaObject(String value) {
+ try {
+ return UUID.fromString(value);
+ } catch (IllegalArgumentException e) {
+ throw new CayenneRuntimeException("Invalid UUID value: " + value, e);
+ }
+ }
+
+ @Override
+ public String fromJavaObject(UUID object) {
+ return object.toString();
+ }
+
+ @Override
+ public String toCacheKey(UUID object) {
+ return object.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
index 9fa5010..5e3fb82 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
@@ -42,24 +42,22 @@ public class UtilDateType implements ExtendedType<Date> {
}
protected Object convertToJdbcObject(Date val, int type) throws Exception {
- if (type == Types.DATE)
+ if (type == Types.DATE) {
return new java.sql.Date(val.getTime());
- else if (type == Types.TIME)
+ } else if (type == Types.TIME) {
return new java.sql.Time(val.getTime());
- else if (type == Types.TIMESTAMP)
+ } else if (type == Types.TIMESTAMP) {
return new java.sql.Timestamp(val.getTime());
- else
+ } else {
throw new IllegalArgumentException(
- "Only DATE, TIME or TIMESTAMP can be mapped as '"
- + getClassName()
- + "', got "
- + TypesMapping.getSqlNameByType(type));
+ "Only DATE, TIME or TIMESTAMP can be mapped as '" + getClassName()
+ + "', got " + TypesMapping.getSqlNameByType(type));
+ }
}
@Override
public Date materializeObject(ResultSet rs, int index, int type) throws Exception {
- Date val = null;
-
+ Date val;
switch (type) {
case Types.TIMESTAMP:
val = rs.getTimestamp(index);
@@ -80,10 +78,8 @@ public class UtilDateType implements ExtendedType<Date> {
}
@Override
- public Date materializeObject(CallableStatement cs, int index, int type)
- throws Exception {
- Date val = null;
-
+ public Date materializeObject(CallableStatement cs, int index, int type) throws Exception {
+ Date val;
switch (type) {
case Types.TIMESTAMP:
val = cs.getTimestamp(index);
@@ -113,8 +109,7 @@ public class UtilDateType implements ExtendedType<Date> {
if (value == null) {
statement.setNull(pos, type);
- }
- else {
+ } else {
statement.setObject(pos, convertToJdbcObject(value, type), type);
}
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectType.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectType.java
new file mode 100644
index 0000000..f66799c
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectType.java
@@ -0,0 +1,63 @@
+/*****************************************************************
+ * 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;
+
+/**
+ * Descriptor and serialization helper for custom value objects that can be safely stored in the DB.
+ * Lightweight alternative for the {@link ExtendedType}.
+ *
+ * @param <V> type of user's custom object.
+ * @param <T> type that custom object will be serialized to/from
+ * should be backed by appropriate {@link ExtendedType}.
+ *
+ * @since 4.0
+ */
+public interface ValueObjectType<V, T> {
+
+ /**
+ * @return base type used to serialize <b>V</b> objects to.
+ */
+ Class<T> getTargetType();
+
+ /**
+ * @return type of Objects described by this ValueObjectType.
+ */
+ Class<V> getValueType();
+
+ /**
+ * @param value of type T
+ * @return java object
+ */
+ V toJavaObject(T value);
+
+ /**
+ * @param object java object
+ * @return value of type T
+ */
+ T fromJavaObject(V object);
+
+ /**
+ * Returned value should be same for objects that is logically equal.
+ *
+ * @return String representation usable for cache.
+ */
+ String toCacheKey(V object);
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectTypeFactory.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectTypeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectTypeFactory.java
new file mode 100644
index 0000000..5ce4273
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectTypeFactory.java
@@ -0,0 +1,101 @@
+/*****************************************************************
+ * 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.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+
+/**
+ * @since 4.0
+ */
+public class ValueObjectTypeFactory implements ExtendedTypeFactory {
+
+ ValueObjectTypeRegistry valueObjectTypeRegistry;
+
+ private ExtendedTypeMap map;
+
+ public ValueObjectTypeFactory(ExtendedTypeMap map, ValueObjectTypeRegistry valueObjectTypeRegistry) {
+ this.map = map;
+ this.valueObjectTypeRegistry = valueObjectTypeRegistry;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public ExtendedType<? extends ValueObjectType> getType(Class<?> objectClass) {
+
+ ValueObjectType<?, ?> valueObjectType = valueObjectTypeRegistry.getValueType(objectClass);
+ if(valueObjectType == null) {
+ return null;
+ }
+ ExtendedType<?> decorator = map.getExplictlyRegisteredType(valueObjectType.getTargetType().getName());
+
+ return new ExtendedTypeConverter(decorator, valueObjectType);
+ }
+
+ static class ExtendedTypeConverter<T, E> implements ExtendedType<T> {
+
+ private ExtendedType<E> extendedType;
+ private ValueObjectType<T, E> valueObjectType;
+
+ ExtendedTypeConverter(ExtendedType<E> extendedType, ValueObjectType<T, E> valueObjectType) {
+ this.extendedType = extendedType;
+ this.valueObjectType = valueObjectType;
+ }
+
+ @Override
+ public String getClassName() {
+ return valueObjectType.getValueType().getName();
+ }
+
+ protected T toJavaObject(E materializedValue) {
+ if(materializedValue == null) {
+ return null;
+ }
+ return valueObjectType.toJavaObject(materializedValue);
+ }
+
+ @Override
+ public T materializeObject(CallableStatement rs, int index, int type) throws Exception {
+ return toJavaObject(extendedType.materializeObject(rs, index, type));
+ }
+
+ @Override
+ public T materializeObject(ResultSet rs, int index, int type) throws Exception {
+ return toJavaObject(extendedType.materializeObject(rs, index, type));
+ }
+
+ @Override
+ public void setJdbcObject(PreparedStatement statement, T value, int pos, int type, int precision) throws Exception {
+ E dbValue = value == null ? null : valueObjectType.fromJavaObject(value);
+ extendedType.setJdbcObject(statement, dbValue, pos, type, precision);
+ }
+
+ @Override
+ public String toString(T value) {
+ if (value == null) {
+ return "NULL";
+ }
+
+ return valueObjectType.toCacheKey(value);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectTypeRegistry.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectTypeRegistry.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectTypeRegistry.java
new file mode 100644
index 0000000..1af249f
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ValueObjectTypeRegistry.java
@@ -0,0 +1,39 @@
+/*****************************************************************
+ * 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;
+
+/**
+ * <p>Registry of user-defined descriptors of custom value objects' classes.</p>
+ * <p>Used to convert this objects into values that can be used directly with JDBC.</p>
+ * <p>Part of replacement for the {@link ExtendedType ExtendedTypes API} for the end-user.</p>
+ *
+ * @see ValueObjectType
+ * @since 4.0
+ */
+public interface ValueObjectTypeRegistry {
+
+ /**
+ * Lookup descriptor in this registry.
+ *
+ * @param valueClass class of the custom value object
+ * @return {@link ValueObjectType} descriptor
+ */
+ <T> ValueObjectType<T,?> getValueType(Class<? extends T> valueClass);
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5e9f0e0f/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
index 67ad5d0..f282939 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java
@@ -24,6 +24,7 @@ import org.apache.cayenne.DataChannelFilter;
import org.apache.cayenne.access.DataDomain;
import org.apache.cayenne.access.DataNode;
import org.apache.cayenne.access.DataRowStoreFactory;
+import org.apache.cayenne.access.types.ValueObjectTypeRegistry;
import org.apache.cayenne.cache.NestedQueryCache;
import org.apache.cayenne.cache.QueryCache;
import org.apache.cayenne.configuration.ConfigurationTree;
@@ -88,6 +89,9 @@ public class DataDomainProvider implements Provider<DataDomain> {
@Inject
protected DataNodeFactory dataNodeFactory;
+ @Inject
+ protected ValueObjectTypeRegistry valueObjectTypeRegistry;
+
@Override
public DataDomain get() throws ConfigurationException {
@@ -127,6 +131,7 @@ public class DataDomainProvider implements Provider<DataDomain> {
dataDomain.getEntityResolver().applyDBLayerDefaults();
dataDomain.getEntityResolver().applyObjectLayerDefaults();
+ dataDomain.getEntityResolver().setValueObjectTypeRegistry(valueObjectTypeRegistry);
for (DataNodeDescriptor nodeDescriptor : descriptor.getNodeDescriptors()) {
addDataNode(dataDomain, nodeDescriptor);