Fix some issues in the legacy type resolution documentation and raw types issues for UserType
This commit is contained in:
parent
29d457b16a
commit
111fe26ccc
|
@ -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]]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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[]
|
|
@ -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[]
|
||||
}
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<>();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue