Fix some issues in the legacy type resolution documentation and raw types issues for UserType

This commit is contained in:
Christian Beikov 2022-03-30 11:23:27 +02:00
parent 29d457b16a
commit 111fe26ccc
11 changed files with 276 additions and 142 deletions

View File

@ -22,93 +22,85 @@ in <<basic-custom-type>>.
[[basic-legacy-provided]]
=== Hibernate-provided BasicTypes
=== Hibernate-provided BasicTypeReferences
.Standard BasicTypes
.StandardBasicTypes
[cols="<.^,<.^,<.^,<.^",options="header",]
|=======================================================================================================================================================================================================================================================================================
|Hibernate type (org.hibernate.type package) |JDBC type |Java type |BasicTypeRegistry key(s)
|StringType |VARCHAR |java.lang.String |string, java.lang.String
|MaterializedClob |CLOB |java.lang.String |materialized_clob
|TextType |LONGVARCHAR |java.lang.String |text
|CharacterType |CHAR |char, java.lang.Character |character, char, java.lang.Character
|BooleanType |BOOLEAN |boolean, java.lang.Boolean |boolean, java.lang.Boolean
|NumericBooleanType |INTEGER, 0 is false, 1 is true |boolean, java.lang.Boolean |numeric_boolean
|YesNoType |CHAR, 'N'/'n' is false, 'Y'/'y' is true. The uppercase value is written to the database. |boolean, java.lang.Boolean |yes_no
|TrueFalseType |CHAR, 'F'/'f' is false, 'T'/'t' is true. The uppercase value is written to the database. |boolean, java.lang.Boolean |true_false
|ByteType |TINYINT |byte, java.lang.Byte |byte, java.lang.Byte
|ShortType |SMALLINT |short, java.lang.Short |short, java.lang.Short
|IntegerType |INTEGER |int, java.lang.Integer |integer, int, java.lang.Integer
|LongType |BIGINT |long, java.lang.Long |long, java.lang.Long
|FloatType |FLOAT |float, java.lang.Float |float, java.lang.Float
|DoubleType |DOUBLE |double, java.lang.Double |double, java.lang.Double
|BigIntegerType |NUMERIC |java.math.BigInteger |big_integer, java.math.BigInteger
|BigDecimalType |NUMERIC |java.math.BigDecimal |big_decimal, java.math.bigDecimal
|TimestampType |TIMESTAMP |java.util.Date |timestamp, java.sql.Timestamp, java.util.Date
|DbTimestampType |TIMESTAMP |java.util.Date |dbtimestamp
|TimeType |TIME |java.util.Date |time, java.sql.Time
|DateType |DATE |java.util.Date |date, java.sql.Date
|CalendarType |TIMESTAMP |java.util.Calendar |calendar, java.util.Calendar, java.util.GregorianCalendar
|CalendarDateType |DATE |java.util.Calendar |calendar_date
|CalendarTimeType |TIME |java.util.Calendar |calendar_time
|CurrencyType |VARCHAR |java.util.Currency |currency, java.util.Currency
|LocaleType |VARCHAR |java.util.Locale |locale, java.util.Locale
|TimeZoneType |VARCHAR, using the TimeZone ID |java.util.TimeZone |timezone, java.util.TimeZone
|UrlType |VARCHAR |java.net.URL |url, java.net.URL
|ClassType |VARCHAR (class FQN) |java.lang.Class |class, java.lang.Class
|BlobType |BLOB |java.sql.Blob |blob, java.sql.Blob
|ClobType |CLOB |java.sql.Clob |clob, java.sql.Clob
|BinaryType |VARBINARY |byte[] |binary, byte[]
|MaterializedBlobType |BLOB |byte[] |materialized_blob
|ImageType |LONGVARBINARY |byte[] |image
|WrapperBinaryType |VARBINARY |java.lang.Byte[] |wrapper-binary, Byte[], java.lang.Byte[]
|CharArrayType |VARCHAR |char[] |characters, char[]
|CharacterArrayType |VARCHAR |java.lang.Character[] |wrapper-characters, Character[], java.lang.Character[]
|UUIDBinaryType |BINARY |java.util.UUID |uuid-binary, java.util.UUID
|UUIDCharType |CHAR, can also read VARCHAR |java.util.UUID |uuid-char
|PostgresUUIDType |PostgreSQL UUID, through Types#OTHER, which complies to the PostgreSQL JDBC driver definition |java.util.UUID |pg-uuid
|SerializableType |VARBINARY |implementors of java.lang.Serializable |Unlike the other value types, multiple instances of this type are registered. It is registered once under java.io.Serializable, and registered under the specific java.io.Serializable implementation class names.
|StringNVarcharType |NVARCHAR |java.lang.String |nstring
|NTextType |LONGNVARCHAR |java.lang.String |ntext
|NClobType |NCLOB |java.sql.NClob |nclob, java.sql.NClob
|MaterializedNClobType |NCLOB |java.lang.String |materialized_nclob
|PrimitiveCharacterArrayNClobType |NCHAR |char[] |N/A
|CharacterNCharType |NCHAR |java.lang.Character |ncharacter
|CharacterArrayNClobType |NCLOB |java.lang.Character[] |N/A
|RowVersionType |VARBINARY |byte[] |row_version
|ObjectType |VARCHAR |implementors of java.lang.Serializable | object, java.lang.Object
|StandardBasicTypes constant |JDBC type |Java type |BasicTypeRegistry key(s)
|STRING |VARCHAR |java.lang.String |string, java.lang.String
|MATERIALIZED_CLOB |CLOB |java.lang.String |materialized_clob
|MATERIALIZED_CLOB_CHAR_ARRAY |CHAR |char[] |materialized_clob_char_array
|MATERIALIZED_CLOB_CHARACTER_ARRAY |CLOB |java.lang.Character[] |materialized_clob_character_array
|TEXT |LONGVARCHAR |java.lang.String |text
|CHARACTER |CHAR |char, java.lang.Character |character, char, java.lang.Character
|BOOLEAN |BOOLEAN |boolean, java.lang.Boolean |boolean, java.lang.Boolean
|NUMERIC_BOOLEAN |TINYINT, 0 is false, 1 is true |boolean, java.lang.Boolean |numeric_boolean
|YES_NO |CHAR, 'N'/'n' is false, 'Y'/'y' is true. The uppercase value is written to the database. |boolean, java.lang.Boolean |yes_no
|TRUE_FALSE |CHAR, 'F'/'f' is false, 'T'/'t' is true. The uppercase value is written to the database. |boolean, java.lang.Boolean |true_false
|BYTE |TINYINT |byte, java.lang.Byte |byte, java.lang.Byte
|SHORT |SMALLINT |short, java.lang.Short |short, java.lang.Short
|INTEGER |INTEGER |int, java.lang.Integer |integer, int, java.lang.Integer
|LONG |BIGINT |long, java.lang.Long |long, java.lang.Long
|FLOAT |FLOAT |float, java.lang.Float |float, java.lang.Float
|DOUBLE |DOUBLE |double, java.lang.Double |double, java.lang.Double
|BIG_INTEGER |NUMERIC |java.math.BigInteger |big_integer, java.math.BigInteger
|BIG_DECIMAL |NUMERIC |java.math.BigDecimal |big_decimal, java.math.bigDecimal
|TIMESTAMP |TIMESTAMP |java.util.Date |timestamp, java.sql.Timestamp, java.util.Date
//|DbTimestampType |TIMESTAMP |java.util.Date |dbtimestamp
|TIME |TIME |java.util.Date |time, java.sql.Time
|DATE |DATE |java.util.Date |date, java.sql.Date
|CALENDAR |TIMESTAMP |java.util.Calendar |calendar, java.util.Calendar, java.util.GregorianCalendar
|CALENDAR_DATE |DATE |java.util.Calendar |calendar_date
|CALENDAR_TIME |TIME |java.util.Calendar |calendar_time
|CURRENCY |VARCHAR |java.util.Currency |currency, java.util.Currency
|LOCALE |VARCHAR |java.util.Locale |locale, java.util.Locale
|TIMEZONE |VARCHAR, using the TimeZone ID |java.util.TimeZone |timezone, java.util.TimeZone
|URL |VARCHAR |java.net.URL |url, java.net.URL
|CLASS |VARCHAR (class FQN) |java.lang.Class |class, java.lang.Class
|BLOB |BLOB |java.sql.Blob |blob, java.sql.Blob
|CLOB |CLOB |java.sql.Clob |clob, java.sql.Clob
|BINARY |VARBINARY |byte[] |binary, byte[]
|MATERIALIZED_BLOB |BLOB |byte[] |materialized_blob
|IMAGE |LONGVARBINARY |byte[] |image
|BINARY_WRAPPER |VARBINARY |java.lang.Byte[] |binary_wrapper, wrapper-binary, Byte[], java.lang.Byte[]
|MATERIALIZED_BLOB_WRAPPER |BLOB |java.lang.Byte[] |materialized_blob_wrapper
|CHAR_ARRAY |VARCHAR |char[] |characters, char[]
|CHARACTER_ARRAY |VARCHAR |java.lang.Character[] |wrapper-characters, Character[], java.lang.Character[]
|UUID |UUID or BINARY |java.util.UUID |uuid, java.util.UUID, pg-uuid
|UUID_BINARY |BINARY |java.util.UUID |uuid-binary, java.util.UUID
|UUID_CHAR |CHAR, can also read VARCHAR |java.util.UUID |uuid-char
|SERIALIZABLE |VARBINARY |implementors of java.lang.Serializable |Unlike the other value types, multiple instances of this type are registered. It is registered once under java.io.Serializable, and registered under the specific java.io.Serializable implementation class names.
|NSTRING |NVARCHAR |java.lang.String |nstring
|NTEXT |LONGNVARCHAR |java.lang.String |ntext
|NCLOB |NCLOB |java.sql.NClob |nclob, java.sql.NClob
|MATERIALIZED_NCLOB |NCLOB |java.lang.String |materialized_nclob
|MATERIALIZED_NCLOB_CHAR_ARRAY |NCHAR |char[] |materialized_nclob_char_array
|CHARACTER_NCHAR |NCHAR |java.lang.Character |ncharacter
|MATERIALIZED_NCLOB_CHARACTER_ARRAY |NCLOB |java.lang.Character[] |materialized_nclob_character_array
|ROW_VERSION |VARBINARY |byte[] |row_version
|OBJECT_TYPE |VARCHAR |implementors of java.lang.Serializable | object, java.lang.Object
|=======================================================================================================================================================================================================================================================================================
.Java 8 BasicTypes
.Java 8 StandardBasicTypes
[cols="<.^,<.^,<.^,<.^",options="header",]
|=================================================================================================
|Hibernate type (org.hibernate.type package) |JDBC type |Java type |BasicTypeRegistry key(s)
|DurationType |BIGINT |java.time.Duration |Duration, java.time.Duration
|InstantType |TIMESTAMP |java.time.Instant |Instant, java.time.Instant
|LocalDateTimeType |TIMESTAMP |java.time.LocalDateTime |LocalDateTime, java.time.LocalDateTime
|LocalDateType |DATE |java.time.LocalDate |LocalDate, java.time.LocalDate
|LocalTimeType |TIME |java.time.LocalTime |LocalTime, java.time.LocalTime
|OffsetDateTimeType |TIMESTAMP |java.time.OffsetDateTime |OffsetDateTime, java.time.OffsetDateTime
|OffsetTimeType |TIME |java.time.OffsetTime |OffsetTime, java.time.OffsetTime
|ZonedDateTimeType |TIMESTAMP |java.time.ZonedDateTime |ZonedDateTime, java.time.ZonedDateTime
|DURATION |INTERVAL_SECOND |java.time.Duration |Duration, java.time.Duration
|INSTANT |TIMESTAMP_UTC |java.time.Instant |Instant, java.time.Instant
|LOCAL_DATE_TIME |TIMESTAMP |java.time.LocalDateTime |LocalDateTime, java.time.LocalDateTime
|LOCAL_DATE |DATE |java.time.LocalDate |LocalDate, java.time.LocalDate
|LOCAL_TIME |TIME |java.time.LocalTime |LocalTime, java.time.LocalTime
|OFFSET_DATE_TIME |TIMESTAMP_WITH_TIMEZONE |java.time.OffsetDateTime |OffsetDateTime, java.time.OffsetDateTime
|OFFSET_DATE_TIME_WITH_TIMEZONE |TIMESTAMP_WITH_TIMEZONE |java.time.OffsetDateTime |OffsetDateTime, java.time.OffsetDateTime
|OFFSET_DATE_TIME_WITHOUT_TIMEZONE |TIMESTAMP |java.time.OffsetDateTime |OffsetDateTime, java.time.OffsetDateTime
|OFFSET_TIME |TIME |java.time.OffsetTime |OffsetTime, java.time.OffsetTime
|ZONED_DATE_TIME |TIMESTAMP_WITH_TIMEZONE |java.time.ZonedDateTime |ZonedDateTime, java.time.ZonedDateTime
|ZONED_DATE_TIME_WITH_TIMEZONE |TIMESTAMP_WITH_TIMEZONE |java.time.ZonedDateTime |ZonedDateTimeWithTimezone
|ZONED_DATE_TIME_WITHOUT_TIMEZONE |TIMESTAMP |java.time.ZonedDateTime |ZonedDateTimeWithoutTimezone
|ZONE_OFFSET |VARCHAR |java.time.ZoneOffset |ZoneOffset, java.time.ZoneOffset
|=================================================================================================
.Hibernate Spatial BasicTypes
[cols="<.^,<.^,<.^,<.^",options="header",]
|=================================================================================================
|Hibernate type (org.hibernate.spatial package) |JDBC type |Java type |BasicTypeRegistry key(s)
|JTSGeometryType |depends on the dialect | org.locationtech.jts.geom.Geometry |jts_geometry, and the class names of Geometry and its subclasses
|GeolatteGeometryType |depends on the dialect | org.geolatte.geom.Geometry |geolatte_geometry, and the class names of Geometry and its subclasses
|=================================================================================================
[NOTE]
====
To use the Hibernate Spatial types, you must add the `hibernate-spatial` dependency to your classpath _and_ use an `org.hibernate.spatial.SpatialDialect` implementation.
See the <<chapters/query/spatial/Spatial.adoc#spatial,Spatial>> chapter for more details.
====
[[basic-legacy-registry]]
=== BasicTypeRegistry
@ -165,11 +157,11 @@ This is just for illustration purposes; for better ways to indicate nationalized
Additionally, the description is to be handled as a LOB. Again, for better ways to indicate LOBs see <<basic-lob>> section.
The `org.hibernate.annotations.Type#type` attribute can name any of the following:
The `org.hibernate.annotations.Type#value` attribute can refers to a `org.hibernate.type.UserType` class
which can be configured further by specifying `org.hibernate.annotations.Type#parameters`.
* Fully qualified name of any `org.hibernate.type.Type` implementation
* Any key registered with `BasicTypeRegistry`
* The name of any known _type definitions_
The special user type `org.hibernate.usertype.UserTypeLegacyBridge` provides a way to bridge the gap between the named
type use before Hibernate 6.0 and the new strongly typed nature of `org.hibernate.annotations.Type`.
[[basic-custom-type]]
=== Custom BasicTypes
@ -205,16 +197,16 @@ include::{sourcedir}/basic/bitset/BitSetType.java[tags=basic-custom-type-BitSetT
----
====
The `AbstractSingleColumnStandardBasicType` requires an `jdbcType` and a `javaTypeDescriptor`.
The `jdbcType` is `VarcharTypeDescriptor.INSTANCE` because the database column is a VARCHAR.
The `AbstractSingleColumnStandardBasicType` requires an `jdbcType` and a `javaType`.
The `jdbcType` is `VarcharJdbcType.INSTANCE` because the database column is a VARCHAR.
On the Java side, we need to use a `BitSetJavaType` instance which can be implemented like this:
[[basic-custom-type-BitSetTypeDescriptor-example]]
.Custom `AbstractTypeDescriptor` implementation
[[basic-custom-type-BitSetJavaType-example]]
.Custom `JavaType` implementation
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/bitset/BitSetTypeDescriptor.java[tags=basic-custom-type-BitSetTypeDescriptor-example]
include::{sourcedir}/basic/bitset/BitSetJavaType.java[tags=basic-bitset-example-java-type]
----
====
@ -249,17 +241,6 @@ include::{sourcedir}/basic/bitset/BitSetTypeTest.java[tags=basic-custom-type-Bit
----
====
Alternatively, you can use the `@TypeDef` and skip the registration phase:
[[basic-custom-type-BitSetTypeDef-mapping-example]]
.Using `@TypeDef` to register a custom Type
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/bitset/BitSetTypeDefTest.java[tags=basic-custom-type-BitSetTypeDef-mapping-example]
----
====
To validate this new `BasicType` implementation, we can test it as follows:
[[basic-custom-type-BitSetType-persistence-example]]
@ -294,7 +275,7 @@ The second approach is to implement the `UserType` interface.
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/BitSetUserType.java[tags=basic-custom-type-BitSetUserType-example]
include::{sourcedir}/basic/bitset/BitSetUserType.java[tags=basic-custom-type-BitSetUserType-example]
----
====
@ -305,7 +286,7 @@ The entity mapping looks as follows:
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/BitSetUserTypeTest.java[tags=basic-custom-type-BitSetUserType-mapping-example]
include::{sourcedir}/basic/bitset/BitSetUserTypeTest.java[tags=basic-custom-type-BitSetUserType-mapping-example]
----
====
@ -316,7 +297,7 @@ In this example, the `UserType` is registered under the `bitset` name, and this
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/BitSetUserTypeTest.java[tags=basic-custom-type-register-UserType-example]
include::{sourcedir}/basic/bitset/BitSetUserTypeTest.java[tags=basic-custom-type-register-UserType-example]
----
or using the `MetadataBuilder`
@ -327,18 +308,6 @@ include::{sourcedir}/../bootstrap/BootstrapTest.java[tags=basic-custom-type-regi
----
====
[NOTE]
====
Like `BasicType`, you can also register the `UserType` using a simple name.
Without registering a name, the `UserType` mapping requires the fully qualified class name:
[source, JAVA, indent=0]
----
@Type( type = "org.hibernate.userguide.mapping.basic.bitset.BitSetUserType" )
----
====
When running the previous test case against the `BitSetUserType` entity mapping, Hibernate executed the following SQL statements:
[[basic-custom-type-BitSetUserType-persistence-sql-example]]

View File

@ -43,6 +43,7 @@ import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
import org.hibernate.jpa.boot.internal.PersistenceUnitInfoDescriptor;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.hibernate.userguide.mapping.basic.bitset.BitSetType;
import org.hibernate.userguide.mapping.basic.bitset.BitSetUserType;
import org.junit.Test;
@ -557,6 +558,25 @@ public class BootstrapTest {
}
//end::bootstrap-native-PersistenceUnitInfoImpl-example[]
@Test
public void test_basic_custom_type_register_BasicType_example() {
try {
//tag::basic-custom-type-register-BasicType-example[]
ServiceRegistry standardRegistry =
new StandardServiceRegistryBuilder().build();
MetadataSources sources = new MetadataSources( standardRegistry );
MetadataBuilder metadataBuilder = sources.getMetadataBuilder();
metadataBuilder.applyBasicType( BitSetType.INSTANCE );
//end::basic-custom-type-register-BasicType-example[]
}
catch (Exception ignore) {
}
}
@Test
public void test_basic_custom_type_register_UserType_example() {
try {

View File

@ -0,0 +1,27 @@
package org.hibernate.userguide.mapping.basic.bitset;
import java.util.BitSet;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
/**
* @author Vlad Mihalcea
*/
//tag::basic-custom-type-BitSetType-example[]
public class BitSetType
extends AbstractSingleColumnStandardBasicType<BitSet> {
public static final BitSetType INSTANCE = new BitSetType();
public BitSetType() {
super( VarcharJdbcType.INSTANCE, BitSetJavaType.INSTANCE );
}
@Override
public String getName() {
return "bitset";
}
}
//end::basic-custom-type-BitSetType-example[]

View File

@ -0,0 +1,100 @@
/*
* 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.userguide.mapping.basic.bitset;
import java.util.BitSet;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.cfg.Configuration;
import org.hibernate.usertype.UserTypeLegacyBridge;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
/**
* @author Vlad Mihalcea
*/
public class BitSetTypeTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Product.class
};
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
//tag::basic-custom-type-register-BasicType-example[]
configuration.registerTypeContributor( (typeContributions, serviceRegistry) -> {
typeContributions.contributeType( BitSetType.INSTANCE );
} );
//end::basic-custom-type-register-BasicType-example[]
}
@Test
public void test() {
//tag::basic-custom-type-BitSetType-persistence-example[]
BitSet bitSet = BitSet.valueOf( new long[] {1, 2, 3} );
doInHibernate( this::sessionFactory, session -> {
Product product = new Product( );
product.setId( 1 );
product.setBitSet( bitSet );
session.persist( product );
} );
doInHibernate( this::sessionFactory, session -> {
Product product = session.get( Product.class, 1 );
assertEquals(bitSet, product.getBitSet());
} );
//end::basic-custom-type-BitSetType-persistence-example[]
}
//tag::basic-custom-type-BitSetType-mapping-example[]
@Entity(name = "Product")
public static class Product {
@Id
private Integer id;
@Type(
value = UserTypeLegacyBridge.class,
parameters = @Parameter(name = UserTypeLegacyBridge.TYPE_NAME_PARAM_KEY, value = "bitset")
)
private BitSet bitSet;
public Integer getId() {
return id;
}
//Getters and setters are omitted for brevity
//end::basic-custom-type-BitSetType-mapping-example[]
public void setId(Integer id) {
this.id = id;
}
public BitSet getBitSet() {
return bitSet;
}
public void setBitSet(BitSet bitSet) {
this.bitSet = bitSet;
}
//tag::basic-custom-type-BitSetType-mapping-example[]
}
//end::basic-custom-type-BitSetType-mapping-example[]
}

View File

@ -9,6 +9,7 @@ package org.hibernate.userguide.mapping.basic.bitset;
import java.util.BitSet;
import org.hibernate.annotations.Type;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
@ -36,6 +37,19 @@ public class BitSetUserTypeTest extends BaseCoreFunctionalTestCase {
};
}
// Note that the following is just for legacy documentation purposes
/*
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
//tag::basic-custom-type-register-UserType-example[]
configuration.registerTypeContributor( (typeContributions, serviceRegistry) -> {
typeContributions.contributeType( BitSetUserType.INSTANCE, "bitset");
} );
//end::basic-custom-type-register-UserType-example[]
}
*/
@Test
public void test() {

View File

@ -16,9 +16,9 @@ import org.hibernate.usertype.UserType;
* @author Steve Ebersole
*/
public class UserTypeMutabilityPlanAdapter<T> implements MutabilityPlan<T> {
private final UserType userType;
private final UserType<T> userType;
public UserTypeMutabilityPlanAdapter(UserType userType) {
public UserTypeMutabilityPlanAdapter(UserType<T> userType) {
this.userType = userType;
}
@ -28,9 +28,8 @@ public class UserTypeMutabilityPlanAdapter<T> implements MutabilityPlan<T> {
}
@Override
@SuppressWarnings("unchecked")
public T deepCopy(T value) {
return (T) userType.deepCopy( value );
return userType.deepCopy( value );
}
@Override
@ -39,8 +38,7 @@ public class UserTypeMutabilityPlanAdapter<T> implements MutabilityPlan<T> {
}
@Override
@SuppressWarnings("unchecked")
public T assemble(Serializable cached, SharedSessionContract session) {
return (T) userType.assemble( cached, null );
return userType.assemble( cached, null );
}
}

View File

@ -38,7 +38,7 @@ public class UserTypeResolution implements BasicValue.Resolution {
this.combinedTypeParameters = combinedTypeParameters;
this.mutabilityPlan = explicitMutabilityPlan != null
? explicitMutabilityPlan
: new UserTypeMutabilityPlanAdapter( userTypeAdapter.getUserType() );
: new UserTypeMutabilityPlanAdapter<>( userTypeAdapter.getUserType() );
}
@Override

View File

@ -149,19 +149,19 @@ public abstract class AbstractDelegatingMetadataBuilderImplementor<T extends Met
}
@Override
public MetadataBuilder applyBasicType(BasicType type) {
public MetadataBuilder applyBasicType(BasicType<?> type) {
delegate.applyBasicType( type );
return getThis();
}
@Override
public MetadataBuilder applyBasicType(BasicType type, String... keys) {
public MetadataBuilder applyBasicType(BasicType<?> type, String... keys) {
delegate.applyBasicType( type, keys );
return getThis();
}
@Override
public MetadataBuilder applyBasicType(UserType type, String... keys) {
public MetadataBuilder applyBasicType(UserType<?> type, String... keys) {
delegate.applyBasicType( type, keys );
return getThis();
}

View File

@ -363,7 +363,7 @@ public class Configuration {
void registerType(MetadataBuilder metadataBuilder);
}
public Configuration registerTypeOverride(UserType type, String[] keys) {
public Configuration registerTypeOverride(UserType<?> type, String[] keys) {
if ( userTypeRegistrations == null ) {
userTypeRegistrations = new ArrayList<>();
}

View File

@ -322,7 +322,7 @@ public class BasicValueBinder implements JdbcTypeIndicators {
applyJpaConverter( modelXProperty, converterDescriptor );
final Class<? extends UserType> userTypeImpl = kind.mappingAccess.customType( modelXProperty );
final Class<? extends UserType<?>> userTypeImpl = kind.mappingAccess.customType( modelXProperty );
if ( userTypeImpl != null ) {
applyExplicitType( userTypeImpl, kind.mappingAccess.customTypeParameters( modelXProperty ) );
@ -366,9 +366,8 @@ public class BasicValueBinder implements JdbcTypeIndicators {
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void applyExplicitType(Class<? extends UserType> impl, Parameter[] params) {
this.explicitCustomType = (Class) impl;
private void applyExplicitType(Class<? extends UserType<?>> impl, Parameter[] params) {
this.explicitCustomType = impl;
this.explicitLocalTypeParams = extractTypeParams( params );
}
@ -467,7 +466,7 @@ public class BasicValueBinder implements JdbcTypeIndicators {
}
}
final Class<? extends UserType> customTypeImpl = Kind.ATTRIBUTE.mappingAccess.customType( modelXProperty );
final Class<? extends UserType<?>> customTypeImpl = Kind.ATTRIBUTE.mappingAccess.customType( modelXProperty );
if ( customTypeImpl.isAnnotationPresent( Immutable.class ) ) {
return ImmutableMutabilityPlan.instance();
}
@ -582,7 +581,7 @@ public class BasicValueBinder implements JdbcTypeIndicators {
}
}
final Class<? extends UserType> customTypeImpl = Kind.MAP_KEY.mappingAccess.customType( mapAttribute );
final Class<? extends UserType<?>> customTypeImpl = Kind.MAP_KEY.mappingAccess.customType( mapAttribute );
if ( customTypeImpl != null ) {
if ( customTypeImpl.isAnnotationPresent( Immutable.class ) ) {
return ImmutableMutabilityPlan.instance();
@ -912,7 +911,7 @@ public class BasicValueBinder implements JdbcTypeIndicators {
}
}
final Class<? extends UserType> customTypeImpl = Kind.ATTRIBUTE.mappingAccess.customType( attributeXProperty );
final Class<? extends UserType<?>> customTypeImpl = Kind.ATTRIBUTE.mappingAccess.customType( attributeXProperty );
if ( customTypeImpl != null ) {
if ( customTypeImpl.isAnnotationPresent( Immutable.class ) ) {
return ImmutableMutabilityPlan.instance();
@ -1288,7 +1287,7 @@ public class BasicValueBinder implements JdbcTypeIndicators {
* Access to detail of basic value mappings based on {@link Kind}
*/
private interface BasicMappingAccess {
Class<? extends UserType> customType(XProperty xProperty);
Class<? extends UserType<?>> customType(XProperty xProperty);
Parameter[] customTypeParameters(XProperty xProperty);
}

View File

@ -539,13 +539,20 @@ public final class StandardBasicTypes {
/**
* The standard Hibernate type for mapping {@link Byte Byte[]} to JDBC {@link org.hibernate.type.SqlTypes#VARBINARY VARBINARY}.
*/
public static final BasicTypeReference<Byte[]> WRAPPER_BINARY = new BasicTypeReference<>(
//TODO find a decent name before documenting
"wrapper-binary",
public static final BasicTypeReference<Byte[]> BINARY_WRAPPER = new BasicTypeReference<>(
"binary_wrapper",
Byte[].class,
SqlTypes.VARBINARY
);
/**
* The standard Hibernate type for mapping {@link Byte Byte[]} to JDBC {@link org.hibernate.type.SqlTypes#VARBINARY VARBINARY}.
*
* @deprecated use {@link #BINARY_WRAPPER} instead
*/
@Deprecated(forRemoval = true)
public static final BasicTypeReference<Byte[]> WRAPPER_BINARY = BINARY_WRAPPER;
/**
* The standard Hibernate type for mapping {@code byte[]} to JDBC {@link org.hibernate.type.SqlTypes#LONGVARBINARY LONGVARBINARY}.
*
@ -586,8 +593,8 @@ public final class StandardBasicTypes {
* @see #MATERIALIZED_BLOB
* @see #IMAGE
*/
public static final BasicTypeReference<Byte[]> WRAPPED_MATERIALIZED_BLOB = new BasicTypeReference<>(
"wrapped_materialized_blob",
public static final BasicTypeReference<Byte[]> MATERIALIZED_BLOB_WRAPPER = new BasicTypeReference<>(
"materialized_blob_wrapper",
Byte[].class,
SqlTypes.BLOB
);
@ -767,10 +774,10 @@ public final class StandardBasicTypes {
);
handle(
WRAPPER_BINARY,
BINARY_WRAPPER,
"org.hibernate.type.WrapperBinaryType",
basicTypeRegistry,
"wrapper-binary", "Byte[]", Byte[].class.getName()
"binary_wrapper", "wrapper-binary", "Byte[]", Byte[].class.getName()
);
handle(
@ -796,10 +803,10 @@ public final class StandardBasicTypes {
);
handle(
WRAPPED_MATERIALIZED_BLOB,
"org.hibernate.type.MaterializedBlobType",
MATERIALIZED_BLOB_WRAPPER,
"org.hibernate.type.WrappedMaterializedBlobType",
basicTypeRegistry,
"wrapped_materialized_blob"
"materialized_blob_wrapper"
);
@ -1109,7 +1116,7 @@ public final class StandardBasicTypes {
UUID,
"org.hibernate.type.PostgresUUIDType",
basicTypeRegistry,
"uuid", UUID.class.getName()
"uuid", UUID.class.getName(), "pg-uuid"
);
handle(