diff --git a/gradle/libraries.gradle b/gradle/libraries.gradle
index 4b8548d8b3..8aa97bd43b 100644
--- a/gradle/libraries.gradle
+++ b/gradle/libraries.gradle
@@ -24,6 +24,8 @@ ext {
javassistVersion = '3.22.0-GA'
byteBuddyVersion = '1.8.0' // Now with JDK10 compatibility and preliminary support for JDK11
+ geolatteVersion = '1.3.0'
+
// Wildfly version targeted by module ZIP; Arquillian/Shrinkwrap versions used for CDI testing and testing the module ZIP
wildflyVersion = '12.0.0.Final'
arquillianVersion = '1.1.11.Final'
@@ -31,6 +33,8 @@ ext {
shrinkwrapDescriptorsVersion = '2.0.0-alpha-8'
wildflyArquillianContainerVersion = '2.0.0.Final'
+ jodaTimeVersion = '2.3'
+
libraries = [
// Ant
ant: 'org.apache.ant:ant:1.8.2',
@@ -74,6 +78,8 @@ ext {
jaxb2_jaxb: 'org.jvnet.jaxb2_commons:jaxb2-basics-jaxb:2.2.4-1',
jaxb2_jaxb_xjc: 'org.jvnet.jaxb2_commons:jaxb2-basics-jaxb-xjc:2.2.4-1',
+ geolatte: "org.geolatte:geolatte-geom:${geolatteVersion}",
+
// Animal Sniffer Ant Task and Java 1.6 API signature file
// not using 1.9 for the time being due to MANIMALSNIFFER-34
animal_sniffer: 'org.codehaus.mojo:animal-sniffer-ant-tasks:1.13',
@@ -105,6 +111,8 @@ ext {
db2: 'com.ibm.db2:db2jcc:10.5',
hana: 'com.sap.db.jdbc:ngdbc:2.2.1', // for HANA 1 the minimum required client version is 1.120.20
+ jodaTime: "joda-time:joda-time:${jodaTimeVersion}",
+
informix: 'com.ibm.informix:jdbc:4.10.7.20160517',
jboss_jta: "org.jboss.jbossts:jbossjta:4.16.4.Final",
xapool: "com.experlog:xapool:1.5.0",
diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle
index b2a9c3ee82..50263efd75 100644
--- a/hibernate-core/hibernate-core.gradle
+++ b/hibernate-core/hibernate-core.gradle
@@ -69,7 +69,7 @@ dependencies {
testCompile( libraries.classmate )
testCompile( libraries.mockito )
testCompile( libraries.mockito_inline )
- testCompile( 'joda-time:joda-time:2.3' )
+ testCompile( libraries.jodaTime )
testCompile( libraries.cdi ) {
// we need to force it to make sure we influence the one coming from arquillian
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/TypeContributions.java b/hibernate-core/src/main/java/org/hibernate/boot/model/TypeContributions.java
index d85c8912e5..8f2dcbfa94 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/TypeContributions.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/TypeContributions.java
@@ -7,6 +7,8 @@
package org.hibernate.boot.model;
import org.hibernate.type.BasicType;
+import org.hibernate.type.StandardBasicTypeTemplate;
+import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
@@ -19,34 +21,56 @@ import org.hibernate.usertype.UserType;
* @author Steve Ebersole
*/
public interface TypeContributions {
+ TypeConfiguration getTypeConfiguration();
+
+ /**
+ * Add the JavaTypeDescriptor to the {@link TypeConfiguration}'s
+ * {@link JavaTypeDescriptorRegistry}
+ */
+ void contributeJavaTypeDescriptor(JavaTypeDescriptor descriptor);
+
+ /**
+ * Add the JavaTypeDescriptor to the {@link TypeConfiguration}'s
+ * {@link JavaTypeDescriptorRegistry}
+ */
+ void contributeSqlTypeDescriptor(SqlTypeDescriptor descriptor);
+
void contributeType(BasicType type);
/**
- * @deprecated (since 5.3) It will be replaced by {@link #contributeType(BasicType)}
- * but do not move to it before 6.0
+ * @deprecated (since 5.3) Use {@link #contributeType(BasicType)} instead. Basic
+ * types will be defined and handled much differently in 6.0 based on a combination
+ * of {@link JavaTypeDescriptor}, {@link SqlTypeDescriptor} and a concept of a "value
+ * converter" (a JPA AttributeConverter, an enum value resolver, etc). To get as
+ * close as possible in 5.3 use existing {@link JavaTypeDescriptor} and
+ * {@link SqlTypeDescriptor} implementations (or write your own for custom types)
+ * and use {@link StandardBasicTypeTemplate} to combine those with
+ * registration keys and call {@link #contributeType(BasicType)} instead
*/
@Deprecated
void contributeType(BasicType type, String... keys);
/**
- * @deprecated (since 5.3) It will be replaced by {@link #contributeType(BasicType)}
- * but do not move to it before 6.0
+ * @deprecated (since 5.3) Use {@link #contributeType(BasicType)} instead.
+ * {@link UserType}, as currently defined, will be done very differently in 6.0.
+ * In most cases a {@link UserType} can be simply replaced with proper
+ * {@link JavaTypeDescriptor}. To get as close as possible to 6.0 in 5.3 use
+ * existing {@link JavaTypeDescriptor} and {@link SqlTypeDescriptor}
+ * implementations (or write your own for custom impls) and use
+ * {@link StandardBasicTypeTemplate} to combine those with registration keys
+ * and call {@link #contributeType(BasicType)} instead
*/
+ @Deprecated
void contributeType(UserType type, String... keys);
/**
- * @deprecated (since 5.3) It will be replaced by {@link #contributeType(BasicType)}
- * but do not move to it before 6.0
+ * @deprecated (since 5.3) Use {@link #contributeType(BasicType)} instead.
+ * {@link CompositeUserType}, as currently defined, will be done very differently
+ * in 6.0. {@link CompositeUserType} should be replaced with a normal Hibernate
+ * component or JPA embeddable (different names, same thing. This embeddable
+ * may contain, in turn, custom types that should be handled as described on these
+ * methods
*/
+ @Deprecated
void contributeType(CompositeUserType type, String... keys);
-
- /*
- * Add the JavaTypeDescriptor to the
- * @param descriptor
- */
- void contributeJavaTypeDescriptor(JavaTypeDescriptor descriptor);
-
- void contributeSqlTypeDescriptor(SqlTypeDescriptor descriptor);
-
- TypeConfiguration getTypeConfiguration();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/convert/spi/JpaAttributeConverterCreationContext.java b/hibernate-core/src/main/java/org/hibernate/boot/model/convert/spi/JpaAttributeConverterCreationContext.java
index bb9c19af9f..03a9bd34ef 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/model/convert/spi/JpaAttributeConverterCreationContext.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/model/convert/spi/JpaAttributeConverterCreationContext.java
@@ -7,7 +7,7 @@
package org.hibernate.boot.model.convert.spi;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
-import org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry;
+import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
/**
* Access to information that implementors of
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java
index 302b9f4763..4dff977e74 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java
@@ -64,7 +64,7 @@ public class StandardServiceRegistryBuilder {
* @param bootstrapServiceRegistry Provided bootstrap registry to use.
*/
public StandardServiceRegistryBuilder(BootstrapServiceRegistry bootstrapServiceRegistry) {
- this( bootstrapServiceRegistry, LoadedConfig.baseline() );
+ this( bootstrapServiceRegistry, LoadedConfig.baseline() );
}
/**
@@ -72,7 +72,9 @@ public class StandardServiceRegistryBuilder {
*
* @param bootstrapServiceRegistry Provided bootstrap registry to use.
*/
- public StandardServiceRegistryBuilder(BootstrapServiceRegistry bootstrapServiceRegistry, LoadedConfig loadedConfigBaseline) {
+ public StandardServiceRegistryBuilder(
+ BootstrapServiceRegistry bootstrapServiceRegistry,
+ LoadedConfig loadedConfigBaseline) {
this.settings = Environment.getProperties();
this.bootstrapServiceRegistry = bootstrapServiceRegistry;
this.configLoader = new ConfigLoader( bootstrapServiceRegistry );
@@ -103,7 +105,7 @@ public class StandardServiceRegistryBuilder {
/**
* Read settings from a {@link java.util.Properties} file by resource name.
- *
+ *
* Differs from {@link #configure()} and {@link #configure(String)} in that here we expect to read a
* {@link java.util.Properties} file while for {@link #configure} we read the XML variant.
*
@@ -114,7 +116,7 @@ public class StandardServiceRegistryBuilder {
* @see #configure()
* @see #configure(String)
*/
- @SuppressWarnings( {"unchecked"})
+ @SuppressWarnings({"unchecked"})
public StandardServiceRegistryBuilder loadProperties(String resourceName) {
settings.putAll( configLoader.loadProperties( resourceName ) );
return this;
@@ -122,7 +124,7 @@ public class StandardServiceRegistryBuilder {
/**
* Read settings from a {@link java.util.Properties} file by File reference
- *
+ *
* Differs from {@link #configure()} and {@link #configure(String)} in that here we expect to read a
* {@link java.util.Properties} file while for {@link #configure} we read the XML variant.
*
@@ -133,7 +135,7 @@ public class StandardServiceRegistryBuilder {
* @see #configure()
* @see #configure(String)
*/
- @SuppressWarnings( {"unchecked"})
+ @SuppressWarnings({"unchecked"})
public StandardServiceRegistryBuilder loadProperties(File file) {
settings.putAll( configLoader.loadProperties( file ) );
return this;
@@ -171,7 +173,7 @@ public class StandardServiceRegistryBuilder {
return configure( configLoader.loadConfigXmlUrl( url ) );
}
- @SuppressWarnings( {"unchecked"})
+ @SuppressWarnings({"unchecked"})
public StandardServiceRegistryBuilder configure(LoadedConfig loadedConfig) {
aggregatedCfgXml.merge( loadedConfig );
settings.putAll( loadedConfig.getConfigurationValues() );
@@ -187,7 +189,7 @@ public class StandardServiceRegistryBuilder {
*
* @return this, for method chaining
*/
- @SuppressWarnings( {"unchecked", "UnusedDeclaration"})
+ @SuppressWarnings({"unchecked", "UnusedDeclaration"})
public StandardServiceRegistryBuilder applySetting(String settingName, Object value) {
settings.put( settingName, value );
return this;
@@ -200,7 +202,7 @@ public class StandardServiceRegistryBuilder {
*
* @return this, for method chaining
*/
- @SuppressWarnings( {"unchecked", "UnusedDeclaration"})
+ @SuppressWarnings({"unchecked", "UnusedDeclaration"})
public StandardServiceRegistryBuilder applySettings(Map settings) {
this.settings.putAll( settings );
return this;
@@ -213,7 +215,7 @@ public class StandardServiceRegistryBuilder {
*
* @return this, for method chaining
*/
- @SuppressWarnings( {"UnusedDeclaration"})
+ @SuppressWarnings({"UnusedDeclaration"})
public StandardServiceRegistryBuilder addInitiator(StandardServiceInitiator initiator) {
initiators.add( initiator );
return this;
@@ -227,7 +229,7 @@ public class StandardServiceRegistryBuilder {
*
* @return this, for method chaining
*/
- @SuppressWarnings( {"unchecked"})
+ @SuppressWarnings({"unchecked"})
public StandardServiceRegistryBuilder addService(final Class serviceRole, final Service service) {
providedServices.add( new ProvidedService( serviceRole, service ) );
return this;
@@ -289,9 +291,11 @@ public class StandardServiceRegistryBuilder {
@SuppressWarnings("deprecation")
private void applyServiceContributingIntegrators() {
- for ( Integrator integrator : bootstrapServiceRegistry.getService( IntegratorService.class ).getIntegrators() ) {
+ for ( Integrator integrator : bootstrapServiceRegistry.getService( IntegratorService.class )
+ .getIntegrators() ) {
if ( org.hibernate.integrator.spi.ServiceContributingIntegrator.class.isInstance( integrator ) ) {
- org.hibernate.integrator.spi.ServiceContributingIntegrator.class.cast( integrator ).prepareServices( this );
+ org.hibernate.integrator.spi.ServiceContributingIntegrator.class.cast( integrator ).prepareServices(
+ this );
}
}
}
@@ -332,4 +336,4 @@ public class StandardServiceRegistryBuilder {
( (StandardServiceRegistryImpl) serviceRegistry ).destroy();
}
-}
+}
\ No newline at end of file
diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java
index b6e59d6a4a..a563522f18 100644
--- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java
+++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java
@@ -50,13 +50,13 @@ import org.hibernate.type.Type;
import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter;
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
+import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
-import org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry;
+import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
import org.hibernate.type.descriptor.sql.JdbcTypeJavaClassMappings;
import org.hibernate.type.descriptor.sql.LobTypeMappings;
import org.hibernate.type.descriptor.sql.NationalizedTypeMappings;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
-import org.hibernate.type.descriptor.sql.SqlTypeDescriptorRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.DynamicParameterizedType;
@@ -576,13 +576,13 @@ public class SimpleValue implements KeyValue {
}
@Override
- public JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
+ public org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry getJavaTypeDescriptorRegistry() {
return metadata.getTypeConfiguration().getJavaTypeDescriptorRegistry();
}
}
);
- final JavaTypeDescriptor entityAttributeJavaTypeDescriptor = jpaAttributeConverter.getDomainJavaTypeDescriptor();
+ final BasicJavaDescriptor entityAttributeJavaTypeDescriptor = jpaAttributeConverter.getDomainJavaTypeDescriptor();
// build the SqlTypeDescriptor adapter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -591,7 +591,11 @@ public class SimpleValue implements KeyValue {
// corresponding to the AttributeConverter's declared "databaseColumnJavaType" (how we read that value out
// of ResultSets). See JdbcTypeJavaClassMappings for details. Again, given example, this should return
// VARCHAR/CHAR
- int jdbcTypeCode = JdbcTypeJavaClassMappings.INSTANCE.determineJdbcTypeCodeForJavaClass( jpaAttributeConverter.getRelationalJavaTypeDescriptor().getJavaType() );
+ final SqlTypeDescriptor recommendedSqlType = jpaAttributeConverter.getRelationalJavaTypeDescriptor().getJdbcRecommendedSqlType(
+ // todo (6.0) : handle the other JdbcRecommendedSqlTypeMappingContext methods
+ metadata::getTypeConfiguration
+ );
+ int jdbcTypeCode = recommendedSqlType.getSqlType();
if ( isLob() ) {
if ( LobTypeMappings.INSTANCE.hasCorrespondingLobCode( jdbcTypeCode ) ) {
jdbcTypeCode = LobTypeMappings.INSTANCE.getCorrespondingLobCode( jdbcTypeCode );
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/JpaAttributeConverterImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/JpaAttributeConverterImpl.java
index 941a37ecca..6be89acaf1 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/JpaAttributeConverterImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/internal/JpaAttributeConverterImpl.java
@@ -10,6 +10,7 @@ import javax.persistence.AttributeConverter;
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
import org.hibernate.resource.beans.spi.ManagedBean;
+import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
@@ -20,8 +21,8 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
public class JpaAttributeConverterImpl implements JpaAttributeConverter {
private final ManagedBean> attributeConverterBean;
private final JavaTypeDescriptor> converterJavaTypeDescriptor;
- private final JavaTypeDescriptor domainJavaTypeDescriptor;
- private final JavaTypeDescriptor relationalJavaTypeDescriptor;
+ private final BasicJavaDescriptor domainJavaTypeDescriptor;
+ private final BasicJavaDescriptor relationalJavaTypeDescriptor;
public JpaAttributeConverterImpl(
ManagedBean> attributeConverterBean,
@@ -30,8 +31,13 @@ public class JpaAttributeConverterImpl implements JpaAttributeConverter relationalJavaTypeDescriptor) {
this.attributeConverterBean = attributeConverterBean;
this.converterJavaTypeDescriptor = converterJavaTypeDescriptor;
- this.domainJavaTypeDescriptor = domainJavaTypeDescriptor;
- this.relationalJavaTypeDescriptor = relationalJavaTypeDescriptor;
+ this.domainJavaTypeDescriptor = (BasicJavaDescriptor) domainJavaTypeDescriptor;
+ this.relationalJavaTypeDescriptor = (BasicJavaDescriptor) relationalJavaTypeDescriptor;
+ }
+
+ @Override
+ public ManagedBean> getConverterBean() {
+ return attributeConverterBean;
}
@Override
@@ -50,12 +56,12 @@ public class JpaAttributeConverterImpl implements JpaAttributeConverter getDomainJavaTypeDescriptor() {
+ public BasicJavaDescriptor getDomainJavaTypeDescriptor() {
return domainJavaTypeDescriptor;
}
@Override
- public JavaTypeDescriptor getRelationalJavaTypeDescriptor() {
+ public BasicJavaDescriptor getRelationalJavaTypeDescriptor() {
return relationalJavaTypeDescriptor;
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/JpaAttributeConverter.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/JpaAttributeConverter.java
index 2dad1c1b0d..a5f5d4f4b7 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/JpaAttributeConverter.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/convert/spi/JpaAttributeConverter.java
@@ -8,6 +8,8 @@ package org.hibernate.metamodel.model.convert.spi;
import javax.persistence.AttributeConverter;
+import org.hibernate.resource.beans.spi.ManagedBean;
+import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
@@ -17,6 +19,9 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
*/
public interface JpaAttributeConverter extends BasicValueConverter {
JavaTypeDescriptor> getConverterJavaTypeDescriptor();
- JavaTypeDescriptor getDomainJavaTypeDescriptor();
- JavaTypeDescriptor getRelationalJavaTypeDescriptor();
+
+ ManagedBean> getConverterBean();
+
+ BasicJavaDescriptor getDomainJavaTypeDescriptor();
+ BasicJavaDescriptor getRelationalJavaTypeDescriptor();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/ServiceRegistry.java b/hibernate-core/src/main/java/org/hibernate/service/ServiceRegistry.java
index fb77f52810..da5e34d782 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/ServiceRegistry.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/ServiceRegistry.java
@@ -11,7 +11,7 @@ package org.hibernate.service;
*
* @author Steve Ebersole
*/
-public interface ServiceRegistry {
+public interface ServiceRegistry extends AutoCloseable {
/**
* Retrieve this registry's parent registry.
*
@@ -56,4 +56,6 @@ public interface ServiceRegistry {
return service;
}
+ @Override
+ void close();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/service/spi/ServiceRegistryImplementor.java b/hibernate-core/src/main/java/org/hibernate/service/spi/ServiceRegistryImplementor.java
index fc9b545a20..5122727498 100644
--- a/hibernate-core/src/main/java/org/hibernate/service/spi/ServiceRegistryImplementor.java
+++ b/hibernate-core/src/main/java/org/hibernate/service/spi/ServiceRegistryImplementor.java
@@ -25,6 +25,11 @@ public interface ServiceRegistryImplementor extends ServiceRegistry {
*/
ServiceBinding locateServiceBinding(Class serviceRole);
+ @Override
+ default void close() {
+ destroy();
+ }
+
/**
* Release resources
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java
index c7b330ccb3..eb91251e35 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java
@@ -91,7 +91,7 @@ public abstract class AbstractStandardBasicType
@Override
public String[] getRegistrationKeys() {
return registerUnderJavaType()
- ? new String[] { getName(), javaTypeDescriptor.getJavaTypeClass().getName() }
+ ? new String[] { getName(), javaTypeDescriptor.getJavaType().getName() }
: new String[] { getName() };
}
@@ -128,7 +128,7 @@ public abstract class AbstractStandardBasicType
@Override
public final Class getReturnedClass() {
- return javaTypeDescriptor.getJavaTypeClass();
+ return javaTypeDescriptor.getJavaType();
}
@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java
index 3b4b996dbd..cead4fd315 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java
@@ -169,6 +169,12 @@ public class BasicTypeRegistry implements Serializable {
register( new CompositeCustomType( type, keys ) );
}
+ public void unregister(String... keys) {
+ for ( String key : keys ) {
+ registry.remove( key );
+ }
+ }
+
public BasicType getRegisteredType(String key) {
return registry.get( key );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/PostgresUUIDType.java b/hibernate-core/src/main/java/org/hibernate/type/PostgresUUIDType.java
index d04bf5e26c..3b7ee81fa4 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/PostgresUUIDType.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/PostgresUUIDType.java
@@ -16,11 +16,13 @@ import java.util.UUID;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
+import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicBinder;
import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+import org.hibernate.type.spi.TypeConfiguration;
/**
* Specialized type mapping for {@link UUID} and the Postgres UUID data type (which is mapped as OTHER in its
@@ -59,6 +61,12 @@ public class PostgresUUIDType extends AbstractSingleColumnStandardBasicType ValueBinder getBinder(final JavaTypeDescriptor javaTypeDescriptor) {
return new BasicBinder( javaTypeDescriptor, this ) {
@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractTypeDescriptor.java
index 2ea2036701..0266f6f423 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractTypeDescriptor.java
@@ -16,9 +16,14 @@ import org.hibernate.internal.util.compare.EqualsHelper;
/**
* Abstract adapter for Java type descriptors.
*
+ * @apiNote This abstract descriptor implements BasicJavaDescriptor
+ * because we currently only categorize "basic" JavaTypeDescriptors,
+ * as in the {@link javax.persistence.metamodel.Type.PersistenceType#BASIC}
+ * sense
+ *
* @author Steve Ebersole
*/
-public abstract class AbstractTypeDescriptor implements JavaTypeDescriptor, Serializable {
+public abstract class AbstractTypeDescriptor implements BasicJavaDescriptor, Serializable {
private final Class type;
private final MutabilityPlan mutabilityPlan;
private final Comparator comparator;
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BasicJavaDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BasicJavaDescriptor.java
new file mode 100644
index 0000000000..7bca9ce773
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BasicJavaDescriptor.java
@@ -0,0 +1,36 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.type.descriptor.java;
+
+import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
+import org.hibernate.type.descriptor.sql.JdbcTypeJavaClassMappings;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+
+/**
+ * @apiNote Currently this is the only high-level categorization of
+ * JavaTypeDescriptor, but 6.0 will have specific JavaTypeDescriptor
+ * categorizations for managed-type, mapped-superclass, identifiable-type, entity, embeddable,
+ * collections.
+ *
+ * @author Steve Ebersole
+ */
+public interface BasicJavaDescriptor extends JavaTypeDescriptor {
+ /**
+ * Obtain the "recommended" SQL type descriptor for this Java type. The recommended
+ * aspect comes from the JDBC spec (mostly).
+ *
+ * @param context Contextual information
+ *
+ * @return The recommended SQL type descriptor
+ */
+ default SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
+ // match legacy behavior
+ return context.getTypeConfiguration().getSqlTypeDescriptorRegistry().getDescriptor(
+ JdbcTypeJavaClassMappings.INSTANCE.determineJdbcTypeCodeForJavaClass( getJavaType() )
+ );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/EnumJavaTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/EnumJavaTypeDescriptor.java
index a3fa10babd..1b1039968f 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/EnumJavaTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/EnumJavaTypeDescriptor.java
@@ -15,7 +15,7 @@ import org.hibernate.type.descriptor.WrapperOptions;
*/
public class EnumJavaTypeDescriptor extends AbstractTypeDescriptor {
@SuppressWarnings("unchecked")
- protected EnumJavaTypeDescriptor(Class type) {
+ public EnumJavaTypeDescriptor(Class type) {
super( type, ImmutableMutabilityPlan.INSTANCE );
//JavaTypeDescriptorRegistry.INSTANCE.addDescriptor( this );
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JavaTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JavaTypeDescriptor.java
index 18489391bb..bf8c81e456 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JavaTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JavaTypeDescriptor.java
@@ -9,6 +9,8 @@ package org.hibernate.type.descriptor.java;
import java.io.Serializable;
import java.util.Comparator;
+import org.hibernate.internal.util.compare.ComparableComparator;
+import org.hibernate.internal.util.compare.EqualsHelper;
import org.hibernate.type.descriptor.WrapperOptions;
/**
@@ -37,17 +39,18 @@ public interface JavaTypeDescriptor extends Serializable {
/**
* Retrieve the mutability plan for this Java type.
- *
- * @return The mutability plan
*/
- public MutabilityPlan getMutabilityPlan();
+ @SuppressWarnings("unchecked")
+ default MutabilityPlan getMutabilityPlan() {
+ return ImmutableMutabilityPlan.INSTANCE;
+ }
/**
* Retrieve the natural comparator for this type.
- *
- * @return The natural comparator.
*/
- public Comparator getComparator();
+ default Comparator getComparator() {
+ return Comparable.class.isAssignableFrom( Comparable.class ) ? ComparableComparator.INSTANCE : null;
+ }
/**
* Extract a proper hash code for this value.
@@ -56,7 +59,12 @@ public interface JavaTypeDescriptor extends Serializable {
*
* @return The extracted hash code.
*/
- public int extractHashCode(T value);
+ default int extractHashCode(T value) {
+ if ( value == null ) {
+ throw new IllegalArgumentException( "Value to extract hashCode from cannot be null" );
+ }
+ return value.hashCode();
+ }
/**
* Determine if two instances are equal
@@ -66,7 +74,9 @@ public interface JavaTypeDescriptor extends Serializable {
*
* @return True if the two are considered equal; false otherwise.
*/
- public boolean areEqual(T one, T another);
+ default boolean areEqual(T one, T another) {
+ return EqualsHelper.areEqual( one, another );
+ }
/**
* Extract a loggable representation of the value.
@@ -75,11 +85,15 @@ public interface JavaTypeDescriptor extends Serializable {
*
* @return The loggable representation
*/
- public String extractLoggableRepresentation(T value);
+ default String extractLoggableRepresentation(T value) {
+ return toString( value );
+ }
- public String toString(T value);
+ default String toString(T value) {
+ return value == null ? "null" : value.toString();
+ }
- public T fromString(String string);
+ T fromString(String string);
/**
* Unwrap an instance of our handled Java type into the requested type.
@@ -97,7 +111,7 @@ public interface JavaTypeDescriptor extends Serializable {
*
* @return The unwrapped value.
*/
- public X unwrap(T value, Class type, WrapperOptions options);
+ X unwrap(T value, Class type, WrapperOptions options);
/**
* Wrap a value as our handled Java type.
@@ -110,5 +124,5 @@ public interface JavaTypeDescriptor extends Serializable {
*
* @return The wrapped value.
*/
- public T wrap(X value, WrapperOptions options);
+ T wrap(X value, WrapperOptions options);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JavaTypeDescriptorRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JavaTypeDescriptorRegistry.java
index e1d85ace0e..981dcee298 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JavaTypeDescriptorRegistry.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/JavaTypeDescriptorRegistry.java
@@ -7,7 +7,6 @@
package org.hibernate.type.descriptor.java;
import java.io.Serializable;
-import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.HibernateException;
@@ -16,6 +15,7 @@ import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.type.descriptor.WrapperOptions;
+import org.hibernate.type.descriptor.java.spi.RegistryHelper;
import org.hibernate.type.spi.TypeConfiguration;
/**
@@ -84,8 +84,7 @@ public class JavaTypeDescriptorRegistry implements Serializable {
}
private JavaTypeDescriptor addDescriptorInternal(JavaTypeDescriptor descriptor) {
- JavaTypeDescriptor javaTypeDescriptor = descriptorsByClass.put( descriptor.getJavaType(), descriptor );
- return javaTypeDescriptor;
+ return descriptorsByClass.put( descriptor.getJavaType(), descriptor );
}
/**
@@ -113,43 +112,26 @@ public class JavaTypeDescriptorRegistry implements Serializable {
*/
@Deprecated
@SuppressWarnings("unchecked")
- public JavaTypeDescriptor getDescriptor(Class cls) {
- if ( cls == null ) {
- throw new IllegalArgumentException( "Class passed to locate Java type descriptor cannot be null" );
- }
+ public JavaTypeDescriptor getDescriptor(Class cls) {
+ return RegistryHelper.INSTANCE.resolveDescriptor(
+ descriptorsByClass,
+ cls,
+ () -> {
+ if ( Serializable.class.isAssignableFrom( cls ) ) {
+ return new SerializableTypeDescriptor( cls );
+ }
- JavaTypeDescriptor descriptor = descriptorsByClass.get( cls );
- if ( descriptor != null ) {
- return descriptor;
- }
+ log.debugf(
+ "Could not find matching JavaTypeDescriptor for requested Java class [%s]; using fallback. " +
+ "This means Hibernate does not know how to perform certain basic operations in relation to this Java type." +
+ "",
+ cls.getName()
+ );
+ checkEqualsAndHashCode( cls );
- if ( cls.isEnum() ) {
- descriptor = new EnumJavaTypeDescriptor( cls );
- descriptorsByClass.put( cls, descriptor );
- return descriptor;
- }
-
- // find the first "assignable" match
- for ( Map.Entry entry : descriptorsByClass.entrySet() ) {
- if ( entry.getKey().isAssignableFrom( cls ) ) {
- log.debugf( "Using cached JavaTypeDescriptor instance for Java class [%s]", cls.getName() );
- return entry.getValue();
- }
- }
-
- if ( Serializable.class.isAssignableFrom( cls ) ) {
- return new SerializableTypeDescriptor( cls );
- }
-
- log.debugf(
- "Could not find matching JavaTypeDescriptor for requested Java class [%s]; using fallback. " +
- "This means Hibernate does not know how to perform certain basic operations in relation to this Java type." +
- "",
- cls.getName()
+ return new FallbackJavaTypeDescriptor<>( cls );
+ }
);
- checkEqualsAndHashCode( cls );
-
- return new FallbackJavaTypeDescriptor<>( cls );
}
@SuppressWarnings("unchecked")
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/SerializableTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/SerializableTypeDescriptor.java
index 08a914703e..90fdafaf2b 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/SerializableTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/SerializableTypeDescriptor.java
@@ -29,11 +29,9 @@ public class SerializableTypeDescriptor extends Abstract
// unfortunately the param types cannot be the same so use something other than 'T' here to make that obvious
public static class SerializableMutabilityPlan extends MutableMutabilityPlan {
+ public static final SerializableMutabilityPlan INSTANCE = new SerializableMutabilityPlan<>();
- public static final SerializableMutabilityPlan INSTANCE
- = new SerializableMutabilityPlan( );
-
- public SerializableMutabilityPlan() {
+ private SerializableMutabilityPlan() {
}
@Override
@@ -124,7 +122,7 @@ public class SerializableTypeDescriptor extends Abstract
throw new HibernateException( e );
}
}
- else if ( getJavaTypeClass().isInstance( value ) ) {
+ else if ( getJavaType().isInstance( value ) ) {
return (T) value;
}
throw unknownWrap( value.getClass() );
@@ -136,6 +134,6 @@ public class SerializableTypeDescriptor extends Abstract
@SuppressWarnings({ "unchecked" })
protected T fromBytes(byte[] bytes) {
- return (T) SerializationHelper.deserialize( bytes, getJavaTypeClass().getClassLoader() );
+ return (T) SerializationHelper.deserialize( bytes, getJavaType().getClassLoader() );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java
index 11b96bb444..a71b4529a1 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeDescriptorRegistry.java
@@ -7,10 +7,13 @@
package org.hibernate.type.descriptor.java.spi;
import java.io.Serializable;
+import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
+import org.jboss.logging.Logger;
+
/**
* Basically a map from {@link Class} -> {@link JavaTypeDescriptor}
*
@@ -19,25 +22,41 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @since 5.3
*/
-public class JavaTypeDescriptorRegistry
- extends org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry
- implements Serializable {
+public class JavaTypeDescriptorRegistry implements Serializable {
+ private static final Logger log = Logger.getLogger( JavaTypeDescriptorRegistry.class );
- private final TypeConfiguration typeConfiguration;
- private final org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry javaTypeDescriptorRegistry;
+ private ConcurrentHashMap descriptorsByClass = new ConcurrentHashMap<>();
+
+ @SuppressWarnings("unused")
public JavaTypeDescriptorRegistry(TypeConfiguration typeConfiguration) {
- this.typeConfiguration = typeConfiguration;
- javaTypeDescriptorRegistry = org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry.INSTANCE;
}
- @Override
public JavaTypeDescriptor getDescriptor(Class javaType) {
- return javaTypeDescriptorRegistry.getDescriptor( javaType );
+ return RegistryHelper.INSTANCE.resolveDescriptor(
+ descriptorsByClass,
+ javaType,
+ () -> {
+ log.debugf(
+ "Could not find matching scoped JavaTypeDescriptor for requested Java class [%s]; " +
+ "falling back to static registry",
+ javaType.getName()
+ );
+
+ return org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry.INSTANCE.getDescriptor( javaType );
+ }
+ );
}
- @Override
public void addDescriptor(JavaTypeDescriptor descriptor) {
- javaTypeDescriptorRegistry.addDescriptor( descriptor );
+ JavaTypeDescriptor old = descriptorsByClass.put( descriptor.getJavaType(), descriptor );
+ if ( old != null ) {
+ log.debugf(
+ "JavaTypeDescriptorRegistry entry replaced : %s -> %s (was %s)",
+ descriptor.getJavaType(),
+ descriptor,
+ old
+ );
+ }
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/RegistryHelper.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/RegistryHelper.java
new file mode 100644
index 0000000000..da449213eb
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/RegistryHelper.java
@@ -0,0 +1,63 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.type.descriptor.java.spi;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
+import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
+import org.hibernate.type.descriptor.java.SerializableTypeDescriptor;
+
+import org.jboss.logging.Logger;
+
+/**
+ * @author Steve Ebersole
+ */
+public class RegistryHelper {
+ private static final Logger log = Logger.getLogger( RegistryHelper.class );
+
+ /**
+ * Singleton access
+ */
+ public static final RegistryHelper INSTANCE = new RegistryHelper();
+
+ private RegistryHelper() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public JavaTypeDescriptor resolveDescriptor(
+ Map descriptorsByClass,
+ Class cls,
+ Supplier> defaultValueSupplier) {
+ if ( cls == null ) {
+ throw new IllegalArgumentException( "Class passed to locate JavaTypeDescriptor cannot be null" );
+ }
+
+ JavaTypeDescriptor descriptor = descriptorsByClass.get( cls );
+ if ( descriptor != null ) {
+ return descriptor;
+ }
+
+ if ( cls.isEnum() ) {
+ descriptor = new EnumJavaTypeDescriptor( cls );
+ descriptorsByClass.put( cls, descriptor );
+ return descriptor;
+ }
+
+ // find the first "assignable" match
+ for ( Map.Entry entry : descriptorsByClass.entrySet() ) {
+ if ( entry.getKey().isAssignableFrom( cls ) ) {
+ log.debugf( "Using cached JavaTypeDescriptor instance for Java class [%s]", cls.getName() );
+ return entry.getValue();
+ }
+ }
+
+ return defaultValueSupplier.get();
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/spi/JdbcRecommendedSqlTypeMappingContext.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/spi/JdbcRecommendedSqlTypeMappingContext.java
new file mode 100644
index 0000000000..79803b64f6
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/spi/JdbcRecommendedSqlTypeMappingContext.java
@@ -0,0 +1,64 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.type.descriptor.spi;
+
+import java.sql.Types;
+import javax.persistence.EnumType;
+
+import org.hibernate.type.spi.TypeConfiguration;
+
+/**
+ * More-or-less a parameter-object intended for use in determining the SQL/JDBC type recommended
+ * by the JDBC spec (explicitly or implicitly) for a given Java type.
+ *
+ * @see org.hibernate.type.descriptor.java.BasicJavaDescriptor#getJdbcRecommendedSqlType
+ *
+ * @author Steve Ebersole
+ */
+public interface JdbcRecommendedSqlTypeMappingContext {
+ /**
+ * Was nationalized character datatype requested for the given Java type?
+ *
+ * @return {@code true} if nationalized character datatype should be used; {@code false} otherwise.
+ */
+ default boolean isNationalized() {
+ return false;
+ }
+
+ /**
+ * Was LOB datatype requested for the given Java type?
+ *
+ * @return {@code true} if LOB datatype should be used; {@code false} otherwise.
+ */
+ default boolean isLob() {
+ return false;
+ }
+
+ /**
+ * For enum mappings, what style of storage was requested (name vs. ordinal)?
+ *
+ * @return The enum type.
+ */
+ default EnumType getEnumeratedType() {
+ return EnumType.ORDINAL;
+ }
+
+ /**
+ * When mapping a boolean type to the database what is the preferred SQL type code to use?
+ *
+ * Specifically names the key into the
+ * {@link org.hibernate.type.descriptor.sql.spi.SqlTypeDescriptorRegistry}.
+ */
+ default int getPreferredSqlTypeCodeForBoolean() {
+ return Types.BOOLEAN;
+ }
+
+ /**
+ * Provides access to the TypeConfiguration for access to various type-system registries.
+ */
+ TypeConfiguration getTypeConfiguration();
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/SqlTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/SqlTypeDescriptor.java
index a580346ad3..3b5431f84c 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/SqlTypeDescriptor.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/SqlTypeDescriptor.java
@@ -10,7 +10,9 @@ import java.io.Serializable;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
+import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
+import org.hibernate.type.spi.TypeConfiguration;
/**
* Descriptor for the SQL/JDBC side of a value mapping.
@@ -38,6 +40,15 @@ public interface SqlTypeDescriptor extends Serializable {
*/
boolean canBeRemapped();
+ @SuppressWarnings("unchecked")
+ default BasicJavaDescriptor getJdbcRecommendedJavaTypeMapping(TypeConfiguration typeConfiguration) {
+ // match legacy behavior
+ return (BasicJavaDescriptor) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor(
+ JdbcTypeJavaClassMappings.INSTANCE.determineJavaClassForJdbcTypeCode( getSqlType() )
+ );
+
+ }
+
/**
* Get the binder (setting JDBC in-going parameter values) capable of handling values of the type described by the
* passed descriptor.
diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/SqlTypeDescriptorRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/SqlTypeDescriptorRegistry.java
index ac333aabbc..71ad7f6450 100644
--- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/SqlTypeDescriptorRegistry.java
+++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/SqlTypeDescriptorRegistry.java
@@ -151,7 +151,7 @@ public class SqlTypeDescriptorRegistry implements Serializable {
@Override
public ValueBinder getBinder(JavaTypeDescriptor javaTypeDescriptor) {
- if ( Serializable.class.isAssignableFrom( javaTypeDescriptor.getJavaTypeClass() ) ) {
+ if ( Serializable.class.isAssignableFrom( javaTypeDescriptor.getJavaType() ) ) {
return VarbinaryTypeDescriptor.INSTANCE.getBinder( javaTypeDescriptor );
}
@@ -173,7 +173,7 @@ public class SqlTypeDescriptorRegistry implements Serializable {
@Override
@SuppressWarnings("unchecked")
public ValueExtractor getExtractor(JavaTypeDescriptor javaTypeDescriptor) {
- if ( Serializable.class.isAssignableFrom( javaTypeDescriptor.getJavaTypeClass() ) ) {
+ if ( Serializable.class.isAssignableFrom( javaTypeDescriptor.getJavaType() ) ) {
return VarbinaryTypeDescriptor.INSTANCE.getExtractor( javaTypeDescriptor );
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/CustomTypeConverterTest.java b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/CustomTypeConverterTest.java
new file mode 100644
index 0000000000..5182e1ab9c
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/CustomTypeConverterTest.java
@@ -0,0 +1,95 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.test.converter.custom;
+
+import org.hibernate.boot.MetadataSources;
+import org.hibernate.boot.registry.StandardServiceRegistry;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.boot.spi.MetadataBuilderImplementor;
+import org.hibernate.cfg.AvailableSettings;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.tool.schema.Action;
+import org.hibernate.type.spi.TypeConfiguration;
+
+import org.hibernate.testing.junit4.BaseUnitTestCase;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * @author Steve Ebersole
+ */
+public class CustomTypeConverterTest extends BaseUnitTestCase {
+ @Test
+ public void testConverterAppliedStaticRegistration() {
+ // this is how we told users to do it previously using the static reference -
+ // make sure it still works for now
+ org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry.INSTANCE.addDescriptor( MyCustomJavaTypeDescriptor.INSTANCE );
+ org.hibernate.type.descriptor.sql.SqlTypeDescriptorRegistry.INSTANCE.addDescriptor( MyCustomSqlTypeDescriptor.INSTANCE );
+
+ try ( final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
+ .applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
+ .build() ) {
+ final MetadataSources metadataSources = new MetadataSources( ssr )
+ .addAnnotatedClass( MyCustomConverter.class )
+ .addAnnotatedClass( MyEntity.class );
+ final MetadataBuilderImplementor metadataBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder();
+
+ final TypeConfiguration bootTypeConfiguration = metadataBuilder.getBootstrapContext().getTypeConfiguration();
+ performAssertions( metadataBuilder, bootTypeConfiguration );
+
+ }
+ }
+
+ @Test
+ public void testConverterAppliedScopedRegistration() {
+
+ try ( final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
+ .applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
+ .build() ) {
+ final MetadataSources metadataSources = new MetadataSources( ssr )
+ .addAnnotatedClass( MyCustomConverter.class )
+ .addAnnotatedClass( MyEntity.class );
+ final MetadataBuilderImplementor metadataBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder();
+
+ // now the new scoped way
+ final TypeConfiguration bootTypeConfiguration = metadataBuilder.getBootstrapContext().getTypeConfiguration();
+ bootTypeConfiguration.getJavaTypeDescriptorRegistry()
+ .addDescriptor( MyCustomJavaTypeDescriptor.INSTANCE );
+ bootTypeConfiguration.getSqlTypeDescriptorRegistry()
+ .addDescriptor( MyCustomSqlTypeDescriptor.INSTANCE );
+
+ performAssertions( metadataBuilder, bootTypeConfiguration );
+ }
+ }
+
+ protected void performAssertions(
+ MetadataBuilderImplementor metadataBuilder,
+ TypeConfiguration bootTypeConfiguration) {
+ try ( final SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) metadataBuilder.build().buildSessionFactory()) {
+ assertThat(
+ sessionFactory.getMetamodel().getTypeConfiguration(),
+ sameInstance( bootTypeConfiguration )
+ );
+
+ assertThat(
+ bootTypeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( MyCustomJavaType.class ),
+ sameInstance( MyCustomJavaTypeDescriptor.INSTANCE )
+ );
+
+ assertThat(
+ bootTypeConfiguration.getSqlTypeDescriptorRegistry().getDescriptor( MyCustomSqlTypeDescriptor.INSTANCE.getSqlType() ),
+ sameInstance( MyCustomSqlTypeDescriptor.INSTANCE )
+ );
+
+ final EntityPersister entityPersister = sessionFactory.getMetamodel().entityPersister( MyEntity.class );
+ entityPersister.getPropertyType( "customType" );
+ }
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomConverter.java b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomConverter.java
new file mode 100644
index 0000000000..4d3024ccd0
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomConverter.java
@@ -0,0 +1,26 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.test.converter.custom;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+
+/**
+ * @author Steve Ebersole
+ */
+@Converter( autoApply = true )
+public class MyCustomConverter implements AttributeConverter {
+ @Override
+ public String convertToDatabaseColumn(MyCustomJavaType attribute) {
+ return null;
+ }
+
+ @Override
+ public MyCustomJavaType convertToEntityAttribute(String dbData) {
+ return null;
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaType.java b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaType.java
new file mode 100644
index 0000000000..928a37fad9
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaType.java
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.test.converter.custom;
+
+/**
+ * @author Steve Ebersole
+ */
+public class MyCustomJavaType implements Comparable {
+ private String payload;
+
+ public MyCustomJavaType() {
+ this( null );
+ }
+
+ public MyCustomJavaType(String payload) {
+ this.payload = payload;
+ }
+
+ public String getPayload() {
+ return payload;
+ }
+
+ public void setPayload(String payload) {
+ this.payload = payload;
+ }
+
+ @Override
+ public int compareTo(MyCustomJavaType other) {
+ if ( getPayload() == null ) {
+ return -1;
+ }
+
+ if ( other == null || other.getPayload() == null ) {
+ return 1;
+ }
+
+ return getPayload().compareTo( other.getPayload() );
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaTypeDescriptor.java b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaTypeDescriptor.java
new file mode 100644
index 0000000000..228f702828
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomJavaTypeDescriptor.java
@@ -0,0 +1,77 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.test.converter.custom;
+
+import org.hibernate.internal.util.StringHelper;
+import org.hibernate.type.descriptor.WrapperOptions;
+import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
+import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
+import org.hibernate.type.descriptor.java.MutabilityPlan;
+import org.hibernate.type.descriptor.java.MutableMutabilityPlan;
+import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+
+/**
+ * @author Steve Ebersole
+ */
+public class MyCustomJavaTypeDescriptor implements BasicJavaDescriptor {
+ /**
+ * Singleton access
+ */
+ public static final MyCustomJavaTypeDescriptor INSTANCE = new MyCustomJavaTypeDescriptor();
+
+ private final MutableMutabilityPlan mutabilityPlan = new MutableMutabilityPlan() {
+ @Override
+ protected MyCustomJavaType deepCopyNotNull(MyCustomJavaType value) {
+ return value == null ? null : new MyCustomJavaType( value.getPayload() );
+ }
+ };
+
+ private MyCustomJavaTypeDescriptor() {
+ }
+
+ @Override
+ public Class getJavaTypeClass() {
+ return MyCustomJavaType.class;
+ }
+
+ @Override
+ public SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
+ return MyCustomSqlTypeDescriptor.INSTANCE;
+ }
+
+ @Override
+ public MutabilityPlan getMutabilityPlan() {
+ return mutabilityPlan;
+ }
+
+ @Override
+ public MyCustomJavaType fromString(String string) {
+ return StringHelper.isEmpty( string ) ? null : new MyCustomJavaType( string );
+ }
+
+ @Override
+ public MyCustomJavaType wrap(Object value, WrapperOptions options) {
+ if ( value == null ) {
+ return null;
+ }
+ else if ( String.class.isInstance( value ) ) {
+ return new MyCustomJavaType( (String) value );
+ }
+
+ throw new UnsupportedOperationException( "Wrapping value as MyCustomJavaType only supported for String or MyCustomJdbcType : " + value );
+ }
+
+ @Override
+ public Object unwrap(MyCustomJavaType value, Class type, WrapperOptions options) {
+ if ( String.class.isAssignableFrom( type ) ) {
+ return value.getPayload();
+ }
+
+ throw new UnsupportedOperationException( "Unwrapping MyCustomJavaType value only supported for String or MyCustomJdbcType : " + value );
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomSqlTypeDescriptor.java b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomSqlTypeDescriptor.java
new file mode 100644
index 0000000000..a9f336232d
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyCustomSqlTypeDescriptor.java
@@ -0,0 +1,83 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.test.converter.custom;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.type.descriptor.ValueBinder;
+import org.hibernate.type.descriptor.ValueExtractor;
+import org.hibernate.type.descriptor.WrapperOptions;
+import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
+import org.hibernate.type.descriptor.sql.BasicBinder;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
+import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor;
+
+/**
+ * A custom SqlTypeDescriptor. For example, this might be used to provide support
+ * for a "non-standard" SQL type or to provide some special handling of values (e.g.
+ * Oracle's dodgy handling of `""` as `null` but only in certain uses).
+ *
+ * This descriptor shows an example of replacing how VARCHAR values are handled.
+ *
+ * @author Steve Ebersole
+ */
+public class MyCustomSqlTypeDescriptor implements SqlTypeDescriptor {
+ /**
+ * Singleton access
+ */
+ public static final MyCustomSqlTypeDescriptor INSTANCE = new MyCustomSqlTypeDescriptor();
+
+ private MyCustomSqlTypeDescriptor() {
+ }
+
+ @Override
+ public int getSqlType() {
+ // given the Oracle example above we might want to replace the
+ // handling of VARCHAR
+ return Types.VARCHAR;
+ }
+
+ @Override
+ public boolean canBeRemapped() {
+ return false;
+ }
+
+ @Override
+ public ValueBinder getBinder(JavaTypeDescriptor javaTypeDescriptor) {
+ return new BasicBinder( javaTypeDescriptor, this ) {
+ @Override
+ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException {
+ final String valueStr = javaTypeDescriptor.unwrap( value, String.class, options );
+ if ( valueStr == null || valueStr.trim().isEmpty() ) {
+ st.setNull( index, getSqlType() );
+ }
+ else {
+ st.setString( index, valueStr );
+ }
+ }
+
+ @Override
+ protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) throws SQLException {
+ final String valueStr = javaTypeDescriptor.unwrap( value, String.class, options );
+ if ( valueStr == null || valueStr.trim().isEmpty() ) {
+ st.setNull( name, getSqlType() );
+ }
+ else {
+ st.setString( name, valueStr );
+ }
+ }
+ };
+ }
+
+ @Override
+ public ValueExtractor getExtractor(JavaTypeDescriptor javaTypeDescriptor) {
+ return VarcharTypeDescriptor.INSTANCE.getExtractor( javaTypeDescriptor );
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyEntity.java b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyEntity.java
new file mode 100644
index 0000000000..0fbea16fd1
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/MyEntity.java
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.test.converter.custom;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * @author Steve Ebersole
+ */
+@Entity
+@Table( name = "CUST_TYPE_CONV_ENTITY")
+public class MyEntity {
+ private Integer id;
+ private MyCustomJavaType customType;
+
+ public MyEntity() {
+ }
+
+ public MyEntity(Integer id, MyCustomJavaType customType) {
+ this.id = id;
+ this.customType = customType;
+ }
+
+ @Id
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ // NOTE : this AttributeConverter should be auto-applied here
+
+ @Basic
+ public MyCustomJavaType getCustomType() {
+ return customType;
+ }
+
+ public void setCustomType(MyCustomJavaType customType) {
+ this.customType = customType;
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/custom/package-info.java b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/package-info.java
new file mode 100644
index 0000000000..d444591b3c
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/test/converter/custom/package-info.java
@@ -0,0 +1,12 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+
+/**
+ * Test illustrating use of an AttributeConverter over custom
+ * java / sql type descriptors
+ */
+package org.hibernate.test.converter.custom;
diff --git a/hibernate-core/src/test/java/org/hibernate/test/type/Java8DateTimeTests.java b/hibernate-core/src/test/java/org/hibernate/test/type/Java8DateTimeTests.java
index d1a5428872..22391fce9c 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/type/Java8DateTimeTests.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/type/Java8DateTimeTests.java
@@ -83,7 +83,7 @@ public class Java8DateTimeTests extends BaseNonConfigCoreFunctionalTestCase {
String.format(
"%s (%s) -> %s",
propertyBinding.getName(),
- javaTypeDescriptor.getJavaTypeClass().getSimpleName(),
+ javaTypeDescriptor.getJavaType().getSimpleName(),
javaTypeDescriptor.toString( propertyBinding.getGetter( TheEntity.class ).get( theEntity ) )
)
);
diff --git a/hibernate-spatial/hibernate-spatial.gradle b/hibernate-spatial/hibernate-spatial.gradle
index 26aac5469c..78f7b0d3dd 100644
--- a/hibernate-spatial/hibernate-spatial.gradle
+++ b/hibernate-spatial/hibernate-spatial.gradle
@@ -1,3 +1,5 @@
+import org.apache.tools.ant.filters.ReplaceTokens
+
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@@ -8,13 +10,27 @@
apply from: rootProject.file( 'gradle/published-java-module.gradle' )
apply plugin: 'hibernate-matrix-testing'
+ext {
+ db = project.hasProperty('db') ? project.getProperty('db') : 'h2'
+ dbBundle = [
+ h2 : [
+ 'db.dialect' : 'org.hibernate.spatial.dialect.h2geodb.GeoDBDialect',
+ 'jdbc.driver': 'org.h2.Driver',
+ 'jdbc.user' : 'sa',
+ 'jdbc.pass' : '',
+ 'jdbc.url' : 'jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=10000',
+ ]
+ ]
+}
+
description = 'Integrate support for Spatial/GIS data into Hibernate O/RM'
dependencies {
- compile(project(':hibernate-core'))
+ compile( project(':hibernate-core') )
+ compile( libraries.geolatte )
+
+ compile( 'org.postgresql:postgresql:42.1.4' )
- compile('org.postgresql:postgresql:42.1.4')
- compile([group: 'org.geolatte', name: 'geolatte-geom', version: '1.3.0'])
compile(libraries.dom4j) {
transitive = false
}
@@ -40,3 +56,25 @@ sourceSets.test.resources {
setSrcDirs(['src/test/java', 'src/test/resources'])
}
+processTestResources {
+ doLast {
+ copy {
+ from( sourceSets.test.java.srcDirs ) {
+ include '**/*.properties'
+ include '**/*.xml'
+ }
+ into sourceSets.test.java.outputDir
+ }
+ copy {
+ from file( 'src/test/resources' )
+ into file( "${buildDir}/resources/test" )
+ exclude 'src/test/resources/arquillian.xml'
+ exclude 'src/test/resources/hibernate.properties'
+ }
+ copy {
+ from file( 'src/test/resources/hibernate.properties' )
+ into file( "${buildDir}/resources/test" )
+ filter( ReplaceTokens, tokens: dbBundle[db] )
+ }
+ }
+}
diff --git a/hibernate-spatial/src/main/java/org/hibernate/spatial/GeolatteGeometryJavaTypeDescriptor.java b/hibernate-spatial/src/main/java/org/hibernate/spatial/GeolatteGeometryJavaTypeDescriptor.java
index a45531db2c..4c817ef1b6 100644
--- a/hibernate-spatial/src/main/java/org/hibernate/spatial/GeolatteGeometryJavaTypeDescriptor.java
+++ b/hibernate-spatial/src/main/java/org/hibernate/spatial/GeolatteGeometryJavaTypeDescriptor.java
@@ -7,9 +7,12 @@
package org.hibernate.spatial;
+import java.sql.Types;
+
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
-import org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry;
+import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
+import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import org.geolatte.geom.Geometry;
import org.geolatte.geom.codec.Wkt;
@@ -35,6 +38,11 @@ public class GeolatteGeometryJavaTypeDescriptor extends AbstractTypeDescriptor implements Spatial {
+ public static final String[] REG_KEYS = {
+ Geometry.class.getCanonicalName(),
+ Point.class.getCanonicalName(),
+ Polygon.class.getCanonicalName(),
+ MultiPolygon.class.getCanonicalName(),
+ LineString.class.getCanonicalName(),
+ MultiLineString.class.getCanonicalName(),
+ MultiPoint.class.getCanonicalName(),
+ GeometryCollection.class.getCanonicalName(),
+ "geolatte_geometry"
+ };
+
/**
* Constructs an instance with the specified {@code SqlTypeDescriptor}
*
@@ -38,17 +50,7 @@ public class GeolatteGeometryType extends AbstractSingleColumnStandardBasicType<
@Override
public String[] getRegistrationKeys() {
- return new String[] {
- Geometry.class.getCanonicalName(),
- Point.class.getCanonicalName(),
- Polygon.class.getCanonicalName(),
- MultiPolygon.class.getCanonicalName(),
- LineString.class.getCanonicalName(),
- MultiLineString.class.getCanonicalName(),
- MultiPoint.class.getCanonicalName(),
- GeometryCollection.class.getCanonicalName(),
- "geolatte_geometry"
- };
+ return REG_KEYS;
}
@Override
diff --git a/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/GeometryConverter.java b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/GeometryConverter.java
new file mode 100644
index 0000000000..b1f566b6ed
--- /dev/null
+++ b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/GeometryConverter.java
@@ -0,0 +1,36 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.spatial.testing.converter;
+
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+
+import org.hibernate.spatial.dialect.h2geodb.GeoDbWkb;
+
+import org.geolatte.geom.Geometry;
+
+/**
+ * @author Steve Ebersole
+ */
+@Converter( autoApply = true )
+public class GeometryConverter implements AttributeConverter {
+ @Override
+ public byte[] convertToDatabaseColumn(Geometry attribute) {
+ if ( attribute == null ) {
+ return null;
+ }
+ return GeoDbWkb.to( attribute );
+ }
+
+ @Override
+ public Geometry convertToEntityAttribute(byte[] dbData) {
+ if ( dbData == null ) {
+ return null;
+ }
+ return GeoDbWkb.from( dbData );
+ }
+}
diff --git a/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/GeometryConverterTest.java b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/GeometryConverterTest.java
new file mode 100644
index 0000000000..8751711269
--- /dev/null
+++ b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/GeometryConverterTest.java
@@ -0,0 +1,76 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.spatial.testing.converter;
+
+import org.hibernate.boot.MetadataSources;
+import org.hibernate.boot.registry.StandardServiceRegistry;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.boot.spi.MetadataBuilderImplementor;
+import org.hibernate.cfg.AvailableSettings;
+import org.hibernate.engine.spi.SessionFactoryImplementor;
+import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.spatial.GeolatteGeometryJavaTypeDescriptor;
+import org.hibernate.spatial.dialect.h2geodb.GeoDBDialect;
+import org.hibernate.tool.schema.Action;
+import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
+import org.hibernate.type.spi.TypeConfiguration;
+
+import org.hibernate.testing.junit4.BaseUnitTestCase;
+import org.junit.Test;
+
+import org.geolatte.geom.Geometry;
+
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
+
+/**
+ * @author Steve Ebersole
+ */
+public class GeometryConverterTest extends BaseUnitTestCase {
+
+ @Test
+ public void testConverterUsage() {
+ try ( final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
+ .applySetting( AvailableSettings.DIALECT, GeoDBDialect.class )
+ .applySetting( AvailableSettings.HBM2DDL_AUTO, Action.CREATE_DROP )
+ .build() ) {
+ final MetadataSources metadataSources = new MetadataSources( ssr )
+ .addAnnotatedClass( GeometryConverter.class )
+ .addAnnotatedClass( MyEntity.class );
+ final MetadataBuilderImplementor metadataBuilder = (MetadataBuilderImplementor) metadataSources.getMetadataBuilder();
+
+ try ( final SessionFactoryImplementor sessionFactory =
+ (SessionFactoryImplementor) metadataBuilder.build().buildSessionFactory() ) {
+
+ final TypeConfiguration typeConfiguration = sessionFactory.getMetamodel().getTypeConfiguration();
+
+ assertThat(
+ typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( Geometry.class ),
+ sameInstance( GeolatteGeometryJavaTypeDescriptor.INSTANCE )
+ );
+
+ // todo (5.3) : what to assert wrt to SqlTypeDescriptor? Anything?
+
+ final EntityPersister entityPersister = sessionFactory.getMetamodel().entityPersister( MyEntity.class );
+ final AttributeConverterTypeAdapter geometryAttributeType = assertTyping(
+ AttributeConverterTypeAdapter.class,
+ entityPersister.getPropertyType( "geometry" )
+ );
+
+ final JpaAttributeConverter converter = assertTyping(
+ JpaAttributeConverter.class,
+ geometryAttributeType.getAttributeConverter()
+ );
+
+ assert GeometryConverter.class.equals( converter.getConverterBean().getBeanClass() );
+ }
+ }
+ }
+
+}
diff --git a/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/MyEntity.java b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/MyEntity.java
new file mode 100644
index 0000000000..2fbb213890
--- /dev/null
+++ b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/MyEntity.java
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+package org.hibernate.spatial.testing.converter;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.geolatte.geom.Geometry;
+
+/**
+ * @author Steve Ebersole
+ */
+@Entity
+@Table( name = "SP_CUST_TYPE_CONV_ENTITY")
+public class MyEntity {
+ private Integer id;
+ private Geometry geometry;
+
+ public MyEntity() {
+ }
+
+ public MyEntity(Integer id, Geometry geometry) {
+ this.id = id;
+ this.geometry = geometry;
+ }
+
+ @Id
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ // NOTE : the AttributeConverter should be auto-applied here
+
+ @Basic
+ public Geometry getGeometry() {
+ return geometry;
+ }
+
+ public void setGeometry(Geometry geometry) {
+ this.geometry = geometry;
+ }
+}
diff --git a/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/package-info.java b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/package-info.java
new file mode 100644
index 0000000000..9f03a58fe0
--- /dev/null
+++ b/hibernate-spatial/src/test/java/org/hibernate/spatial/testing/converter/package-info.java
@@ -0,0 +1,12 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * License: GNU Lesser General Public License (LGPL), version 2.1 or later
+ * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
+ */
+
+/**
+ * Make sure that JPA {@link javax.persistence.AttributeConverter}
+ * implementations using Geolatte types work with hibernate-spatial
+ */
+package org.hibernate.spatial.testing.converter;