HHH-14589 - Make sure documentation examples regarding basic-types work and update the section
- re-enable the basic-type tests in the `documentation` module - fix basic-type resolution in various cases from tests in both `hibernate-core` and `documentation` - updated the basic_types.adoc user-guide section + moved much of the "legacy" discussion to an appendix - fixed missing impls of the optional contract `org.hibernate.type.AdjustableBasicType` - improved handling of `NationalizationSupport` offered by a Dialect NOTE : - changes to `ColumnTransformerTest` are related to "composite basics" not being supported, not problems with `ColumnTransformer`. - final failure in `org.hibernate.userguide.mapping.basic` is `SubselectTest#testRefreshLifecycle` which actually fails because refresh is not working properly
This commit is contained in:
parent
987dbbba2f
commit
71515af5cc
|
@ -0,0 +1,86 @@
|
||||||
|
= Mapping foreign-keys
|
||||||
|
|
||||||
|
|
||||||
|
The relational model:
|
||||||
|
|
||||||
|
```
|
||||||
|
orders (
|
||||||
|
id (PK),
|
||||||
|
customer_fk,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
customers (
|
||||||
|
id (PK),
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
FK "customer_orders" : orders.cust_fk -> customers.id
|
||||||
|
```
|
||||||
|
|
||||||
|
So we have a foreign-key between `orders` and `customers` where:
|
||||||
|
|
||||||
|
key-side:: `orders.customer_fk`
|
||||||
|
target-side:: `customers.id`
|
||||||
|
|
||||||
|
|
||||||
|
Assuming bi-directionality, we have 2 `Association` refs:
|
||||||
|
|
||||||
|
* `Order#customer` which models the key-side of the FK,
|
||||||
|
* `Customer#orders` which models the target-side
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
There is a single ForeignKeyDescriptor instance for this FK in our metamodel, with 2 Sides:
|
||||||
|
|
||||||
|
```
|
||||||
|
ForeignKeyDescriptor (
|
||||||
|
name : "customer_orders",
|
||||||
|
keySide (
|
||||||
|
nature: KEY,
|
||||||
|
column(s) : `orders.customer_fk`,
|
||||||
|
keyModelPart : BasicType(...),
|
||||||
|
...
|
||||||
|
),
|
||||||
|
targetSide (
|
||||||
|
nature: TARGET,
|
||||||
|
column(s) : `customer.id`,
|
||||||
|
keyModelPart : BasicType(...),
|
||||||
|
...
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
So this gives us all the information we need. We just need to model that within the `Association` contract:
|
||||||
|
|
||||||
|
```
|
||||||
|
ManyToOne (
|
||||||
|
name: `Order#customer`,
|
||||||
|
foreignKeyDescriptor : FKD(customer_orders),
|
||||||
|
side : FKD(customer_orders)#keySide
|
||||||
|
)
|
||||||
|
|
||||||
|
OneToMany (
|
||||||
|
name: `Customer#orders`,
|
||||||
|
foreignKeyDescriptor : FKD(customer_orders),
|
||||||
|
side : FKD(customer_orders)#targetSide
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
When rendering one of these associations into SQL, we have all of the information we need. Let's
|
||||||
|
assume we are processing HQL like `from Order join fetch customer`. We know:
|
||||||
|
|
||||||
|
1. We be "coming from" the `Order` side, meaning the LHS will be `Order` and the RHS will be `Order#customer`
|
||||||
|
2. `Order#customer` knows that it models the Side(KEY) of the FKD(customer_orders).
|
||||||
|
|
||||||
|
Further, `Order#customer` also knows that the "other side" is, well, the other Side (here, the TARGET) modeled on the FKD.
|
||||||
|
|
||||||
|
All of this allows us to properly render join predicate.
|
||||||
|
|
||||||
|
|
||||||
|
If we come from the other side: `from Customer join fetch orders`, similar situation:
|
||||||
|
|
||||||
|
1. Here we are "coming from" the Customer side, meaning the LHS will be `Customer` and RHS is `Customer#orders`.
|
||||||
|
2. `Customer#orders` knows it is the `Side(TARGET)` of the FKD(customer_orders).
|
||||||
|
|
|
@ -82,6 +82,8 @@ else {
|
||||||
task release( dependsOn: [clean, test] )
|
task release( dependsOn: [clean, test] )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//tasks.test.include 'org/hibernate/'
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// grouping tasks - declaration, see below for task dependency definitions
|
// grouping tasks - declaration, see below for task dependency definitions
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -300,6 +302,10 @@ task renderIntegrationGuide(type: AsciidoctorTask, group: 'Documentation') {
|
||||||
|
|
||||||
// Testing
|
// Testing
|
||||||
|
|
||||||
|
test {
|
||||||
|
include '**/mapping/basic/**'
|
||||||
|
}
|
||||||
|
|
||||||
// resources inherently exclude sources
|
// resources inherently exclude sources
|
||||||
sourceSets.test.resources {
|
sourceSets.test.resources {
|
||||||
setSrcDirs( ['src/test/java','src/test/resources'] )
|
setSrcDirs( ['src/test/java','src/test/resources'] )
|
||||||
|
|
|
@ -4,3 +4,4 @@
|
||||||
- [[[PoEAA]]] Martin Fowler. https://www.martinfowler.com/books/eaa.html[Patterns of Enterprise Application Architecture].
|
- [[[PoEAA]]] Martin Fowler. https://www.martinfowler.com/books/eaa.html[Patterns of Enterprise Application Architecture].
|
||||||
Addison-Wesley Publishing Company. 2003.
|
Addison-Wesley Publishing Company. 2003.
|
||||||
- [[[JPwH]]] Christian Bauer & Gavin King. https://www.manning.com/books/java-persistence-with-hibernate-second-edition[Java Persistence with Hibernate, Second Edition]. Manning Publications Co. 2015.
|
- [[[JPwH]]] Christian Bauer & Gavin King. https://www.manning.com/books/java-persistence-with-hibernate-second-edition[Java Persistence with Hibernate, Second Edition]. Manning Publications Co. 2015.
|
||||||
|
- [[[jdbc]]] https://download.oracle.com/otndocs/jcp/jdbc-4_2-mrel2-spec/[JDBC Specification - Version 4.2]
|
||||||
|
|
|
@ -37,6 +37,7 @@ include::appendices/Annotations.adoc[]
|
||||||
include::appendices/BestPractices.adoc[]
|
include::appendices/BestPractices.adoc[]
|
||||||
include::appendices/Legacy_Bootstrap.adoc[]
|
include::appendices/Legacy_Bootstrap.adoc[]
|
||||||
include::appendices/Legacy_DomainModel.adoc[]
|
include::appendices/Legacy_DomainModel.adoc[]
|
||||||
|
include::appendices/LegacyBasicTypeResolution.adoc[]
|
||||||
include::appendices/Legacy_Criteria.adoc[]
|
include::appendices/Legacy_Criteria.adoc[]
|
||||||
include::appendices/Legacy_Native_Queries.adoc[]
|
include::appendices/Legacy_Native_Queries.adoc[]
|
||||||
|
|
||||||
|
|
|
@ -595,7 +595,7 @@ See the <<chapters/domain/identifiers.adoc#identifiers-generators-table-configur
|
||||||
|
|
||||||
The {jpaJavadocUrlPrefix}Temporal.html[`@Temporal`] annotation is used to specify the `TemporalType` of the currently annotated `java.util.Date` or `java.util.Calendar` entity attribute.
|
The {jpaJavadocUrlPrefix}Temporal.html[`@Temporal`] annotation is used to specify the `TemporalType` of the currently annotated `java.util.Date` or `java.util.Calendar` entity attribute.
|
||||||
|
|
||||||
See the <<chapters/domain/basic_types.adoc#basic-datetime,Basic temporal types>> chapter for more info.
|
See the <<chapters/domain/basic_types.adoc#basic-temporal,Basic temporal types>> chapter for more info.
|
||||||
|
|
||||||
[[annotations-jpa-transient]]
|
[[annotations-jpa-transient]]
|
||||||
==== `@Transient`
|
==== `@Transient`
|
||||||
|
|
|
@ -0,0 +1,351 @@
|
||||||
|
:sourcedir: ../../../../test/java/org/hibernate/userguide/mapping
|
||||||
|
:extrasdir: extras
|
||||||
|
:originalextrasdir: ../chapters/domain/extras
|
||||||
|
|
||||||
|
[[basic-legacy]]
|
||||||
|
== Legacy BasicType resolution
|
||||||
|
|
||||||
|
Versions prior to 6.0 statically combined the `JavaTypeDescriptor`, `JdbcTypeDescriptor`, `BasicValueConverter` and
|
||||||
|
`MutabilityPlan` aspects within the `org.hibernate.type.BasicType` contract. Hibernate's legacy strategy for resolving
|
||||||
|
a basic type is based on finding the implementation of `org.hibernate.type.BasicType` to use.
|
||||||
|
|
||||||
|
This appendix will describe the legacy approach for influencing the mapping of basic types.
|
||||||
|
|
||||||
|
Generally speaking, this resolution uses an internal registry of `BasicType` implementations
|
||||||
|
registered under one-or-more "registration keys". The tables in <<basic-legacy-provided>> describe
|
||||||
|
the initial set of `BasicType` references registered by Hibernate. <<basic-legacy-registry>>
|
||||||
|
describes this `BasicTypeRegistry`.
|
||||||
|
|
||||||
|
Users can also override mappings in the `BasicTypeRegistry` or extend them to map new types, as described
|
||||||
|
in <<basic-custom-type>>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[[basic-legacy-provided]]
|
||||||
|
=== Hibernate-provided BasicTypes
|
||||||
|
|
||||||
|
.Standard BasicTypes
|
||||||
|
[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
|
||||||
|
|=======================================================================================================================================================================================================================================================================================
|
||||||
|
|
||||||
|
.Java 8 BasicTypes
|
||||||
|
[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
|
||||||
|
|=================================================================================================
|
||||||
|
|
||||||
|
.Hibernate Spatial BasicTypes
|
||||||
|
[cols="<.^,<.^,<.^,<.^",options="header",]
|
||||||
|
|=================================================================================================
|
||||||
|
|Hibernate type (org.hibernate.spatial package) |JDBC type |Java type |BasicTypeRegistry key(s)
|
||||||
|
|JTSGeometryType |depends on the dialect | com.vividsolutions.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
|
||||||
|
|
||||||
|
We said before that a Hibernate type is not a Java type, nor an SQL type, but that it understands both and performs the marshalling between them.
|
||||||
|
But looking at the basic type mappings from the previous examples,
|
||||||
|
how did Hibernate know to use its `org.hibernate.type.StringType` for mapping for `java.lang.String` attributes,
|
||||||
|
or its `org.hibernate.type.IntegerType` for mapping `java.lang.Integer` attributes?
|
||||||
|
|
||||||
|
The answer lies in a service inside Hibernate called the `org.hibernate.type.BasicTypeRegistry`, which maintains a
|
||||||
|
map of `org.hibernate.type.BasicType` instances keyed by a name.
|
||||||
|
|
||||||
|
We will see later, in the <<basic-type-annotation>> section, that we can explicitly tell Hibernate which BasicType to use for a particular attribute.
|
||||||
|
But first, let's explore how implicit resolution works and how applications can adjust the implicit resolution.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
A thorough discussion of `BasicTypeRegistry` and all the different ways to contribute types is beyond the scope of this documentation.
|
||||||
|
|
||||||
|
Please see the http://docs.jboss.org/hibernate/orm/{majorMinorVersion}/integrationguide/html_single/Hibernate_Integration_Guide.html[Integration Guide] for complete details.
|
||||||
|
====
|
||||||
|
|
||||||
|
As an example, take a String attribute such as we saw before with Product#sku.
|
||||||
|
Since there is no explicit type mapping, Hibernate looks to the `BasicTypeRegistry` to find the registered
|
||||||
|
mapping for `java.lang.String`.
|
||||||
|
|
||||||
|
As a baseline within `BasicTypeRegistry`, Hibernate follows the recommended mappings of JDBC for Java types.
|
||||||
|
JDBC recommends mapping Strings to VARCHAR, which is the exact mapping that `StringType` handles.
|
||||||
|
So that is the baseline mapping within `BasicTypeRegistry` for Strings.
|
||||||
|
|
||||||
|
Applications can also extend (add new `BasicType` registrations) or override (replace an existing `BasicType` registration) using one of the
|
||||||
|
`MetadataBuilder#applyBasicType` methods or the `MetadataBuilder#applyTypes` method during bootstrap.
|
||||||
|
For more details, see <<basic-custom-type>> section.
|
||||||
|
|
||||||
|
[[basic-type-annotation]]
|
||||||
|
=== Explicit BasicTypes
|
||||||
|
|
||||||
|
Sometimes you want a particular attribute to be handled differently.
|
||||||
|
Occasionally Hibernate will implicitly pick a `BasicType` that you do not want (and for some reason you do not want to adjust the `BasicTypeRegistry`).
|
||||||
|
|
||||||
|
In these cases, you must explicitly tell Hibernate the `BasicType` to use, via the `org.hibernate.annotations.Type` annotation.
|
||||||
|
|
||||||
|
[[basic-type-annotation-example]]
|
||||||
|
.Using `@org.hibernate.annotations.Type`
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/ExplicitTypeTest.java[tags=basic-type-annotation-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
This tells Hibernate to store the Strings as nationalized data.
|
||||||
|
This is just for illustration purposes; for better ways to indicate nationalized character data see <<basic-nationalized>> section.
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
* Fully qualified name of any `org.hibernate.type.Type` implementation
|
||||||
|
* Any key registered with `BasicTypeRegistry`
|
||||||
|
* The name of any known _type definitions_
|
||||||
|
|
||||||
|
[[basic-custom-type]]
|
||||||
|
=== Custom BasicTypes
|
||||||
|
|
||||||
|
Hibernate makes it relatively easy for developers to create their own basic type mappings type.
|
||||||
|
For example, you might want to persist properties of type `java.util.BigInteger` to `VARCHAR` columns, or support completely new types.
|
||||||
|
|
||||||
|
There are two approaches to developing a custom type:
|
||||||
|
|
||||||
|
- implementing a `BasicType` and registering it
|
||||||
|
- implementing a `UserType` which doesn't require type registration
|
||||||
|
|
||||||
|
As a means of illustrating the different approaches, let's consider a use case where we need to support a `java.util.BitSet` mapping that's stored as a VARCHAR.
|
||||||
|
|
||||||
|
[[basic-custom-type-BasicType]]
|
||||||
|
==== Implementing a `BasicType`
|
||||||
|
|
||||||
|
The first approach is to directly implement the `BasicType` interface.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
Because the `BasicType` interface has a lot of methods to implement, if the value is stored in a single database column, it's much more convenient to extend the `AbstractStandardBasicType` or the `AbstractSingleColumnStandardBasicType` Hibernate classes.
|
||||||
|
====
|
||||||
|
|
||||||
|
First, we need to extend the `AbstractSingleColumnStandardBasicType` like this:
|
||||||
|
|
||||||
|
[[basic-custom-type-BitSetType-example]]
|
||||||
|
.Custom `BasicType` implementation
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/BitSetType.java[tags=basic-custom-type-BitSetType-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
The `AbstractSingleColumnStandardBasicType` requires an `jdbcTypeDescriptor` and a `javaTypeDescriptor`.
|
||||||
|
The `jdbcTypeDescriptor` is `VarcharTypeDescriptor.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
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/BitSetTypeDescriptor.java[tags=basic-custom-type-BitSetTypeDescriptor-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
The `unwrap()` method is used when passing a `BitSet` as a `PreparedStatement` bind parameter, while the `wrap()` method is used to transform the JDBC column value object (e.g. `String` in our case) to the actual mapping object type (e.g. `BitSet` in this example).
|
||||||
|
|
||||||
|
The `BasicType` must be registered, and this can be done at bootstrapping time:
|
||||||
|
|
||||||
|
[[basic-custom-type-register-BasicType-example]]
|
||||||
|
.Register a Custom `BasicType` implementation
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/BitSetTypeTest.java[tags=basic-custom-type-register-BasicType-example]
|
||||||
|
----
|
||||||
|
|
||||||
|
or using the `MetadataBuilder`
|
||||||
|
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/../bootstrap/BootstrapTest.java[tags=basic-custom-type-register-BasicType-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
With the new `BitSetType` being registered as `bitset`, the entity mapping looks like this:
|
||||||
|
|
||||||
|
[[basic-custom-type-BitSetType-mapping-example]]
|
||||||
|
.Custom `BasicType` mapping
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/BitSetTypeTest.java[tags=basic-custom-type-BitSetType-mapping-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
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/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]]
|
||||||
|
.Persisting the custom `BasicType`
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/BitSetTypeTest.java[tags=basic-custom-type-BitSetType-persistence-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
When executing this unit test, Hibernate generates the following SQL statements:
|
||||||
|
|
||||||
|
[[basic-custom-type-BitSetType-persistence-sql-example]]
|
||||||
|
.Persisting the custom `BasicType`
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{originalextrasdir}/basic/basic-custom-type-BitSetType-persistence-sql-example.sql[]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
As you can see, the `BitSetType` takes care of the _Java-to-SQL_ and _SQL-to-Java_ type conversion.
|
||||||
|
|
||||||
|
[[basic-custom-type-UserType]]
|
||||||
|
==== Implementing a `UserType`
|
||||||
|
|
||||||
|
The second approach is to implement the `UserType` interface.
|
||||||
|
|
||||||
|
[[basic-custom-type-BitSetUserType-example]]
|
||||||
|
.Custom `UserType` implementation
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/BitSetUserType.java[tags=basic-custom-type-BitSetUserType-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
The entity mapping looks as follows:
|
||||||
|
|
||||||
|
[[basic-custom-type-BitSetUserType-mapping-example]]
|
||||||
|
.Custom `UserType` mapping
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/BitSetUserTypeTest.java[tags=basic-custom-type-BitSetUserType-mapping-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
In this example, the `UserType` is registered under the `bitset` name, and this is done like this:
|
||||||
|
|
||||||
|
[[basic-custom-type-register-UserType-example]]
|
||||||
|
.Register a Custom `UserType` implementation
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/basic/BitSetUserTypeTest.java[tags=basic-custom-type-register-UserType-example]
|
||||||
|
----
|
||||||
|
|
||||||
|
or using the `MetadataBuilder`
|
||||||
|
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{sourcedir}/../bootstrap/BootstrapTest.java[tags=basic-custom-type-register-UserType-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
[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.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]]
|
||||||
|
.Persisting the custom `BasicType`
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{originalextrasdir}/basic/basic-custom-type-BitSetUserType-persistence-sql-example.sql[]
|
||||||
|
----
|
||||||
|
====
|
|
@ -1,7 +1,7 @@
|
||||||
[[batch]]
|
[[batch]]
|
||||||
== Batching
|
== Batching
|
||||||
:sourcedir: ../../../../../test/java/org/hibernate/userguide/batch
|
:sourcedir: ../../../../../test/java/org/hibernate/userguide/batch
|
||||||
:bulkid-sourcedir: ../../../../../../../hibernate-core/src/test/java/org/hibernate/test/bulkid
|
:bulkid-sourcedir: ../../../../../../../hibernate-core/src/test_legacy/java/org/hibernate/test/bulkid
|
||||||
:extrasdir: extras
|
:extrasdir: extras
|
||||||
|
|
||||||
[[batch-jdbcbatch]]
|
[[batch-jdbcbatch]]
|
||||||
|
|
|
@ -29,4 +29,3 @@ include::natural_id.adoc[]
|
||||||
include::dynamic_model.adoc[]
|
include::dynamic_model.adoc[]
|
||||||
include::inheritance.adoc[]
|
include::inheritance.adoc[]
|
||||||
include::immutability.adoc[]
|
include::immutability.adoc[]
|
||||||
include::jdbc_mappings.adoc[]
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,66 +0,0 @@
|
||||||
[[jdbc-mapping]]
|
|
||||||
=== JDBC Mappings
|
|
||||||
|
|
||||||
Historically Hibernate's BasicType / UserType system is based on a static binding between a Java type
|
|
||||||
(`JavaTypeDescriptor`) and a SQL/JDBC type (`JdbcTypeDescriptor`). 6.0 introduces the ability to influence
|
|
||||||
the `JavaTypeDescriptor` and `JdbcTypeDescriptor` independently. Under this new approach, the resolution of a
|
|
||||||
basic value mapping comes down to:
|
|
||||||
|
|
||||||
* `JavaTypeDescriptor` to use
|
|
||||||
* `JdbcTypeDescriptor` to use
|
|
||||||
* `BasicValueConverter` to use (if one)
|
|
||||||
* `MutabilityPlan` to use
|
|
||||||
|
|
||||||
Each of these pieces can be influenced independently.
|
|
||||||
|
|
||||||
==== JavaTypeDescriptor
|
|
||||||
|
|
||||||
`@JavaType` can be used to explicitly specify the `JavaTypeDescriptor` to use for a particular mapping.
|
|
||||||
|
|
||||||
`@JavaTypeRegistration` can be used to replace the default `Class` -> `JavaTypeDescriptor` mapping as part
|
|
||||||
of the `JavaTypeDescriptorRegistry`.
|
|
||||||
|
|
||||||
`@Temporal` hints at the `JavaTypeDescriptor` to use in certain cases. E.g. `java.util.Date` can represent a
|
|
||||||
`java.sql.Date`, `java.sql.Time` or `java.sql.Timestamp` - the `TemporalType` specified by the `@Temporal`
|
|
||||||
indicates which specific `JavaTypeDescriptor` to use...
|
|
||||||
|
|
||||||
An `AttributeConverter` can also influence the `JavaTypeDescriptor` used in certain cases.
|
|
||||||
|
|
||||||
|
|
||||||
==== SqlTypeDescriptor
|
|
||||||
|
|
||||||
`@JdbcType` can be used to explicitly specify the `JdbcTypeDescriptor` to use for a particular mapping.
|
|
||||||
|
|
||||||
`@JdbcTypeCode` can be used to indicate the `JdbcTypeDescriptorRegistry` entry to use. `@JdbcTypeRegistration` can
|
|
||||||
be used to register a `JdbcTypeDescriptor` with the `JdbcTypeDescriptorRegistry`.
|
|
||||||
|
|
||||||
`@MapKeyJdbcType` and `@MapKeyJdbcTypeCode` work the same as `@JdbcType` and `@JdbcTypeCode`, respectively, except
|
|
||||||
describing the `JdbcTypeDescriptor` to use for the map's key. In which case, `@JdbcType` and `@JdbcTypeCode` refer
|
|
||||||
to the map's values.
|
|
||||||
|
|
||||||
For character and binary data, the JPA `@Lob` annotation can be used to indicate that a JDBC BLOB, CLOB, NCLOB should
|
|
||||||
be used.
|
|
||||||
|
|
||||||
For character data, `@Nationalized` can be used to indicate that the JDBC nationalized variant should be used.
|
|
||||||
E.g. `Types.CLOB` -> `Types.CLOB`, `Types.VARCHAR` -> `Types.NVARCHAR`, etc
|
|
||||||
|
|
||||||
`@Enumerated` influences the `JdbcTypeDescriptor` to use by the `EnumType` specified. `EnumType#ORDINAL` implies
|
|
||||||
that `Types.TINYINT` should be used. `EnumType#STRING` implies that `Types.VARCHAR` should be used.
|
|
||||||
|
|
||||||
`@Temporal` can also influence the `JdbcTypeDescriptor` used.
|
|
||||||
|
|
||||||
An `AttributeConverter` can also influence the `JdbcTypeDescriptor` to use by the Java type it reports for its
|
|
||||||
"relational type"
|
|
||||||
|
|
||||||
|
|
||||||
==== BasicValueConverter
|
|
||||||
|
|
||||||
At the moment, the only ways to apply a `BasicValueConverter` are by using `@Enumerated` and by applying a JPA
|
|
||||||
`AttributeConverter`.
|
|
||||||
|
|
||||||
|
|
||||||
==== MutabilityPlan
|
|
||||||
|
|
||||||
`MutabilityPlan` can be influenced by either `@Immutable` or `@Mutability`.
|
|
||||||
|
|
||||||
By default, `JavaTypeDescriptor#getMutabilityPlan` is used
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
*/
|
*/
|
||||||
package org.hibernate.userguide.flush;
|
package org.hibernate.userguide.flush;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public class AlwaysFlushTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
Session session = entityManager.unwrap( Session.class);
|
Session session = entityManager.unwrap( Session.class);
|
||||||
assertTrue(((Number) session
|
assertTrue(((Number) session
|
||||||
.createNativeQuery("select count(*) from Person")
|
.createNativeQuery("select count(*) from Person")
|
||||||
.setFlushMode( FlushMode.ALWAYS)
|
.setHibernateFlushMode( FlushMode.ALWAYS)
|
||||||
.uniqueResult()).intValue() == 1);
|
.uniqueResult()).intValue() == 1);
|
||||||
//end::flushing-always-flush-sql-example[]
|
//end::flushing-always-flush-sql-example[]
|
||||||
});
|
});
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `BigInteger` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BigDecimalMappingTests.EntityOfBigDecimals.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BigDecimalMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfBigDecimals.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BigDecimal.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BigDecimal.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.NUMERIC ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfBigDecimals( 1, BigDecimal.TEN ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfBigDecimals.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfBigDecimals" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfBigDecimals" )
|
||||||
|
@Table( name = "EntityOfBigDecimals" )
|
||||||
|
public static class EntityOfBigDecimals {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-bigdecimal-example-implicit[]
|
||||||
|
// will be mapped using NUMERIC
|
||||||
|
BigDecimal wrapper;
|
||||||
|
//end::basic-bigdecimal-example-implicit[]
|
||||||
|
|
||||||
|
public EntityOfBigDecimals() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfBigDecimals(Integer id, BigDecimal wrapper) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `BigInteger` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BigIntegerMappingTests.EntityOfBigIntegers.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BigIntegerMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfBigIntegers.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BigInteger.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BigInteger.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.NUMERIC ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfBigIntegers( 1, BigInteger.TEN ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfBigIntegers.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfBigIntegers" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfBigIntegers" )
|
||||||
|
@Table( name = "EntityOfBigIntegers" )
|
||||||
|
public static class EntityOfBigIntegers {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-biginteger-example-implicit[]
|
||||||
|
// will be mapped using NUMERIC
|
||||||
|
BigInteger wrapper;
|
||||||
|
//end::basic-biginteger-example-implicit[]
|
||||||
|
|
||||||
|
public EntityOfBigIntegers() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfBigIntegers(Integer id, BigInteger wrapper) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.Convert;
|
||||||
|
import javax.persistence.Converter;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BitSetConverterTests.Product.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BitSetConverterTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
|
||||||
|
final MappingMetamodel domainModel = sessionFactory.getDomainModel();
|
||||||
|
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( Product.class );
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "bitSet" );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getValueConverter(), instanceOf( JpaAttributeConverter.class ) );
|
||||||
|
final JpaAttributeConverter converter = (JpaAttributeConverter) attributeMapping.getValueConverter();
|
||||||
|
assertThat( converter.getConverterBean().getBeanClass(), equalTo( BitSetConverter.class ) );
|
||||||
|
|
||||||
|
assertThat(
|
||||||
|
attributeMapping.getJdbcMapping().getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
isOneOf( Types.VARCHAR, Types.NVARCHAR )
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo( String.class ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Table(name = "products")
|
||||||
|
//tag::basic-bitset-example-convert[]
|
||||||
|
@Entity(name = "Product")
|
||||||
|
public static class Product {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@Convert( converter = BitSetConverter.class )
|
||||||
|
private BitSet bitSet;
|
||||||
|
|
||||||
|
//Getters and setters are omitted for brevity
|
||||||
|
//end::basic-bitset-example-convert[]
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSet getBitSet() {
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitSet(BitSet bitSet) {
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
//tag::basic-bitset-example-convert[]
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-convert[]
|
||||||
|
|
||||||
|
|
||||||
|
//tag::basic-bitset-example-converter[]
|
||||||
|
@Converter( autoApply = true )
|
||||||
|
public static class BitSetConverter implements AttributeConverter<BitSet,String> {
|
||||||
|
@Override
|
||||||
|
public String convertToDatabaseColumn(BitSet attribute) {
|
||||||
|
return BitSetHelper.bitSetToString( attribute );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BitSet convertToEntityAttribute(String dbData) {
|
||||||
|
return BitSetHelper.stringToBitSet( dbData );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-converter[]
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class BitSetHelper {
|
||||||
|
public static final String DELIMITER = ",";
|
||||||
|
public static final byte[] BYTES = new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||||
|
|
||||||
|
public static String bitSetToString(BitSet bitSet) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for ( long token : bitSet.toLongArray() ) {
|
||||||
|
if ( builder.length() > 0 ) {
|
||||||
|
builder.append( DELIMITER );
|
||||||
|
}
|
||||||
|
builder.append( Long.toString( token, 2 ) );
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitSet stringToBitSet(String string) {
|
||||||
|
if ( string == null || string.isEmpty() ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] tokens = string.split( DELIMITER );
|
||||||
|
long[] values = new long[tokens.length];
|
||||||
|
|
||||||
|
for ( int i = 0; i < tokens.length; i++ ) {
|
||||||
|
values[i] = Long.valueOf( tokens[i], 2 );
|
||||||
|
}
|
||||||
|
return BitSet.valueOf( values );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] bitSetToBytes(BitSet bitSet) {
|
||||||
|
return bitSet == null ? null : bitSet.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitSet bytesToBitSet(byte[] bytes) {
|
||||||
|
return bytes == null || bytes.length == 0
|
||||||
|
? null
|
||||||
|
: BitSet.valueOf( bytes );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for using BitSet without any mapping details
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BitSetImplicitTests.Product.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BitSetImplicitTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
|
||||||
|
final MappingMetamodel domainModel = sessionFactory.getDomainModel();
|
||||||
|
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( Product.class );
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "bitSet" );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getValueConverter(), nullValue() );
|
||||||
|
|
||||||
|
assertThat(
|
||||||
|
attributeMapping.getJdbcMapping().getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
is( Types.VARBINARY )
|
||||||
|
);
|
||||||
|
|
||||||
|
// it will just be serialized
|
||||||
|
assertThat( attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Table(name = "products")
|
||||||
|
//tag::basic-bitset-example-implicit[]
|
||||||
|
@Entity(name = "Product")
|
||||||
|
public static class Product {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private BitSet bitSet;
|
||||||
|
|
||||||
|
//Getters and setters are omitted for brevity
|
||||||
|
//end::basic-bitset-example-implicit[]
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSet getBitSet() {
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitSet(BitSet bitSet) {
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
//tag::basic-bitset-example-implicit[]
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-implicit[]
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package org.hibernate.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.AbstractClassTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
//tag::basic-bitset-example-java-type[]
|
||||||
|
public class BitSetJavaType extends AbstractClassTypeDescriptor<BitSet> {
|
||||||
|
public static final BitSetJavaType INSTANCE = new BitSetJavaType();
|
||||||
|
|
||||||
|
public BitSetJavaType() {
|
||||||
|
super( BitSet.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MutabilityPlan<BitSet> getMutabilityPlan() {
|
||||||
|
return BitSetMutabilityPlan.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JdbcTypeDescriptor getRecommendedJdbcType(JdbcTypeDescriptorIndicators indicators) {
|
||||||
|
return indicators.getTypeConfiguration()
|
||||||
|
.getJdbcTypeDescriptorRegistry()
|
||||||
|
.getDescriptor( Types.VARCHAR );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(BitSet value) {
|
||||||
|
return BitSetHelper.bitSetToString( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BitSet fromString(String string) {
|
||||||
|
return BitSetHelper.stringToBitSet( string );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public <X> X unwrap(BitSet value, Class<X> type, WrapperOptions options) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ( BitSet.class.isAssignableFrom( type ) ) {
|
||||||
|
return (X) value;
|
||||||
|
}
|
||||||
|
if ( String.class.isAssignableFrom( type ) ) {
|
||||||
|
return (X) toString( value);
|
||||||
|
}
|
||||||
|
if ( type.isArray() ) {
|
||||||
|
if ( type.getComponentType() == byte.class ) {
|
||||||
|
return (X) value.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw unknownUnwrap( type );
|
||||||
|
}
|
||||||
|
|
||||||
|
public <X> BitSet wrap(X value, WrapperOptions options) {
|
||||||
|
if ( value == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if ( value instanceof String ) {
|
||||||
|
return fromString( (String) value );
|
||||||
|
}
|
||||||
|
if ( value instanceof BitSet ) {
|
||||||
|
return (BitSet) value;
|
||||||
|
}
|
||||||
|
throw unknownWrap( value.getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-java-type[]
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
import javax.persistence.Basic;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.JavaTypeRegistration;
|
||||||
|
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BitSetJavaTypeRegistrationTests.Product.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BitSetJavaTypeRegistrationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolution(SessionFactoryScope scope) {
|
||||||
|
final EntityPersister productType = scope.getSessionFactory()
|
||||||
|
.getRuntimeMetamodels()
|
||||||
|
.getMappingMetamodel()
|
||||||
|
.findEntityDescriptor( Product.class );
|
||||||
|
final SingularAttributeMapping bitSetAttribute = (SingularAttributeMapping) productType.findAttributeMapping( "bitSet" );
|
||||||
|
// make sure BitSetTypeDescriptor was selected
|
||||||
|
assertThat( bitSetAttribute.getJavaTypeDescriptor(), instanceOf( BitSetJavaType.class ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Table(name = "Product")
|
||||||
|
//tag::basic-bitset-example-java-type-global[]
|
||||||
|
@Entity(name = "Product")
|
||||||
|
@JavaTypeRegistration( javaType = BitSet.class, descriptorClass = BitSetJavaType.class )
|
||||||
|
public static class Product {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private BitSet bitSet;
|
||||||
|
|
||||||
|
//Constructors, getters, and setters are omitted for brevity
|
||||||
|
//end::basic-bitset-example-java-type-global[]
|
||||||
|
public Product() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Product(Number id, BitSet bitSet) {
|
||||||
|
this.id = id.intValue();
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSet getBitSet() {
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitSet(BitSet bitSet) {
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
//tag::basic-bitset-example-java-type-global[]
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-java-type-global[]
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
import javax.persistence.Basic;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.JavaType;
|
||||||
|
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for using an explicit {@link JavaType}
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BitSetJavaTypeTests.Product.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BitSetJavaTypeTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolution(SessionFactoryScope scope) {
|
||||||
|
final EntityPersister productType = scope.getSessionFactory()
|
||||||
|
.getRuntimeMetamodels()
|
||||||
|
.getMappingMetamodel()
|
||||||
|
.findEntityDescriptor( Product.class );
|
||||||
|
final SingularAttributeMapping bitSetAttribute = (SingularAttributeMapping) productType.findAttributeMapping( "bitSet" );
|
||||||
|
// make sure BitSetTypeDescriptor was selected
|
||||||
|
assertThat( bitSetAttribute.getJavaTypeDescriptor(), instanceOf( BitSetJavaType.class ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Table(name = "Product")
|
||||||
|
//tag::basic-bitset-example-java-type-local[]
|
||||||
|
@Entity(name = "Product")
|
||||||
|
public static class Product {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@JavaType( BitSetJavaType.class )
|
||||||
|
private BitSet bitSet;
|
||||||
|
|
||||||
|
//Constructors, getters, and setters are omitted for brevity
|
||||||
|
//end::basic-bitset-example-java-type-local[]
|
||||||
|
public Product() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Product(Number id, BitSet bitSet) {
|
||||||
|
this.id = id.intValue();
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSet getBitSet() {
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitSet(BitSet bitSet) {
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
//tag::basic-bitset-example-java-type-local[]
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-java-type-local[]
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.JdbcTypeCode;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link org.hibernate.annotations.JdbcTypeCode}
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BitSetJdbcTypeCodeTests.Product.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BitSetJdbcTypeCodeTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
|
||||||
|
final MappingMetamodel domainModel = sessionFactory.getDomainModel();
|
||||||
|
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( Product.class );
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "bitSet" );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getValueConverter(), nullValue() );
|
||||||
|
|
||||||
|
assertThat(
|
||||||
|
attributeMapping.getJdbcMapping().getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
is( Types.VARBINARY )
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new Product( 1, BitSet.valueOf( BitSetHelper.BYTES ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inSession(
|
||||||
|
(session) -> {
|
||||||
|
final Product product = session.get( Product.class, 1 );
|
||||||
|
assertThat( product.getBitSet(), equalTo( BitSet.valueOf( BitSetHelper.BYTES ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete Product" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Table(name = "Product")
|
||||||
|
//tag::basic-bitset-example-jdbc-type-code[]
|
||||||
|
@Entity(name = "Product")
|
||||||
|
public static class Product {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@JdbcTypeCode( Types.VARBINARY )
|
||||||
|
private BitSet bitSet;
|
||||||
|
|
||||||
|
//Constructors, getters, and setters are omitted for brevity
|
||||||
|
//end::basic-bitset-example-jdbc-type-code[]
|
||||||
|
public Product() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Product(Number id, BitSet bitSet) {
|
||||||
|
this.id = id.intValue();
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSet getBitSet() {
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitSet(BitSet bitSet) {
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
//tag::basic-bitset-example-jdbc-type-code[]
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-jdbc-type-code[]
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.JdbcTypeCode;
|
||||||
|
import org.hibernate.annotations.JdbcTypeRegistration;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BitSetJdbcTypeRegistrationTests.Product.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BitSetJdbcTypeRegistrationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
|
||||||
|
final MappingMetamodel domainModel = sessionFactory.getDomainModel();
|
||||||
|
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( Product.class );
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "bitSet" );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getValueConverter(), nullValue() );
|
||||||
|
|
||||||
|
assertThat(
|
||||||
|
attributeMapping.getJdbcMapping().getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
is( Types.VARBINARY )
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new Product( 1, BitSet.valueOf( BitSetHelper.BYTES ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inSession(
|
||||||
|
(session) -> {
|
||||||
|
final Product product = session.get( Product.class, 1 );
|
||||||
|
assertThat( product.getBitSet(), equalTo( BitSet.valueOf( BitSetHelper.BYTES ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete Product" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Table(name = "Product")
|
||||||
|
//tag::basic-bitset-example-jdbc-type-global[]
|
||||||
|
@Entity(name = "Product")
|
||||||
|
@JdbcTypeRegistration( CustomBinaryJdbcType.class )
|
||||||
|
public static class Product {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private BitSet bitSet;
|
||||||
|
|
||||||
|
//Constructors, getters, and setters are omitted for brevity
|
||||||
|
//end::basic-bitset-example-jdbc-type-global[]
|
||||||
|
public Product() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Product(Number id, BitSet bitSet) {
|
||||||
|
this.id = id.intValue();
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSet getBitSet() {
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitSet(BitSet bitSet) {
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
//tag::basic-bitset-example-jdbc-type-global[]
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-jdbc-type-global[]
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.JdbcType;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BitSetJdbcTypeTests.Product.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BitSetJdbcTypeTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
|
||||||
|
final MappingMetamodel domainModel = sessionFactory.getDomainModel();
|
||||||
|
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( Product.class );
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "bitSet" );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getValueConverter(), nullValue() );
|
||||||
|
|
||||||
|
assertThat(
|
||||||
|
attributeMapping.getJdbcMapping().getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
is( Types.VARBINARY )
|
||||||
|
);
|
||||||
|
|
||||||
|
assertThat( attributeMapping.getJdbcMapping().getJavaTypeDescriptor().getJavaTypeClass(), equalTo( BitSet.class ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new Product( 1, BitSet.valueOf( BitSetHelper.BYTES ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inSession(
|
||||||
|
(session) -> {
|
||||||
|
final Product product = session.get( Product.class, 1 );
|
||||||
|
assertThat( product.getBitSet(), equalTo( BitSet.valueOf( BitSetHelper.BYTES ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete Product" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Table(name = "Product")
|
||||||
|
//tag::basic-bitset-example-jdbc-type-local[]
|
||||||
|
@Entity(name = "Product")
|
||||||
|
public static class Product {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@JdbcType( CustomBinaryJdbcType.class )
|
||||||
|
private BitSet bitSet;
|
||||||
|
|
||||||
|
//Constructors, getters, and setters are omitted for brevity
|
||||||
|
//end::basic-bitset-example-jdbc-type-local[]
|
||||||
|
public Product() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Product(Number id, BitSet bitSet) {
|
||||||
|
this.id = id.intValue();
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitSet getBitSet() {
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitSet(BitSet bitSet) {
|
||||||
|
this.bitSet = bitSet;
|
||||||
|
}
|
||||||
|
//tag::basic-bitset-example-jdbc-type-local[]
|
||||||
|
}
|
||||||
|
//end::basic-bitset-example-jdbc-type-local[]
|
||||||
|
|
||||||
|
}
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import org.hibernate.SharedSessionContract;
|
||||||
|
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class BitSetMutabilityPlan implements MutabilityPlan<BitSet> {
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final BitSetMutabilityPlan INSTANCE = new BitSetMutabilityPlan();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BitSet deepCopy(BitSet value) {
|
||||||
|
return BitSet.valueOf( value.toByteArray() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable disassemble(BitSet value, SharedSessionContract session) {
|
||||||
|
return value.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BitSet assemble(Serializable cached, SharedSessionContract session) {
|
||||||
|
return BitSet.valueOf( (byte[]) cached );
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ public class BitSetType
|
||||||
public static final BitSetType INSTANCE = new BitSetType();
|
public static final BitSetType INSTANCE = new BitSetType();
|
||||||
|
|
||||||
public BitSetType() {
|
public BitSetType() {
|
||||||
super( VarcharTypeDescriptor.INSTANCE, BitSetTypeDescriptor.INSTANCE );
|
super( VarcharTypeDescriptor.INSTANCE, BitSetJavaType.INSTANCE );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,48 +10,54 @@ import java.util.BitSet;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
|
||||||
import org.hibernate.annotations.Type;
|
|
||||||
import org.hibernate.annotations.TypeDef;
|
import org.hibernate.annotations.TypeDef;
|
||||||
import org.hibernate.cfg.Configuration;
|
|
||||||
|
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
import org.junit.Test;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
public class BitSetTypeDefTest extends BaseCoreFunctionalTestCase {
|
@DomainModel( annotatedClasses = BitSetTypeDefTest.Product.class )
|
||||||
|
@SessionFactory
|
||||||
@Override
|
public class BitSetTypeDefTest {
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
|
||||||
return new Class<?>[] {
|
|
||||||
Product.class
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test(SessionFactoryScope scope) {
|
||||||
|
|
||||||
//tag::basic-custom-type-BitSetTypeDef-persistence-example[]
|
//tag::basic-custom-type-BitSetTypeDef-persistence-example[]
|
||||||
BitSet bitSet = BitSet.valueOf( new long[] {1, 2, 3} );
|
BitSet bitSet = BitSet.valueOf( new long[] {1, 2, 3} );
|
||||||
|
|
||||||
doInHibernate( this::sessionFactory, session -> {
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
Product product = new Product( );
|
Product product = new Product( );
|
||||||
product.setId( 1 );
|
product.setId( 1 );
|
||||||
product.setBitSet( bitSet );
|
product.setBitSet( bitSet );
|
||||||
session.persist( product );
|
session.persist( product );
|
||||||
} );
|
}
|
||||||
|
);
|
||||||
|
|
||||||
doInHibernate( this::sessionFactory, session -> {
|
scope.inTransaction(
|
||||||
Product product = session.get( Product.class, 1 );
|
(session) -> {
|
||||||
|
final Product product = session.get( Product.class, 1 );
|
||||||
assertEquals(bitSet, product.getBitSet());
|
assertEquals(bitSet, product.getBitSet());
|
||||||
} );
|
}
|
||||||
|
);
|
||||||
//end::basic-custom-type-BitSetTypeDef-persistence-example[]
|
//end::basic-custom-type-BitSetTypeDef-persistence-example[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete Product" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//tag::basic-custom-type-BitSetTypeDef-mapping-example[]
|
//tag::basic-custom-type-BitSetTypeDef-mapping-example[]
|
||||||
@Entity(name = "Product")
|
@Entity(name = "Product")
|
||||||
@TypeDef(
|
@TypeDef(
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
package org.hibernate.userguide.mapping.basic;
|
|
||||||
|
|
||||||
import java.util.BitSet;
|
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.WrapperOptions;
|
|
||||||
import org.hibernate.type.descriptor.java.AbstractClassTypeDescriptor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Vlad Mihalcea
|
|
||||||
*/
|
|
||||||
//tag::basic-custom-type-BitSetTypeDescriptor-example[]
|
|
||||||
public class BitSetTypeDescriptor extends AbstractClassTypeDescriptor<BitSet> {
|
|
||||||
|
|
||||||
private static final String DELIMITER = ",";
|
|
||||||
|
|
||||||
public static final BitSetTypeDescriptor INSTANCE = new BitSetTypeDescriptor();
|
|
||||||
|
|
||||||
public BitSetTypeDescriptor() {
|
|
||||||
super( BitSet.class );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(BitSet value) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
for ( long token : value.toLongArray() ) {
|
|
||||||
if ( builder.length() > 0 ) {
|
|
||||||
builder.append( DELIMITER );
|
|
||||||
}
|
|
||||||
builder.append( Long.toString( token, 2 ) );
|
|
||||||
}
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BitSet fromString(String string) {
|
|
||||||
if ( string == null || string.isEmpty() ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String[] tokens = string.split( DELIMITER );
|
|
||||||
long[] values = new long[tokens.length];
|
|
||||||
|
|
||||||
for ( int i = 0; i < tokens.length; i++ ) {
|
|
||||||
values[i] = Long.valueOf( tokens[i], 2 );
|
|
||||||
}
|
|
||||||
return BitSet.valueOf( values );
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
|
||||||
public <X> X unwrap(BitSet value, Class<X> type, WrapperOptions options) {
|
|
||||||
if ( value == null ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if ( BitSet.class.isAssignableFrom( type ) ) {
|
|
||||||
return (X) value;
|
|
||||||
}
|
|
||||||
if ( String.class.isAssignableFrom( type ) ) {
|
|
||||||
return (X) toString( value);
|
|
||||||
}
|
|
||||||
throw unknownUnwrap( type );
|
|
||||||
}
|
|
||||||
|
|
||||||
public <X> BitSet wrap(X value, WrapperOptions options) {
|
|
||||||
if ( value == null ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if ( String.class.isInstance( value ) ) {
|
|
||||||
return fromString( (String) value );
|
|
||||||
}
|
|
||||||
if ( BitSet.class.isInstance( value ) ) {
|
|
||||||
return (BitSet) value;
|
|
||||||
}
|
|
||||||
throw unknownWrap( value.getClass() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//end::basic-custom-type-BitSetTypeDescriptor-example[]
|
|
|
@ -48,14 +48,14 @@ public class BitSetUserType implements UserType {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object nullSafeGet(
|
public Object nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
|
||||||
ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
|
String columnValue = (String) rs.getObject( position );
|
||||||
throws HibernateException, SQLException {
|
if ( rs.wasNull() ) {
|
||||||
String columnName = names[0];
|
columnValue = null;
|
||||||
String columnValue = (String) rs.getObject( columnName );
|
}
|
||||||
log.debugv("Result set column {0} value is {1}", columnName, columnValue);
|
|
||||||
return columnValue == null ? null :
|
log.debugv("Result set column {0} value is {1}", position, columnValue);
|
||||||
BitSetTypeDescriptor.INSTANCE.fromString( columnValue );
|
return BitSetHelper.stringToBitSet( columnValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,7 +67,7 @@ public class BitSetUserType implements UserType {
|
||||||
st.setNull( index, Types.VARCHAR );
|
st.setNull( index, Types.VARCHAR );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String stringValue = BitSetTypeDescriptor.INSTANCE.toString( (BitSet) value );
|
String stringValue = BitSetHelper.bitSetToString( (BitSet) value );
|
||||||
log.debugv("Binding {0} to parameter {1} ", stringValue, index);
|
log.debugv("Binding {0} to parameter {1} ", stringValue, index);
|
||||||
st.setString( index, stringValue );
|
st.setString( index, stringValue );
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Basic;
|
||||||
|
import javax.persistence.Convert;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping boolean values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = BooleanMappingTests.EntityOfBooleans.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class BooleanMappingTests {
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfBooleans.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping implicit = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "implicit" );
|
||||||
|
final JdbcMapping jdbcMapping = implicit.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo( Boolean.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
// the implicit mapping will depend on the Dialect
|
||||||
|
isOneOf( Types.BOOLEAN, Types.BIT, Types.TINYINT )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Converters
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping convertedYesNo = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "convertedYesNo" );
|
||||||
|
final JdbcMapping jdbcMapping = convertedYesNo.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo( Character.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
// could be NCHAR if nationalization is globally enabled
|
||||||
|
isOneOf( Types.CHAR, Types.NCHAR )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping convertedTrueFalse = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "convertedTrueFalse" );
|
||||||
|
final JdbcMapping jdbcMapping = convertedTrueFalse.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo( Character.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
// could be NCHAR if nationalization is globally enabled
|
||||||
|
isOneOf( Types.CHAR, Types.NCHAR )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping convertedNumeric = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "convertedNumeric" );
|
||||||
|
final JdbcMapping jdbcMapping = convertedNumeric.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo( Integer.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
equalTo( Types.INTEGER )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Legacy
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping legacyYesNo = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "legacyYesNo" );
|
||||||
|
final JdbcMapping jdbcMapping = legacyYesNo.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo( Character.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
// could be NCHAR if nationalization is globally enabled
|
||||||
|
isOneOf( Types.CHAR, Types.NCHAR )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping legacyTrueFalse = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "legacyTrueFalse" );
|
||||||
|
final JdbcMapping jdbcMapping = legacyTrueFalse.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo( Character.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
// could be NCHAR if nationalization is globally enabled
|
||||||
|
isOneOf( Types.CHAR, Types.NCHAR )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping legacyNumeric = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "legacyNumeric" );
|
||||||
|
final JdbcMapping jdbcMapping = legacyNumeric.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaType(), equalTo( Integer.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
equalTo( Types.INTEGER )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfBooleans" )
|
||||||
|
@Table( name = "EntityOfBooleans" )
|
||||||
|
public static class EntityOfBooleans {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-boolean-example-implicit[]
|
||||||
|
// this will be mapped to BIT or BOOLEAN on the database
|
||||||
|
@Basic
|
||||||
|
boolean implicit;
|
||||||
|
//end::basic-boolean-example-implicit[]
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// converted
|
||||||
|
|
||||||
|
//tag::basic-boolean-example-explicit-yes-no[]
|
||||||
|
// this will get mapped to CHAR or NCHAR with a conversion
|
||||||
|
@Basic
|
||||||
|
@Convert( converter = org.hibernate.type.YesNoConverter.class )
|
||||||
|
boolean convertedYesNo;
|
||||||
|
//end::basic-boolean-example-explicit-yes-no[]
|
||||||
|
|
||||||
|
//tag::basic-boolean-example-explicit-t-f[]
|
||||||
|
// this will get mapped to CHAR or NCHAR with a conversion
|
||||||
|
@Basic
|
||||||
|
@Convert( converter = org.hibernate.type.TrueFalseConverter.class )
|
||||||
|
boolean convertedTrueFalse;
|
||||||
|
//end::basic-boolean-example-explicit-t-f[]
|
||||||
|
|
||||||
|
//tag::basic-boolean-example-explicit-numeric[]
|
||||||
|
// this will get mapped to TINYINT with a conversion
|
||||||
|
@Basic
|
||||||
|
@Convert( converter = org.hibernate.type.NumericBooleanConverter.class )
|
||||||
|
boolean convertedNumeric;
|
||||||
|
//end::basic-boolean-example-explicit-numeric[]
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Legacy
|
||||||
|
|
||||||
|
//tag::basic-boolean-example-explicit-legacy-yes-no[]
|
||||||
|
// this will get mapped to CHAR or NCHAR with a conversion
|
||||||
|
@Basic
|
||||||
|
@org.hibernate.annotations.Type( type = "yes_no" )
|
||||||
|
boolean legacyYesNo;
|
||||||
|
//end::basic-boolean-example-explicit-legacy-yes-no[]
|
||||||
|
|
||||||
|
//tag::basic-boolean-example-explicit-legacy-t-f[]
|
||||||
|
// this will get mapped to CHAR or NCHAR with a conversion
|
||||||
|
@Basic
|
||||||
|
@org.hibernate.annotations.Type( type = "true_false" )
|
||||||
|
boolean legacyTrueFalse;
|
||||||
|
//end::basic-boolean-example-explicit-legacy-t-f[]
|
||||||
|
|
||||||
|
//tag::basic-boolean-example-explicit-legacy-numeric[]
|
||||||
|
// this will get mapped to TINYINT with a conversion
|
||||||
|
@Basic
|
||||||
|
@org.hibernate.annotations.Type( type = "numeric_boolean" )
|
||||||
|
boolean legacyNumeric;
|
||||||
|
//end::basic-boolean-example-explicit-legacy-numeric[]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = ByteArrayMappingTests.EntityOfByteArrays.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class ByteArrayMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfByteArrays.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping primitive = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
final JdbcMapping jdbcMapping = primitive.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( byte[].class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARBINARY ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping primitive = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
final JdbcMapping jdbcMapping = primitive.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Byte[].class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARBINARY ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping primitive = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitiveLob" );
|
||||||
|
final JdbcMapping jdbcMapping = primitive.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( byte[].class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.BLOB ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping primitive = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapperLob" );
|
||||||
|
final JdbcMapping jdbcMapping = primitive.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Byte[].class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.BLOB ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist(
|
||||||
|
new EntityOfByteArrays( 1, "abc".getBytes(), new Byte[] { (byte) 1 } )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfByteArrays.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropTestData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfByteArrays" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfByteArrays" )
|
||||||
|
@Table( name = "EntityOfByteArrays" )
|
||||||
|
public static class EntityOfByteArrays {
|
||||||
|
@Id
|
||||||
|
public Integer id;
|
||||||
|
|
||||||
|
//tag::basic-bytearray-example[]
|
||||||
|
// mapped as VARBINARY
|
||||||
|
private byte[] primitive;
|
||||||
|
private Byte[] wrapper;
|
||||||
|
|
||||||
|
// mapped as (materialized) BLOB
|
||||||
|
@Lob
|
||||||
|
private byte[] primitiveLob;
|
||||||
|
@Lob
|
||||||
|
private Byte[] wrapperLob;
|
||||||
|
//end::basic-bytearray-example[]
|
||||||
|
|
||||||
|
public EntityOfByteArrays() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfByteArrays(Integer id, byte[] primitive, Byte[] wrapper) {
|
||||||
|
this.id = id;
|
||||||
|
this.primitive = primitive;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitiveLob = primitive;
|
||||||
|
this.wrapperLob = wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfByteArrays(Integer id, byte[] primitive, Byte[] wrapper, byte[] primitiveLob, Byte[] wrapperLob) {
|
||||||
|
this.id = id;
|
||||||
|
this.primitive = primitive;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitiveLob = primitiveLob;
|
||||||
|
this.wrapperLob = wrapperLob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping byte values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = ByteMappingTests.EntityOfBytes.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class ByteMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfBytes.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Byte.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Byte.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.TINYINT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Byte.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Byte.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.TINYINT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfBytes( 1, (byte) 3, (byte) 5 ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfBytes.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfBytes" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfBytes" )
|
||||||
|
@Table( name = "EntityOfBytes" )
|
||||||
|
public static class EntityOfBytes {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-byte-example-implicit[]
|
||||||
|
// these will both be mapped using TINYINT
|
||||||
|
Byte wrapper;
|
||||||
|
byte primitive;
|
||||||
|
//end::basic-byte-example-implicit[]
|
||||||
|
|
||||||
|
|
||||||
|
public EntityOfBytes() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfBytes(Integer id, Byte wrapper, byte primitive) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitive = primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Nationalized;
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = CharacterArrayMappingTests.EntityWithCharArrays.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class CharacterArrayMappingTests {
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithCharArrays.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARCHAR ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARCHAR ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitiveClob" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.CLOB ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapperClob" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.CLOB ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithCharArrays" )
|
||||||
|
@Table( name = "EntityWithCharArrays" )
|
||||||
|
public static class EntityWithCharArrays {
|
||||||
|
@Id
|
||||||
|
public Integer id;
|
||||||
|
|
||||||
|
//tag::basic-chararray-example[]
|
||||||
|
// mapped as VARCHAR
|
||||||
|
char[] primitive;
|
||||||
|
Character[] wrapper;
|
||||||
|
|
||||||
|
// mapped as CLOB
|
||||||
|
@Lob
|
||||||
|
char[] primitiveClob;
|
||||||
|
@Lob
|
||||||
|
Character[] wrapperClob;
|
||||||
|
//end::basic-chararray-example[]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Nationalized;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.NationalizationSupport;
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CharacterArrayMappingTests
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = CharacterArrayNationalizedMappingTests.EntityWithCharArrays.class )
|
||||||
|
@SessionFactory
|
||||||
|
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsNationalizedData.class )
|
||||||
|
public class CharacterArrayNationalizedMappingTests {
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithCharArrays.class );
|
||||||
|
|
||||||
|
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
||||||
|
final NationalizationSupport nationalizationSupport = dialect.getNationalizationSupport();
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitiveNVarchar" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getVarcharVariantCode() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapperNVarchar" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getVarcharVariantCode() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitiveNClob" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getClobVariantCode() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapperNClob" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getClobVariantCode() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithCharArrays" )
|
||||||
|
@Table( name = "EntityWithCharArrays" )
|
||||||
|
public static class EntityWithCharArrays {
|
||||||
|
@Id
|
||||||
|
public Integer id;
|
||||||
|
|
||||||
|
//tag::basic-nchararray-example[]
|
||||||
|
// mapped as NVARCHAR
|
||||||
|
@Nationalized
|
||||||
|
char[] primitiveNVarchar;
|
||||||
|
@Nationalized
|
||||||
|
Character[] wrapperNVarchar;
|
||||||
|
|
||||||
|
// mapped as NCLOB
|
||||||
|
@Lob
|
||||||
|
@Nationalized
|
||||||
|
char[] primitiveNClob;
|
||||||
|
@Lob
|
||||||
|
@Nationalized
|
||||||
|
Character[] wrapperNClob;
|
||||||
|
//end::basic-nchararray-example[]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `double` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = CharacterMappingTests.EntityOfCharacters.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class CharacterMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfCharacters.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Character.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Character.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.CHAR ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Character.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Character.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.CHAR ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfCharacters( 1, 'A', 'b' ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfCharacters.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfCharacters" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfCharacters" )
|
||||||
|
@Table( name = "EntityOfCharacters" )
|
||||||
|
public static class EntityOfCharacters {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-character-example-implicit[]
|
||||||
|
// these will be mapped using CHAR
|
||||||
|
Character wrapper;
|
||||||
|
char primitive;
|
||||||
|
//end::basic-character-example-implicit[]
|
||||||
|
|
||||||
|
public EntityOfCharacters() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfCharacters(Integer id, Character wrapper, char primitive) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitive = primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = ClassMappingTests.EntityWithClass.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class ClassMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithClass.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "clazz" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Class.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARCHAR ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithClass( 1, String.class ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithClass.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithClass" )
|
||||||
|
@Table( name = "EntityWithClass" )
|
||||||
|
public static class EntityWithClass {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-Class-example[]
|
||||||
|
// mapped as VARCHAR
|
||||||
|
private Class<?> clazz;
|
||||||
|
//end::basic-Class-example[]
|
||||||
|
|
||||||
|
public EntityWithClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithClass(Integer id, Class<?> clazz) {
|
||||||
|
this.id = id;
|
||||||
|
this.clazz = clazz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,40 +10,47 @@ import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Lob;
|
import javax.persistence.Lob;
|
||||||
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Jpa;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
public class ClobCharArrayTest extends BaseEntityManagerFunctionalTestCase {
|
@Jpa( annotatedClasses = ClobCharArrayTest.Product.class )
|
||||||
|
public class ClobCharArrayTest {
|
||||||
@Override
|
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
|
||||||
return new Class<?>[] {
|
|
||||||
Product.class
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test(EntityManagerFactoryScope scope) {
|
||||||
Integer productId = doInJPA( this::entityManagerFactory, entityManager -> {
|
Integer productId = scope.fromTransaction(
|
||||||
|
(em) -> {
|
||||||
final Product product = new Product( );
|
final Product product = new Product( );
|
||||||
product.setId( 1 );
|
product.setId( 1 );
|
||||||
product.setName( "Mobile phone" );
|
product.setName( "Mobile phone" );
|
||||||
product.setWarranty( "My product warranty".toCharArray() );
|
product.setWarranty( "My product warranty".toCharArray() );
|
||||||
|
|
||||||
entityManager.persist( product );
|
em.persist( product );
|
||||||
return product.getId();
|
return product.getId();
|
||||||
} );
|
}
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
);
|
||||||
Product product = entityManager.find( Product.class, productId );
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(em) -> {
|
||||||
|
final Product product = em.find( Product.class, productId );
|
||||||
assertArrayEquals( "My product warranty".toCharArray(), product.getWarranty() );
|
assertArrayEquals( "My product warranty".toCharArray(), product.getWarranty() );
|
||||||
} );
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete Product" ).executeUpdate()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//tag::basic-clob-char-array-example[]
|
//tag::basic-clob-char-array-example[]
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.userguide.mapping.basic;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Currency;
|
import java.util.Currency;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import javax.persistence.Embedded;
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@ -18,6 +17,7 @@ import org.hibernate.dialect.H2Dialect;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
import org.hibernate.testing.RequiresDialect;
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.testing.orm.junit.NotImplementedYet;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
@ -26,6 +26,10 @@ import static org.junit.Assert.assertEquals;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
|
@NotImplementedYet(
|
||||||
|
reason = "composition-as-basic (basic mapped to multiple columns) is no longer supported. See https://github.com/hibernate/hibernate-orm/discussions/3960",
|
||||||
|
strict = false
|
||||||
|
)
|
||||||
@RequiresDialect(H2Dialect.class)
|
@RequiresDialect(H2Dialect.class)
|
||||||
public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
|
@ -43,13 +47,15 @@ public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
//tag::basic-datetime-temporal-date-persist-example[]
|
//tag::basic-datetime-temporal-date-persist-example[]
|
||||||
Savings savings = new Savings( );
|
Savings savings = new Savings( );
|
||||||
savings.setId( 1L );
|
savings.setId( 1L );
|
||||||
savings.setWallet( new MonetaryAmount( BigDecimal.TEN, Currency.getInstance( Locale.US ) ) );
|
savings.setCurrency( Currency.getInstance( Locale.US ) );
|
||||||
|
savings.setAmount( BigDecimal.TEN );
|
||||||
entityManager.persist( savings );
|
entityManager.persist( savings );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
Savings savings = entityManager.find( Savings.class, 1L );
|
Savings savings = entityManager.find( Savings.class, 1L );
|
||||||
assertEquals( 10, savings.getWallet().getAmount().intValue());
|
assertEquals( 10, savings.getAmount().intValue());
|
||||||
|
assertEquals( Currency.getInstance( Locale.US ), savings.getCurrency() );
|
||||||
} );
|
} );
|
||||||
//end::mapping-column-read-and-write-composite-type-persistence-example[]
|
//end::mapping-column-read-and-write-composite-type-persistence-example[]
|
||||||
}
|
}
|
||||||
|
@ -61,14 +67,12 @@ public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
@Id
|
@Id
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Embedded
|
|
||||||
@ColumnTransformer(
|
@ColumnTransformer(
|
||||||
forColumn = "money",
|
read = "amount / 100",
|
||||||
read = "money / 100",
|
|
||||||
write = "? * 100"
|
write = "? * 100"
|
||||||
)
|
)
|
||||||
// todo (6.0): needs a composite user type mechanism e.g. by providing a custom ComponentTuplizer/Instantiator
|
private BigDecimal amount;
|
||||||
private MonetaryAmount wallet;
|
private Currency currency;
|
||||||
|
|
||||||
//Getters and setters omitted for brevity
|
//Getters and setters omitted for brevity
|
||||||
|
|
||||||
|
@ -81,12 +85,20 @@ public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonetaryAmount getWallet() {
|
public BigDecimal getAmount() {
|
||||||
return wallet;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWallet(MonetaryAmount wallet) {
|
public void setAmount(BigDecimal amount) {
|
||||||
this.wallet = wallet;
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Currency getCurrency() {
|
||||||
|
return currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrency(Currency currency) {
|
||||||
|
this.currency = currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Currency;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = CurrencyMappingTests.EntityWithCurrency.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class CurrencyMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithCurrency.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "currency" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Currency.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARCHAR ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithCurrency( 1, Currency.getInstance( "USD" ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithCurrency.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithCurrency" )
|
||||||
|
@Table( name = "EntityWithCurrency" )
|
||||||
|
public static class EntityWithCurrency {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-Currency-example[]
|
||||||
|
// mapped as VARCHAR
|
||||||
|
private Currency currency;
|
||||||
|
//end::basic-Currency-example[]
|
||||||
|
|
||||||
|
public EntityWithCurrency() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithCurrency(Integer id, Currency currency) {
|
||||||
|
this.id = id;
|
||||||
|
this.currency = currency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JdbcTypeDescriptor for documentation
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class CustomBinaryJdbcType implements JdbcTypeDescriptor {
|
||||||
|
@Override
|
||||||
|
public int getJdbcType() {
|
||||||
|
return Types.VARBINARY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBeRemapped() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> ValueBinder<X> getBinder(JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||||
|
return VarbinaryTypeDescriptor.INSTANCE.getBinder( javaTypeDescriptor );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaTypeDescriptor<X> javaTypeDescriptor) {
|
||||||
|
return VarbinaryTypeDescriptor.INSTANCE.getExtractor( javaTypeDescriptor );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Date;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
import org.hibernate.type.descriptor.java.TemporalJavaTypeDescriptor;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = DatePrecisionTests.EntityOfDates.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class DatePrecisionTests {
|
||||||
|
@Test
|
||||||
|
public void verifyMapping(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfDates.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "dateAsTimestamp" );
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
final TemporalJavaTypeDescriptor jtd = (TemporalJavaTypeDescriptor) jdbcMapping.getJavaTypeDescriptor();
|
||||||
|
assertThat( jtd, is( attribute.getJavaTypeDescriptor() ) );
|
||||||
|
assertThat( jtd.getJavaTypeClass(), equalTo( java.util.Date.class ) );
|
||||||
|
assertThat( jtd.getPrecision(), equalTo( TemporalType.TIMESTAMP ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.TIMESTAMP ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "dateAsDate" );
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
final TemporalJavaTypeDescriptor jtd = (TemporalJavaTypeDescriptor) jdbcMapping.getJavaTypeDescriptor();
|
||||||
|
assertThat( jtd, is( attribute.getJavaTypeDescriptor() ) );
|
||||||
|
assertThat( jtd.getJavaTypeClass(), equalTo( java.util.Date.class ) );
|
||||||
|
assertThat( jtd.getPrecision(), equalTo( TemporalType.DATE ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.DATE ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "dateAsTime" );
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
final TemporalJavaTypeDescriptor jtd = (TemporalJavaTypeDescriptor) jdbcMapping.getJavaTypeDescriptor();
|
||||||
|
assertThat( jtd, is( attribute.getJavaTypeDescriptor() ) );
|
||||||
|
assertThat( jtd.getJavaTypeClass(), equalTo( java.util.Date.class ) );
|
||||||
|
assertThat( jtd.getPrecision(), equalTo( TemporalType.TIME ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.TIME ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// check persistence operations
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist(
|
||||||
|
new EntityOfDates(
|
||||||
|
1,
|
||||||
|
Date.from( Instant.now() ),
|
||||||
|
Date.from( Instant.now() ),
|
||||||
|
Date.from( Instant.now() )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.find( EntityOfDates.class, 1 );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithTimestamp" )
|
||||||
|
public static class EntityOfDates {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-temporal-example[]
|
||||||
|
// mapped as TIMESTAMP by default
|
||||||
|
Date dateAsTimestamp;
|
||||||
|
|
||||||
|
// explicitly mapped as DATE
|
||||||
|
@Temporal( TemporalType.DATE )
|
||||||
|
Date dateAsDate;
|
||||||
|
|
||||||
|
// explicitly mapped as TIME
|
||||||
|
@Temporal( TemporalType.TIME )
|
||||||
|
Date dateAsTime;
|
||||||
|
//end::basic-temporal-example[]
|
||||||
|
|
||||||
|
|
||||||
|
public EntityOfDates() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfDates(Integer id, Date dateAsTimestamp, Date dateAsDate, Date dateAsTime) {
|
||||||
|
this.id = id;
|
||||||
|
this.dateAsTimestamp = dateAsTimestamp;
|
||||||
|
this.dateAsDate = dateAsDate;
|
||||||
|
this.dateAsTime = dateAsTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `double` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = DoubleMappingTests.EntityOfDoubles.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class DoubleMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfDoubles.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Double.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Double.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
isOneOf( Types.DOUBLE, Types.FLOAT, Types.REAL, Types.NUMERIC )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Double.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Double.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
isOneOf( Types.DOUBLE, Types.FLOAT, Types.REAL, Types.NUMERIC )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfDoubles( 1, 3.0, 5.0 ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfDoubles.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfDoubles" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfDoubles" )
|
||||||
|
@Table( name = "EntityOfDoubles" )
|
||||||
|
public static class EntityOfDoubles {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-double-example-implicit[]
|
||||||
|
// these will be mapped using DOUBLE, FLOAT, REAL or NUMERIC
|
||||||
|
// depending on the capabilities of the database
|
||||||
|
Double wrapper;
|
||||||
|
double primitive;
|
||||||
|
//end::basic-double-example-implicit[]
|
||||||
|
|
||||||
|
public EntityOfDoubles() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfDoubles(Integer id, Double wrapper, double primitive) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitive = primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.Duration;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = DurationMappingTests.EntityWithDuration.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class DurationMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithDuration.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "duration" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Duration.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.NUMERIC ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithDuration( 1, Duration.ofHours( 3 ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithDuration.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithDuration" )
|
||||||
|
@Table( name = "EntityWithDuration" )
|
||||||
|
public static class EntityWithDuration {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-duration-example[]
|
||||||
|
private Duration duration;
|
||||||
|
//end::basic-duration-example[]
|
||||||
|
|
||||||
|
public EntityWithDuration() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithDuration(Integer id, Duration duration) {
|
||||||
|
this.id = id;
|
||||||
|
this.duration = duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `double` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = FloatMappingTests.EntityOfFloats.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class FloatMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfFloats.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Float.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Float.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
isOneOf( Types.FLOAT, Types.REAL, Types.NUMERIC )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Float.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Float.class ) );
|
||||||
|
assertThat(
|
||||||
|
jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(),
|
||||||
|
isOneOf( Types.FLOAT, Types.REAL, Types.NUMERIC )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfFloats( 1, 3.0F, 5.0F ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfFloats.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfFloats" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfFloats" )
|
||||||
|
@Table( name = "EntityOfFloats" )
|
||||||
|
public static class EntityOfFloats {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-float-example-implicit[]
|
||||||
|
// these will be mapped using FLOAT, REAL or NUMERIC
|
||||||
|
// depending on the capabilities of the database
|
||||||
|
Float wrapper;
|
||||||
|
float primitive;
|
||||||
|
//end::basic-float-example-implicit[]
|
||||||
|
|
||||||
|
public EntityOfFloats() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfFloats(Integer id, Float wrapper, float primitive) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitive = primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = InstantMappingTests.EntityWithInstant.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class InstantMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithInstant.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "instant" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Instant.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.TIMESTAMP ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithInstant( 1, Instant.now() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithInstant.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithInstant" )
|
||||||
|
@Table( name = "EntityWithInstant" )
|
||||||
|
public static class EntityWithInstant {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-instant-example[]
|
||||||
|
// mapped as TIMESTAMP
|
||||||
|
private Instant instant;
|
||||||
|
//end::basic-instant-example[]
|
||||||
|
|
||||||
|
public EntityWithInstant() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithInstant(Integer id, Instant instant) {
|
||||||
|
this.id = id;
|
||||||
|
this.instant = instant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `short` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = IntegerMappingTests.EntityOfIntegers.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class IntegerMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfIntegers.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Integer.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Integer.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.INTEGER ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Integer.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Integer.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.INTEGER ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfIntegers( 1, 3, 5 ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfIntegers.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfIntegers" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfIntegers" )
|
||||||
|
@Table( name = "EntityOfIntegers" )
|
||||||
|
public static class EntityOfIntegers {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-integer-example-implicit[]
|
||||||
|
// these will both be mapped using INTEGER
|
||||||
|
Integer wrapper;
|
||||||
|
int primitive;
|
||||||
|
//end::basic-integer-example-implicit[]
|
||||||
|
|
||||||
|
public EntityOfIntegers() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfIntegers(Integer id, Integer wrapper, int primitive) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitive = primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = LocalDateMappingTests.EntityWithLocalDate.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class LocalDateMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithLocalDate.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "localDate" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( LocalDate.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.DATE ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithLocalDate( 1, LocalDate.now() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithLocalDate.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithLocalDate" )
|
||||||
|
@Table( name = "EntityWithLocalDate" )
|
||||||
|
public static class EntityWithLocalDate {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-localDate-example[]
|
||||||
|
// mapped as DATE
|
||||||
|
private LocalDate localDate;
|
||||||
|
//end::basic-localDate-example[]
|
||||||
|
|
||||||
|
public EntityWithLocalDate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithLocalDate(Integer id, LocalDate localDate) {
|
||||||
|
this.id = id;
|
||||||
|
this.localDate = localDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = LocalDateTimeMappingTests.EntityWithLocalDateTime.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class LocalDateTimeMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithLocalDateTime.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "localDateTime" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( LocalDateTime.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.TIMESTAMP ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithLocalDateTime( 1, LocalDateTime.now() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithLocalDateTime.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithLocalDateTime" )
|
||||||
|
@Table( name = "EntityWithLocalDateTime" )
|
||||||
|
public static class EntityWithLocalDateTime {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-localDateTime-example[]
|
||||||
|
// mapped as TIMESTAMP
|
||||||
|
private LocalDateTime localDateTime;
|
||||||
|
//end::basic-localDateTime-example[]
|
||||||
|
|
||||||
|
public EntityWithLocalDateTime() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithLocalDateTime(Integer id, LocalDateTime localDateTime) {
|
||||||
|
this.id = id;
|
||||||
|
this.localDateTime = localDateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = LocalTimeMappingTests.EntityWithLocalTime.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class LocalTimeMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithLocalTime.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "localTime" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( LocalTime.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.TIME ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithLocalTime( 1, LocalTime.now() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithLocalTime.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithLocalTime" )
|
||||||
|
@Table( name = "EntityWithLocalTime" )
|
||||||
|
public static class EntityWithLocalTime {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@Column( name = "`localTime`")
|
||||||
|
//tag::basic-localTime-example[]
|
||||||
|
// mapped as TIME
|
||||||
|
private LocalTime localTime;
|
||||||
|
//end::basic-localTime-example[]
|
||||||
|
|
||||||
|
public EntityWithLocalTime() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithLocalTime(Integer id, LocalTime localTime) {
|
||||||
|
this.id = id;
|
||||||
|
this.localTime = localTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Currency;
|
||||||
|
import java.util.Locale;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = LocaleMappingTests.EntityWithLocale.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class LocaleMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithLocale.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "locale" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Locale.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARCHAR ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithLocale( 1, Locale.US ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithLocale.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithLocale" )
|
||||||
|
@Table( name = "EntityWithLocale" )
|
||||||
|
public static class EntityWithLocale {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-Locale-example[]
|
||||||
|
// mapped as VARCHAR
|
||||||
|
private Locale locale;
|
||||||
|
//end::basic-Locale-example[]
|
||||||
|
|
||||||
|
public EntityWithLocale() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithLocale(Integer id, Locale locale) {
|
||||||
|
this.id = id;
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `short` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = LongMappingTests.EntityOfLongs.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class LongMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfLongs.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Long.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Long.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.BIGINT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Long.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Long.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.BIGINT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfLongs( 1, 3L, 5L ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfLongs.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfLongs" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfLongs" )
|
||||||
|
@Table( name = "EntityOfLongs" )
|
||||||
|
public static class EntityOfLongs {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-long-example-implicit[]
|
||||||
|
// these will both be mapped using BIGINT
|
||||||
|
Long wrapper;
|
||||||
|
long primitive;
|
||||||
|
//end::basic-long-example-implicit[]
|
||||||
|
|
||||||
|
public EntityOfLongs() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfLongs(Integer id, Long wrapper, long primitive) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitive = primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,12 +11,8 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.Lob;
|
import javax.persistence.Lob;
|
||||||
|
|
||||||
import org.hibernate.annotations.Nationalized;
|
import org.hibernate.annotations.Nationalized;
|
||||||
import org.hibernate.dialect.DB2Dialect;
|
|
||||||
import org.hibernate.dialect.MySQL5Dialect;
|
|
||||||
import org.hibernate.dialect.PostgreSQL81Dialect;
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
import org.hibernate.testing.SkipForDialect;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
@ -25,14 +21,6 @@ import static org.junit.Assert.assertArrayEquals;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@SkipForDialect(
|
|
||||||
value = {
|
|
||||||
PostgreSQL81Dialect.class,
|
|
||||||
MySQL5Dialect.class,
|
|
||||||
DB2Dialect.class
|
|
||||||
},
|
|
||||||
comment = "@see https://hibernate.atlassian.net/browse/HHH-10693 and https://hibernate.atlassian.net/browse/HHH-10695 and https://hibernate.atlassian.net/browse/HHH-10473"
|
|
||||||
)
|
|
||||||
public class NClobCharArrayTest extends BaseEntityManagerFunctionalTestCase {
|
public class NClobCharArrayTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,12 +11,10 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.Lob;
|
import javax.persistence.Lob;
|
||||||
|
|
||||||
import org.hibernate.annotations.Nationalized;
|
import org.hibernate.annotations.Nationalized;
|
||||||
import org.hibernate.dialect.DB2Dialect;
|
|
||||||
import org.hibernate.dialect.MySQL5Dialect;
|
|
||||||
import org.hibernate.dialect.PostgreSQL81Dialect;
|
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
import org.hibernate.testing.SkipForDialect;
|
import org.hibernate.testing.DialectChecks;
|
||||||
|
import org.hibernate.testing.RequiresDialectFeature;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
@ -25,14 +23,6 @@ import static org.junit.Assert.assertEquals;
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@SkipForDialect(
|
|
||||||
value = {
|
|
||||||
PostgreSQL81Dialect.class,
|
|
||||||
MySQL5Dialect.class,
|
|
||||||
DB2Dialect.class
|
|
||||||
},
|
|
||||||
comment = "@see https://hibernate.atlassian.net/browse/HHH-10693 and https://hibernate.atlassian.net/browse/HHH-10695 and https://hibernate.atlassian.net/browse/HHH-10473"
|
|
||||||
)
|
|
||||||
public class NClobStringTest extends BaseEntityManagerFunctionalTestCase {
|
public class NClobStringTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,50 +15,31 @@ import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Lob;
|
import javax.persistence.Lob;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
|
||||||
import org.hibernate.annotations.Nationalized;
|
import org.hibernate.annotations.Nationalized;
|
||||||
import org.hibernate.dialect.AbstractHANADialect;
|
|
||||||
import org.hibernate.dialect.CockroachDialect;
|
|
||||||
import org.hibernate.dialect.DB2Dialect;
|
|
||||||
import org.hibernate.dialect.MySQL5Dialect;
|
|
||||||
import org.hibernate.dialect.PostgreSQL81Dialect;
|
|
||||||
import org.hibernate.engine.jdbc.NClobProxy;
|
import org.hibernate.engine.jdbc.NClobProxy;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
|
||||||
|
|
||||||
import org.hibernate.testing.SkipForDialect;
|
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||||
import org.junit.Test;
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Jpa;
|
||||||
|
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@SkipForDialect(
|
@Jpa(annotatedClasses = NClobTest.Product.class)
|
||||||
value = {
|
@RequiresDialectFeature(
|
||||||
PostgreSQL81Dialect.class,
|
feature = DialectFeatureChecks.SupportsNationalizedDataTypes.class,
|
||||||
MySQL5Dialect.class,
|
|
||||||
AbstractHANADialect.class,
|
|
||||||
CockroachDialect.class,
|
|
||||||
DB2Dialect.class
|
|
||||||
},
|
|
||||||
comment = "@see https://hibernate.atlassian.net/browse/HHH-10693 and https://hibernate.atlassian.net/browse/HHH-10695 and https://hibernate.atlassian.net/browse/HHH-10473"
|
comment = "@see https://hibernate.atlassian.net/browse/HHH-10693 and https://hibernate.atlassian.net/browse/HHH-10695 and https://hibernate.atlassian.net/browse/HHH-10473"
|
||||||
)
|
)
|
||||||
public class NClobTest extends BaseEntityManagerFunctionalTestCase {
|
public class NClobTest {
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
|
||||||
return new Class<?>[] {
|
|
||||||
Product.class
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test(EntityManagerFactoryScope scope) {
|
||||||
Integer productId = doInJPA( this::entityManagerFactory, entityManager -> {
|
scope.inTransaction(
|
||||||
Session session = entityManager.unwrap( Session.class );
|
(entityManager) -> {
|
||||||
|
|
||||||
//tag::basic-nclob-persist-example[]
|
//tag::basic-nclob-persist-example[]
|
||||||
String warranty = "My product warranty";
|
String warranty = "My product warranty";
|
||||||
|
|
||||||
|
@ -70,16 +51,16 @@ public class NClobTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
entityManager.persist( product );
|
entityManager.persist( product );
|
||||||
//end::basic-nclob-persist-example[]
|
//end::basic-nclob-persist-example[]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return product.getId();
|
scope.inTransaction(
|
||||||
} );
|
(entityManager) -> {
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
try {
|
try {
|
||||||
//tag::basic-nclob-find-example[]
|
//tag::basic-nclob-find-example[]
|
||||||
|
Product product = entityManager.find( Product.class, 1 );
|
||||||
|
|
||||||
Product product = entityManager.find( Product.class, productId );
|
try ( Reader reader = product.getWarranty().getCharacterStream() ) {
|
||||||
|
|
||||||
try (Reader reader = product.getWarranty().getCharacterStream()) {
|
|
||||||
assertEquals( "My product warranty", toString( reader ) );
|
assertEquals( "My product warranty", toString( reader ) );
|
||||||
}
|
}
|
||||||
//end::basic-nclob-find-example[]
|
//end::basic-nclob-find-example[]
|
||||||
|
@ -87,17 +68,18 @@ public class NClobTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
fail( e.getMessage() );
|
fail( e.getMessage() );
|
||||||
}
|
}
|
||||||
} );
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toString(Reader reader) throws IOException {
|
private String toString(Reader reader) throws IOException {
|
||||||
BufferedReader bufferedReader = new BufferedReader( reader);
|
BufferedReader bufferedReader = new BufferedReader( reader );
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
int result = bufferedReader.read();
|
int result = bufferedReader.read();
|
||||||
|
|
||||||
while(result != -1) {
|
while ( result != -1 ) {
|
||||||
byteArrayOutputStream.write((byte) result);
|
byteArrayOutputStream.write( (byte) result );
|
||||||
result = bufferedReader.read();
|
result = bufferedReader.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = OffsetDateTimeMappingTests.EntityWithOffsetDateTime.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class OffsetDateTimeMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithOffsetDateTime.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "offsetDateTime" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( OffsetDateTime.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), isOneOf( Types.TIMESTAMP, Types.TIMESTAMP_WITH_TIMEZONE ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithOffsetDateTime( 1, OffsetDateTime.now() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithOffsetDateTime.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithOffsetDateTime" )
|
||||||
|
@Table( name = "EntityWithOffsetDateTime" )
|
||||||
|
public static class EntityWithOffsetDateTime {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-OffsetDateTime-example[]
|
||||||
|
// mapped as TIMESTAMP or TIMESTAMP_WITH_TIMEZONE
|
||||||
|
private OffsetDateTime offsetDateTime;
|
||||||
|
//end::basic-OffsetDateTime-example[]
|
||||||
|
|
||||||
|
public EntityWithOffsetDateTime() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithOffsetDateTime(Integer id, OffsetDateTime offsetDateTime) {
|
||||||
|
this.id = id;
|
||||||
|
this.offsetDateTime = offsetDateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.OffsetTime;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = OffsetTimeMappingTests.EntityWithOffsetTime.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class OffsetTimeMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithOffsetTime.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "offsetTime" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( OffsetTime.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), isOneOf( Types.TIME, Types.TIME_WITH_TIMEZONE ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithOffsetTime( 1, OffsetTime.now() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithOffsetTime.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithOffsetTime" )
|
||||||
|
@Table( name = "EntityWithOffsetTime" )
|
||||||
|
public static class EntityWithOffsetTime {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-offsetTime-example[]
|
||||||
|
// mapped as TIME or TIME_WITH_TIMEZONE
|
||||||
|
private OffsetTime offsetTime;
|
||||||
|
//end::basic-offsetTime-example[]
|
||||||
|
|
||||||
|
public EntityWithOffsetTime() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithOffsetTime(Integer id, OffsetTime offsetTime) {
|
||||||
|
this.id = id;
|
||||||
|
this.offsetTime = offsetTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `short` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = ShortMappingTests.EntityOfShorts.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class ShortMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfShorts.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "wrapper" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Short.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Short.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.SMALLINT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "primitive" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Short.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( Short.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), is( Types.SMALLINT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfShorts( 1, (short) 3, (short) 5 ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfShorts.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfShorts" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfShorts" )
|
||||||
|
@Table( name = "EntityOfShorts" )
|
||||||
|
public static class EntityOfShorts {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-short-example-implicit[]
|
||||||
|
// these will both be mapped using SMALLINT
|
||||||
|
Short wrapper;
|
||||||
|
short primitive;
|
||||||
|
//end::basic-short-example-implicit[]
|
||||||
|
|
||||||
|
public EntityOfShorts() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfShorts(Integer id, Short wrapper, short primitive) {
|
||||||
|
this.id = id;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.primitive = primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `double` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = StringMappingTests.EntityOfStrings.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class StringMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfStrings.class );
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "string" );
|
||||||
|
assertThat( attribute.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( String.class ) );
|
||||||
|
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( String.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARCHAR ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "clobString" );
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( String.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.CLOB ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfStrings( 1, "string", "clob" ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfStrings.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfStrings" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfStrings" )
|
||||||
|
@Table( name = "EntityOfStrings" )
|
||||||
|
public static class EntityOfStrings {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-string-example[]
|
||||||
|
// will be mapped using VARCHAR
|
||||||
|
String string;
|
||||||
|
|
||||||
|
// will be mapped using CLOB
|
||||||
|
@Lob
|
||||||
|
String clobString;
|
||||||
|
//end::basic-string-example[]
|
||||||
|
|
||||||
|
public EntityOfStrings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfStrings(Integer id, String string, String clobString) {
|
||||||
|
this.id = id;
|
||||||
|
this.string = string;
|
||||||
|
this.clobString = clobString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Nationalized;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.NationalizationSupport;
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for mapping `double` values
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = StringNationalizedMappingTests.EntityOfStrings.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class StringNationalizedMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMappings(SessionFactoryScope scope) {
|
||||||
|
// first, verify the type selections...
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityOfStrings.class );
|
||||||
|
|
||||||
|
final Dialect dialect = scope.getSessionFactory().getJdbcServices().getDialect();
|
||||||
|
final NationalizationSupport nationalizationSupport = dialect.getNationalizationSupport();
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "nstring" );
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( String.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getVarcharVariantCode() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final BasicAttributeMapping attribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "nclobString" );
|
||||||
|
final JdbcMapping jdbcMapping = attribute.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( String.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( nationalizationSupport.getClobVariantCode() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// and try to use the mapping
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.persist( new EntityOfStrings( 1, "nstring", "nclob" ) )
|
||||||
|
);
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.get( EntityOfStrings.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.createQuery( "delete EntityOfStrings" ).executeUpdate()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityOfStrings" )
|
||||||
|
@Table( name = "EntityOfStrings" )
|
||||||
|
public static class EntityOfStrings {
|
||||||
|
@Id
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
//tag::basic-nstring-example[]
|
||||||
|
// will be mapped using NVARCHAR
|
||||||
|
@Nationalized
|
||||||
|
String nstring;
|
||||||
|
|
||||||
|
// will be mapped using NCLOB
|
||||||
|
@Lob
|
||||||
|
@Nationalized
|
||||||
|
String nclobString;
|
||||||
|
//end::basic-nstring-example[]
|
||||||
|
|
||||||
|
public EntityOfStrings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityOfStrings(Integer id, String nstring, String nclobString) {
|
||||||
|
this.id = id;
|
||||||
|
this.nstring = nstring;
|
||||||
|
this.nclobString = nclobString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,34 +16,100 @@ import javax.persistence.Table;
|
||||||
import org.hibernate.annotations.Subselect;
|
import org.hibernate.annotations.Subselect;
|
||||||
import org.hibernate.annotations.Synchronize;
|
import org.hibernate.annotations.Synchronize;
|
||||||
import org.hibernate.dialect.DerbyDialect;
|
import org.hibernate.dialect.DerbyDialect;
|
||||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
|
||||||
|
|
||||||
import org.hibernate.testing.SkipForDialect;
|
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||||
import org.junit.Test;
|
import org.hibernate.testing.orm.junit.Jpa;
|
||||||
|
import org.hibernate.testing.orm.junit.NotImplementedYet;
|
||||||
|
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vlad Mihalcea
|
* @author Vlad Mihalcea
|
||||||
*/
|
*/
|
||||||
@SkipForDialect(value = DerbyDialect.class, comment = "Derby doesn't support a CONCAT function")
|
@Jpa(
|
||||||
public class SubselectTest extends BaseEntityManagerFunctionalTestCase {
|
annotatedClasses = {
|
||||||
|
SubselectTest.Client.class,
|
||||||
|
SubselectTest.Account.class,
|
||||||
|
SubselectTest.AccountTransaction.class,
|
||||||
|
SubselectTest.AccountSummary.class
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@SkipForDialect( dialectClass = DerbyDialect.class, reason = "Derby doesn't support a CONCAT function" )
|
||||||
|
public class SubselectTest {
|
||||||
|
|
||||||
@Override
|
@Test
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
public void testNormalLifecycle(EntityManagerFactoryScope scope) {
|
||||||
return new Class<?>[] {
|
// same as `#testRefreshLifecycle` except that here we do not rely on
|
||||||
Client.class,
|
// `Session#refresh` which atm in 6.0 dev does not appear to work properly
|
||||||
Account.class,
|
// at least in this scenario
|
||||||
AccountTransaction.class,
|
|
||||||
AccountSummary.class
|
// create the entity
|
||||||
};
|
scope.inTransaction(
|
||||||
|
(entityManager) -> {
|
||||||
|
Client client = new Client();
|
||||||
|
client.setId( 1L );
|
||||||
|
client.setFirstName( "John" );
|
||||||
|
client.setLastName( "Doe" );
|
||||||
|
entityManager.persist( client );
|
||||||
|
|
||||||
|
Account account = new Account();
|
||||||
|
account.setId( 1L );
|
||||||
|
account.setClient( client );
|
||||||
|
account.setDescription( "Checking account" );
|
||||||
|
entityManager.persist( account );
|
||||||
|
|
||||||
|
AccountTransaction transaction = new AccountTransaction();
|
||||||
|
transaction.setAccount( account );
|
||||||
|
transaction.setDescription( "Salary" );
|
||||||
|
transaction.setCents( 100 * 7000 );
|
||||||
|
entityManager.persist( transaction );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// load the entity, verify its state and add a new transaction (thereby updating the calculated balance)
|
||||||
|
scope.inTransaction(
|
||||||
|
(entityManager) -> {
|
||||||
|
AccountSummary summary = entityManager.createQuery(
|
||||||
|
"select s " +
|
||||||
|
"from AccountSummary s " +
|
||||||
|
"where s.id = :id", AccountSummary.class)
|
||||||
|
.setParameter( "id", 1L )
|
||||||
|
.getSingleResult();
|
||||||
|
|
||||||
|
assertEquals( "John Doe", summary.getClientName() );
|
||||||
|
assertEquals( 100 * 7000, summary.getBalance() );
|
||||||
|
|
||||||
|
AccountTransaction transaction = new AccountTransaction();
|
||||||
|
transaction.setAccount( entityManager.getReference( Account.class, 1L ) );
|
||||||
|
transaction.setDescription( "Shopping" );
|
||||||
|
transaction.setCents( -100 * 2200 );
|
||||||
|
entityManager.persist( transaction );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// load the AccountSummary and verify the updated balance
|
||||||
|
scope.inTransaction(
|
||||||
|
(entityManager) -> {
|
||||||
|
AccountSummary summary = entityManager.find( AccountSummary.class, 1L );
|
||||||
|
|
||||||
|
assertEquals( "John Doe", summary.getClientName() );
|
||||||
|
assertEquals( 100 * 4800, summary.getBalance() );
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLifecycle() {
|
@NotImplementedYet(
|
||||||
|
reason = "Refreshing a managed-entity does not work - https://trello.com/c/QAKC08JT/230-refresh-does-not-work-with-managed-entity-the-state-is-not-refreshed",
|
||||||
|
strict = false
|
||||||
|
)
|
||||||
|
public void testRefreshLifecycle(EntityManagerFactoryScope scope) {
|
||||||
//tag::mapping-Subselect-entity-find-example[]
|
//tag::mapping-Subselect-entity-find-example[]
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
scope.inTransaction(
|
||||||
|
(entityManager) -> {
|
||||||
Client client = new Client();
|
Client client = new Client();
|
||||||
client.setId( 1L );
|
client.setId( 1L );
|
||||||
client.setFirstName( "John" );
|
client.setFirstName( "John" );
|
||||||
|
@ -71,11 +137,13 @@ public class SubselectTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
assertEquals( "John Doe", summary.getClientName() );
|
assertEquals( "John Doe", summary.getClientName() );
|
||||||
assertEquals( 100 * 7000, summary.getBalance() );
|
assertEquals( 100 * 7000, summary.getBalance() );
|
||||||
} );
|
}
|
||||||
|
);
|
||||||
//end::mapping-Subselect-entity-find-example[]
|
//end::mapping-Subselect-entity-find-example[]
|
||||||
|
|
||||||
//tag::mapping-Subselect-entity-refresh-example[]
|
//tag::mapping-Subselect-entity-refresh-example[]
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
scope.inTransaction(
|
||||||
|
(entityManager) -> {
|
||||||
AccountSummary summary = entityManager.find( AccountSummary.class, 1L );
|
AccountSummary summary = entityManager.find( AccountSummary.class, 1L );
|
||||||
assertEquals( "John Doe", summary.getClientName() );
|
assertEquals( "John Doe", summary.getClientName() );
|
||||||
assertEquals( 100 * 7000, summary.getBalance() );
|
assertEquals( 100 * 7000, summary.getBalance() );
|
||||||
|
@ -89,11 +157,22 @@ public class SubselectTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
entityManager.refresh( summary );
|
entityManager.refresh( summary );
|
||||||
assertEquals( 100 * 4800, summary.getBalance() );
|
assertEquals( 100 * 4800, summary.getBalance() );
|
||||||
} );
|
}
|
||||||
|
);
|
||||||
//end::mapping-Subselect-entity-refresh-example[]
|
//end::mapping-Subselect-entity-refresh-example[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropTestData(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
(entityManager) -> {
|
||||||
|
entityManager.createQuery( "delete AccountTransaction" ).executeUpdate();
|
||||||
|
entityManager.createQuery( "delete Account" ).executeUpdate();
|
||||||
|
entityManager.createQuery( "delete Client" ).executeUpdate();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//tag::mapping-Subselect-example[]
|
//tag::mapping-Subselect-example[]
|
||||||
@Entity(name = "Client")
|
@Entity(name = "Client")
|
||||||
@Table(name = "client")
|
@Table(name = "client")
|
||||||
|
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = TimeZoneMappingTests.EntityWithTimeZone.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class TimeZoneMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithTimeZone.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "timeZone" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( TimeZone.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARCHAR ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithTimeZone( 1, TimeZone.getDefault() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithTimeZone.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithTimeZone" )
|
||||||
|
@Table( name = "EntityWithTimeZone" )
|
||||||
|
public static class EntityWithTimeZone {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-timeZone-example[]
|
||||||
|
// mapped as VARCHAR
|
||||||
|
private TimeZone timeZone;
|
||||||
|
//end::basic-timeZone-example[]
|
||||||
|
|
||||||
|
public EntityWithTimeZone() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithTimeZone(Integer id, TimeZone timeZone) {
|
||||||
|
this.id = id;
|
||||||
|
this.timeZone = timeZone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = ZoneOffsetMappingTests.EntityWithZoneOffset.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class ZoneOffsetMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithZoneOffset.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "zoneOffset" );
|
||||||
|
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( ZoneOffset.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), equalTo( Types.VARCHAR ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithZoneOffset( 1, ZoneOffset.from( ZoneOffset.MIN ) ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithZoneOffset.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithZoneOffset" )
|
||||||
|
@Table( name = "EntityWithZoneOffset" )
|
||||||
|
public static class EntityWithZoneOffset {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-ZoneOffset-example[]
|
||||||
|
// mapped as VARCHAR
|
||||||
|
private ZoneOffset zoneOffset;
|
||||||
|
//end::basic-ZoneOffset-example[]
|
||||||
|
|
||||||
|
public EntityWithZoneOffset() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithZoneOffset(Integer id, ZoneOffset zoneOffset) {
|
||||||
|
this.id = id;
|
||||||
|
this.zoneOffset = zoneOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.userguide.mapping.basic;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MappingMetamodel;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
|
||||||
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@DomainModel( annotatedClasses = ZonedDateTimeMappingTests.EntityWithZonedDateTime.class )
|
||||||
|
@SessionFactory
|
||||||
|
public class ZonedDateTimeMappingTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyMappings(SessionFactoryScope scope) {
|
||||||
|
final MappingMetamodel domainModel = scope.getSessionFactory().getDomainModel();
|
||||||
|
final EntityPersister entityDescriptor = domainModel.findEntityDescriptor( EntityWithZonedDateTime.class );
|
||||||
|
|
||||||
|
final BasicAttributeMapping attributeMapping = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "zonedDateTime" );
|
||||||
|
final JdbcMapping jdbcMapping = attributeMapping.getJdbcMapping();
|
||||||
|
assertThat( jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo( ZonedDateTime.class ) );
|
||||||
|
assertThat( jdbcMapping.getJdbcTypeDescriptor().getJdbcTypeCode(), isOneOf( Types.TIMESTAMP, Types.TIMESTAMP_WITH_TIMEZONE ) );
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.persist( new EntityWithZonedDateTime( 1, ZonedDateTime.now() ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.inTransaction(
|
||||||
|
(session) -> session.find( EntityWithZonedDateTime.class, 1 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity( name = "EntityWithZonedDateTime" )
|
||||||
|
@Table( name = "EntityWithZonedDateTime" )
|
||||||
|
public static class EntityWithZonedDateTime {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
//tag::basic-ZonedDateTime-example[]
|
||||||
|
// mapped as TIMESTAMP or TIMESTAMP_WITH_TIMEZONE
|
||||||
|
private ZonedDateTime zonedDateTime;
|
||||||
|
//end::basic-ZonedDateTime-example[]
|
||||||
|
|
||||||
|
public EntityWithZonedDateTime() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityWithZonedDateTime(Integer id, ZonedDateTime zonedDateTime) {
|
||||||
|
this.id = id;
|
||||||
|
this.zonedDateTime = zonedDateTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -344,7 +344,7 @@ class Antlr4Plugin implements Plugin<Project> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Antlr4GenerationTask extends DefaultTask {
|
abstract class Antlr4GenerationTask extends DefaultTask {
|
||||||
static final String HQL_PCKG = 'org.hibernate.grammars.hql'
|
static final String HQL_PCKG = 'org.hibernate.grammars.hql'
|
||||||
static final String IMPORT_SQL_PCKG = 'org.hibernate.grammars.importsql'
|
static final String IMPORT_SQL_PCKG = 'org.hibernate.grammars.importsql'
|
||||||
static final String GRAPH_PCKG = 'org.hibernate.grammars.graph'
|
static final String GRAPH_PCKG = 'org.hibernate.grammars.graph'
|
||||||
|
|
|
@ -9,13 +9,26 @@ package org.hibernate.annotations;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.FIELD;
|
import static java.lang.annotation.ElementType.FIELD;
|
||||||
import static java.lang.annotation.ElementType.METHOD;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks a character data type (String, Character, character, Clob) as being a nationalized variant
|
* Used to indicate that the annotated character data should be stored with
|
||||||
* (NVARCHAR, NCHAR, NCLOB, etc).
|
* nationalization support.
|
||||||
|
*
|
||||||
|
* The annotation's affect depends on {@link Dialect#getNationalizationSupport()}
|
||||||
|
*
|
||||||
|
* Some databases support storing nationalized data in their "normal" character data types
|
||||||
|
* (CHAR, VARCHAR, LONGVARCHAR, CLOB). In such cases this annotation is effectively ignored.
|
||||||
|
* See {@link org.hibernate.dialect.NationalizationSupport#IMPLICIT}
|
||||||
|
*
|
||||||
|
* Some databases support storing nationalized data only through the specialized, standard SQL
|
||||||
|
* variants (NCHAR, NVARCHAR, LONGNVARCHAR, NCLOB). In such cases this annotation will adjust
|
||||||
|
* the JDBC type code to the specialized variant. See
|
||||||
|
* {@link org.hibernate.dialect.NationalizationSupport#EXPLICIT}
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.boot.model.process.internal;
|
package org.hibernate.boot.model.process.internal;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
|
@ -19,10 +20,10 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter;
|
import org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter;
|
||||||
import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter;
|
import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter;
|
||||||
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
|
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
|
||||||
|
import org.hibernate.type.AdjustableBasicType;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.CustomType;
|
import org.hibernate.type.CustomType;
|
||||||
import org.hibernate.type.SerializableType;
|
import org.hibernate.type.SerializableType;
|
||||||
import org.hibernate.type.SqlTypeDescriptorIndicatorCapable;
|
|
||||||
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
|
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
|
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
|
||||||
|
@ -31,6 +32,7 @@ import org.hibernate.type.descriptor.java.SerializableTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.TemporalJavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.TemporalJavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.ObjectJdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.TinyIntTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.TinyIntTypeDescriptor;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
@ -76,23 +78,57 @@ public class InferredBasicValueResolver {
|
||||||
explicitJavaType,
|
explicitJavaType,
|
||||||
explicitJdbcType
|
explicitJdbcType
|
||||||
);
|
);
|
||||||
|
legacyType = jdbcMapping;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// infer the STD
|
// we need to infer the JdbcTypeDescriptor and use that to build the value-mapping
|
||||||
final JdbcTypeDescriptor inferredJdbcType = explicitJavaType.getRecommendedJdbcType( stdIndicators );
|
final JdbcTypeDescriptor inferredJdbcType = explicitJavaType.getRecommendedJdbcType( stdIndicators );
|
||||||
|
if ( inferredJdbcType instanceof ObjectJdbcTypeDescriptor ) {
|
||||||
|
// have a "fallback" JDBC type... see if we can decide a better choice
|
||||||
|
|
||||||
|
if ( explicitJavaType instanceof EnumJavaTypeDescriptor ) {
|
||||||
|
return fromEnum(
|
||||||
|
(EnumJavaTypeDescriptor) reflectedJtd,
|
||||||
|
explicitJavaType,
|
||||||
|
null,
|
||||||
|
stdIndicators,
|
||||||
|
typeConfiguration
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( explicitJavaType instanceof TemporalJavaTypeDescriptor ) {
|
||||||
|
return fromTemporal(
|
||||||
|
(TemporalJavaTypeDescriptor) reflectedJtd,
|
||||||
|
explicitJavaType,
|
||||||
|
null,
|
||||||
|
stdIndicators,
|
||||||
|
typeConfiguration
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( explicitJavaType instanceof SerializableTypeDescriptor || explicitJavaType.getJavaType() instanceof Serializable ) {
|
||||||
|
legacyType = new SerializableType<>( explicitJavaType );
|
||||||
|
jdbcMapping = legacyType;
|
||||||
|
}
|
||||||
|
else {
|
||||||
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
|
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
explicitJavaType,
|
explicitJavaType,
|
||||||
inferredJdbcType
|
inferredJdbcType
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
legacyType = jdbcMapping;
|
legacyType = jdbcMapping;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
explicitJavaType,
|
||||||
|
inferredJdbcType
|
||||||
|
);
|
||||||
|
legacyType = jdbcMapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if ( reflectedJtd != null ) {
|
else if ( reflectedJtd != null ) {
|
||||||
// we were able to determine the "reflected java-type"
|
// we were able to determine the "reflected java-type"
|
||||||
|
|
||||||
if ( explicitJdbcType != null ) {
|
if ( explicitJdbcType != null ) {
|
||||||
// we also have an explicit @SqlType(Code)
|
// we also have an explicit @JdbcType(Code)
|
||||||
|
|
||||||
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
|
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
reflectedJtd,
|
reflectedJtd,
|
||||||
|
@ -107,8 +143,8 @@ public class InferredBasicValueResolver {
|
||||||
if ( reflectedJtd instanceof EnumJavaTypeDescriptor ) {
|
if ( reflectedJtd instanceof EnumJavaTypeDescriptor ) {
|
||||||
return fromEnum(
|
return fromEnum(
|
||||||
(EnumJavaTypeDescriptor) reflectedJtd,
|
(EnumJavaTypeDescriptor) reflectedJtd,
|
||||||
explicitJavaTypeAccess.apply( typeConfiguration ),
|
null,
|
||||||
explicitSqlTypeAccess.apply( typeConfiguration ),
|
null,
|
||||||
stdIndicators,
|
stdIndicators,
|
||||||
typeConfiguration
|
typeConfiguration
|
||||||
);
|
);
|
||||||
|
@ -116,8 +152,8 @@ public class InferredBasicValueResolver {
|
||||||
else if ( reflectedJtd instanceof TemporalJavaTypeDescriptor ) {
|
else if ( reflectedJtd instanceof TemporalJavaTypeDescriptor ) {
|
||||||
return fromTemporal(
|
return fromTemporal(
|
||||||
(TemporalJavaTypeDescriptor) reflectedJtd,
|
(TemporalJavaTypeDescriptor) reflectedJtd,
|
||||||
explicitJavaTypeAccess,
|
null,
|
||||||
explicitSqlTypeAccess,
|
null,
|
||||||
stdIndicators,
|
stdIndicators,
|
||||||
typeConfiguration
|
typeConfiguration
|
||||||
);
|
);
|
||||||
|
@ -128,12 +164,11 @@ public class InferredBasicValueResolver {
|
||||||
final BasicType registeredType = typeConfiguration.getBasicTypeRegistry().getRegisteredType( reflectedJtd.getJavaType() );
|
final BasicType registeredType = typeConfiguration.getBasicTypeRegistry().getRegisteredType( reflectedJtd.getJavaType() );
|
||||||
|
|
||||||
if ( registeredType != null ) {
|
if ( registeredType != null ) {
|
||||||
// reuse the "legacy type"
|
legacyType = resolveSqlTypeIndicators( stdIndicators, registeredType, reflectedJtd );
|
||||||
legacyType = resolveSqlTypeIndicators( stdIndicators, registeredType );
|
|
||||||
jdbcMapping = legacyType;
|
jdbcMapping = legacyType;
|
||||||
}
|
}
|
||||||
else if ( reflectedJtd instanceof SerializableTypeDescriptor ) {
|
else if ( reflectedJtd instanceof SerializableTypeDescriptor || reflectedJtd.getJavaType() instanceof Serializable ) {
|
||||||
legacyType = new SerializableType<>( reflectedJtd.getJavaTypeClass() );
|
legacyType = new SerializableType<>( reflectedJtd );
|
||||||
jdbcMapping = legacyType;
|
jdbcMapping = legacyType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -154,7 +189,7 @@ public class InferredBasicValueResolver {
|
||||||
explicitJdbcType
|
explicitJdbcType
|
||||||
);
|
);
|
||||||
|
|
||||||
jdbcMapping = resolveSqlTypeIndicators( stdIndicators, resolved );
|
jdbcMapping = resolveSqlTypeIndicators( stdIndicators, resolved, recommendedJtd );
|
||||||
legacyType = jdbcMapping;
|
legacyType = jdbcMapping;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -193,10 +228,11 @@ public class InferredBasicValueResolver {
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public static BasicType<?> resolveSqlTypeIndicators(
|
public static BasicType<?> resolveSqlTypeIndicators(
|
||||||
JdbcTypeDescriptorIndicators stdIndicators,
|
JdbcTypeDescriptorIndicators stdIndicators,
|
||||||
BasicType<?> resolved) {
|
BasicType<?> resolved,
|
||||||
if ( resolved instanceof SqlTypeDescriptorIndicatorCapable ) {
|
JavaTypeDescriptor<?> domainJtd) {
|
||||||
final SqlTypeDescriptorIndicatorCapable indicatorCapable = (SqlTypeDescriptorIndicatorCapable) resolved;
|
if ( resolved instanceof AdjustableBasicType ) {
|
||||||
final BasicType indicatedType = indicatorCapable.resolveIndicatedType( stdIndicators );
|
final AdjustableBasicType indicatorCapable = (AdjustableBasicType) resolved;
|
||||||
|
final BasicType indicatedType = indicatorCapable.resolveIndicatedType( stdIndicators, domainJtd );
|
||||||
return indicatedType != null ? indicatedType : resolved;
|
return indicatedType != null ? indicatedType : resolved;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -322,28 +358,12 @@ public class InferredBasicValueResolver {
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
public static InferredBasicValueResolution fromTemporal(
|
public static InferredBasicValueResolution fromTemporal(
|
||||||
TemporalJavaTypeDescriptor reflectedJtd,
|
TemporalJavaTypeDescriptor reflectedJtd,
|
||||||
Function<TypeConfiguration, BasicJavaDescriptor> explicitJavaTypeAccess,
|
BasicJavaDescriptor explicitJavaType,
|
||||||
Function<TypeConfiguration, JdbcTypeDescriptor> explicitSqlTypeAccess,
|
JdbcTypeDescriptor explicitJdbcType,
|
||||||
JdbcTypeDescriptorIndicators stdIndicators,
|
JdbcTypeDescriptorIndicators stdIndicators,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
final TemporalType requestedTemporalPrecision = stdIndicators.getTemporalPrecision();
|
final TemporalType requestedTemporalPrecision = stdIndicators.getTemporalPrecision();
|
||||||
|
|
||||||
final JavaTypeDescriptor explicitJavaType;
|
|
||||||
if ( explicitJavaTypeAccess != null ) {
|
|
||||||
explicitJavaType = explicitJavaTypeAccess.apply( typeConfiguration );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
explicitJavaType = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final JdbcTypeDescriptor explicitJdbcType;
|
|
||||||
if ( explicitSqlTypeAccess != null ) {
|
|
||||||
explicitJdbcType = explicitSqlTypeAccess.apply( typeConfiguration );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
explicitJdbcType = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Case #1 - @JavaType
|
// Case #1 - @JavaType
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,10 @@ import org.hibernate.engine.config.spi.StandardConverters;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.BasicTypeRegistry;
|
import org.hibernate.type.BasicTypeRegistry;
|
||||||
|
import org.hibernate.type.CustomType;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypedExpressable;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import org.hibernate.usertype.UserType;
|
import org.hibernate.usertype.UserType;
|
||||||
|
@ -355,16 +358,33 @@ public class MetadataBuildingProcess {
|
||||||
@Override
|
@Override
|
||||||
public void contributeType(org.hibernate.type.BasicType type) {
|
public void contributeType(org.hibernate.type.BasicType type) {
|
||||||
getBasicTypeRegistry().register( type );
|
getBasicTypeRegistry().register( type );
|
||||||
|
|
||||||
|
final JavaTypeDescriptor<?> jtd;
|
||||||
|
if ( type instanceof CustomType ) {
|
||||||
|
final CustomType customType = (CustomType) type;
|
||||||
|
jtd = customType.getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jtd = type.getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
conditionallyRegisterJtd( jtd );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void conditionallyRegisterJtd(JavaTypeDescriptor jtd) {
|
||||||
|
final JavaTypeDescriptorRegistry jtdRegistry = getTypeConfiguration().getJavaTypeDescriptorRegistry();
|
||||||
|
jtdRegistry.resolveDescriptor( jtd.getJavaTypeClass(), () -> jtd );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contributeType(BasicType type, String... keys) {
|
public void contributeType(BasicType type, String... keys) {
|
||||||
getBasicTypeRegistry().register( type, keys );
|
getBasicTypeRegistry().register( type, keys );
|
||||||
|
conditionallyRegisterJtd( type.getJavaTypeDescriptor() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contributeType(UserType type, String[] keys) {
|
public void contributeType(UserType type, String[] keys) {
|
||||||
getBasicTypeRegistry().register( type, keys );
|
contributeType( new CustomType( type, keys, getTypeConfiguration() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -383,7 +403,7 @@ public class MetadataBuildingProcess {
|
||||||
}
|
}
|
||||||
|
|
||||||
final BasicTypeRegistry getBasicTypeRegistry() {
|
final BasicTypeRegistry getBasicTypeRegistry() {
|
||||||
return bootstrapContext.getTypeConfiguration().getBasicTypeRegistry();
|
return getTypeConfiguration().getBasicTypeRegistry();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,8 @@ import org.hibernate.MappingException;
|
||||||
import org.hibernate.annotations.CollectionId;
|
import org.hibernate.annotations.CollectionId;
|
||||||
import org.hibernate.annotations.Immutable;
|
import org.hibernate.annotations.Immutable;
|
||||||
import org.hibernate.annotations.JavaType;
|
import org.hibernate.annotations.JavaType;
|
||||||
|
import org.hibernate.annotations.JdbcType;
|
||||||
|
import org.hibernate.annotations.JdbcTypeCode;
|
||||||
import org.hibernate.annotations.MapKeyJavaType;
|
import org.hibernate.annotations.MapKeyJavaType;
|
||||||
import org.hibernate.annotations.MapKeyJdbcType;
|
import org.hibernate.annotations.MapKeyJdbcType;
|
||||||
import org.hibernate.annotations.MapKeyJdbcTypeCode;
|
import org.hibernate.annotations.MapKeyJdbcTypeCode;
|
||||||
|
@ -33,8 +35,6 @@ import org.hibernate.annotations.MapKeyType;
|
||||||
import org.hibernate.annotations.Mutability;
|
import org.hibernate.annotations.Mutability;
|
||||||
import org.hibernate.annotations.Nationalized;
|
import org.hibernate.annotations.Nationalized;
|
||||||
import org.hibernate.annotations.Parameter;
|
import org.hibernate.annotations.Parameter;
|
||||||
import org.hibernate.annotations.JdbcType;
|
|
||||||
import org.hibernate.annotations.JdbcTypeCode;
|
|
||||||
import org.hibernate.annotations.Type;
|
import org.hibernate.annotations.Type;
|
||||||
import org.hibernate.annotations.common.reflection.XClass;
|
import org.hibernate.annotations.common.reflection.XClass;
|
||||||
import org.hibernate.annotations.common.reflection.XProperty;
|
import org.hibernate.annotations.common.reflection.XProperty;
|
||||||
|
@ -49,6 +49,7 @@ import org.hibernate.cfg.NotYetImplementedException;
|
||||||
import org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass;
|
import org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass;
|
||||||
import org.hibernate.cfg.SetBasicValueTypeSecondPass;
|
import org.hibernate.cfg.SetBasicValueTypeSecondPass;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.NationalizationSupport;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
@ -256,7 +257,7 @@ public class BasicValueBinder<T> implements JdbcTypeDescriptorIndicators {
|
||||||
isLob = modelXProperty.isAnnotationPresent( Lob.class );
|
isLob = modelXProperty.isAnnotationPresent( Lob.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( getDialect().supportsNationalizedTypes() ) {
|
if ( getDialect().getNationalizationSupport() == NationalizationSupport.EXPLICIT ) {
|
||||||
isNationalized = modelXProperty.isAnnotationPresent( Nationalized.class )
|
isNationalized = modelXProperty.isAnnotationPresent( Nationalized.class )
|
||||||
|| buildingContext.getBuildingOptions().useNationalizedCharacterData();
|
|| buildingContext.getBuildingOptions().useNationalizedCharacterData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,8 +234,9 @@ public class CockroachDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsNationalizedTypes() {
|
public NationalizationSupport getNationalizationSupport() {
|
||||||
return false;
|
// TEXT / STRING inherently support nationalized data
|
||||||
|
return NationalizationSupport.IMPLICIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -74,6 +74,7 @@ public class DerbyDialect extends Dialect {
|
||||||
|
|
||||||
// KNOWN LIMITATIONS:
|
// KNOWN LIMITATIONS:
|
||||||
|
|
||||||
|
// no support for nationalized data (nchar, nvarchar, nclob)
|
||||||
// * limited set of fields for extract()
|
// * limited set of fields for extract()
|
||||||
// (no 'day of xxxx', nor 'week of xxxx')
|
// (no 'day of xxxx', nor 'week of xxxx')
|
||||||
// * no support for format()
|
// * no support for format()
|
||||||
|
@ -160,6 +161,11 @@ public class DerbyDialect extends Dialect {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NationalizationSupport getNationalizationSupport() {
|
||||||
|
return NationalizationSupport.IMPLICIT;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getFloatPrecision() {
|
public int getFloatPrecision() {
|
||||||
return 23;
|
return 23;
|
||||||
|
|
|
@ -82,6 +82,10 @@ import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.LongNVarcharTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.NCharTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.NClobTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.NVarcharTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
@ -958,7 +962,15 @@ public abstract class Dialect implements ConversionContext {
|
||||||
* @param serviceRegistry The service registry
|
* @param serviceRegistry The service registry
|
||||||
*/
|
*/
|
||||||
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||||
// by default, nothing to do
|
// by default, not much to do...
|
||||||
|
|
||||||
|
final NationalizationSupport nationalizationSupport = getNationalizationSupport();
|
||||||
|
if ( nationalizationSupport == NationalizationSupport.EXPLICIT ) {
|
||||||
|
typeContributions.contributeJdbcTypeDescriptor( NCharTypeDescriptor.INSTANCE );
|
||||||
|
typeContributions.contributeJdbcTypeDescriptor( NVarcharTypeDescriptor.INSTANCE );
|
||||||
|
typeContributions.contributeJdbcTypeDescriptor( LongNVarcharTypeDescriptor.INSTANCE );
|
||||||
|
typeContributions.contributeJdbcTypeDescriptor( NClobTypeDescriptor.DEFAULT );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static interface Initializable {
|
// public static interface Initializable {
|
||||||
|
@ -3441,9 +3453,18 @@ public abstract class Dialect implements ConversionContext {
|
||||||
* Does this dialect supports Nationalized Types
|
* Does this dialect supports Nationalized Types
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
|
*
|
||||||
|
* @deprecated (since 6.0) Prefer {@link #getNationalizationSupport()} which gives a little
|
||||||
|
* better insight into what is supported. This is interpreted as true if the supported
|
||||||
|
* strategy is {@link NationalizationSupport#EXPLICIT}
|
||||||
*/
|
*/
|
||||||
public boolean supportsNationalizedTypes() {
|
@Deprecated
|
||||||
return true;
|
public final boolean supportsNationalizedTypes() {
|
||||||
|
return getNationalizationSupport() == NationalizationSupport.EXPLICIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NationalizationSupport getNationalizationSupport() {
|
||||||
|
return NationalizationSupport.EXPLICIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* 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.dialect;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates how (if) the underlying database supports the use of nationalized data
|
||||||
|
*/
|
||||||
|
public enum NationalizationSupport {
|
||||||
|
/**
|
||||||
|
* The database's CHAR, VARCHAR, LONGVARCHAR and CLOB types
|
||||||
|
* inherently handle nationalized data. Generally speaking
|
||||||
|
* this means the database will not have dedicated nationalized
|
||||||
|
* data types (NCHAR, ...)
|
||||||
|
*/
|
||||||
|
IMPLICIT( Types.CHAR, Types.VARCHAR, Types.LONGVARCHAR, Types.CLOB ),
|
||||||
|
/**
|
||||||
|
* The database does define/support distinct nationalized
|
||||||
|
* data types (NCHAR, ...).
|
||||||
|
*/
|
||||||
|
EXPLICIT( Types.NCHAR, Types.NVARCHAR, Types.LONGNVARCHAR, Types.NCLOB ),
|
||||||
|
/**
|
||||||
|
* The database does not define/support distinct nationalized
|
||||||
|
* data types (NCHAR, ...) and its corresponding base data
|
||||||
|
* types (CHAR, ...) do not support nationalized data
|
||||||
|
*/
|
||||||
|
UNSUPPORTED;
|
||||||
|
|
||||||
|
private final int charVariantCode;
|
||||||
|
private final int varcharVariantCode;
|
||||||
|
private final int longVarcharVariantCode;
|
||||||
|
private final int clobVariantCode;
|
||||||
|
|
||||||
|
NationalizationSupport() {
|
||||||
|
this( -1, -1, -1, -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
NationalizationSupport(
|
||||||
|
int charVariantCode,
|
||||||
|
int varcharVariantCode,
|
||||||
|
int longVarcharVariantCode,
|
||||||
|
int clobVariantCode) {
|
||||||
|
this.charVariantCode = charVariantCode;
|
||||||
|
this.varcharVariantCode = varcharVariantCode;
|
||||||
|
this.longVarcharVariantCode = longVarcharVariantCode;
|
||||||
|
this.clobVariantCode = clobVariantCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCharVariantCode() {
|
||||||
|
return charVariantCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVarcharVariantCode() {
|
||||||
|
return varcharVariantCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLongVarcharVariantCode() {
|
||||||
|
return longVarcharVariantCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClobVariantCode() {
|
||||||
|
return clobVariantCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -658,8 +658,8 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsNationalizedTypes() {
|
public NationalizationSupport getNationalizationSupport() {
|
||||||
return false;
|
return NationalizationSupport.IMPLICIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,7 +14,6 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import javax.persistence.AttributeConverter;
|
import javax.persistence.AttributeConverter;
|
||||||
|
@ -52,9 +51,9 @@ import org.hibernate.type.descriptor.JdbcTypeNameMapper;
|
||||||
import org.hibernate.type.descriptor.converter.AttributeConverterJdbcTypeDescriptorAdapter;
|
import org.hibernate.type.descriptor.converter.AttributeConverterJdbcTypeDescriptorAdapter;
|
||||||
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
|
import org.hibernate.type.descriptor.converter.AttributeConverterTypeAdapter;
|
||||||
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
|
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.LobTypeMappings;
|
import org.hibernate.type.descriptor.jdbc.LobTypeMappings;
|
||||||
import org.hibernate.type.descriptor.jdbc.NationalizedTypeMappings;
|
import org.hibernate.type.descriptor.jdbc.NationalizedTypeMappings;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import org.hibernate.usertype.DynamicParameterizedType;
|
import org.hibernate.usertype.DynamicParameterizedType;
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,14 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.named.ResultMementoBasic;
|
import org.hibernate.query.named.ResultMementoBasic;
|
||||||
import org.hibernate.query.results.ResultBuilderBasicValued;
|
import org.hibernate.query.results.ResultBuilderBasicValued;
|
||||||
import org.hibernate.query.results.complete.CompleteResultBuilderBasicValuedStandard;
|
import org.hibernate.query.results.complete.CompleteResultBuilderBasicValuedStandard;
|
||||||
|
import org.hibernate.resource.beans.spi.ManagedBean;
|
||||||
|
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
|
import org.hibernate.type.CustomType;
|
||||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
import org.hibernate.usertype.UserType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ResultMappingMemento for scalar (basic) results.
|
* Implementation of ResultMappingMemento for scalar (basic) results.
|
||||||
|
@ -60,6 +64,8 @@ public class ResultMementoBasicStandard implements ResultMementoBasic {
|
||||||
ResultSetMappingResolutionContext context) {
|
ResultSetMappingResolutionContext context) {
|
||||||
this.explicitColumnName = definition.name();
|
this.explicitColumnName = definition.name();
|
||||||
|
|
||||||
|
BasicType resolvedBasicType = null;
|
||||||
|
|
||||||
final Class<?> definedType = definition.type();
|
final Class<?> definedType = definition.type();
|
||||||
if ( void.class == definedType ) {
|
if ( void.class == definedType ) {
|
||||||
explicitJavaTypeDescriptor = null;
|
explicitJavaTypeDescriptor = null;
|
||||||
|
@ -67,11 +73,35 @@ public class ResultMementoBasicStandard implements ResultMementoBasic {
|
||||||
else {
|
else {
|
||||||
final SessionFactoryImplementor sessionFactory = context.getSessionFactory();
|
final SessionFactoryImplementor sessionFactory = context.getSessionFactory();
|
||||||
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
||||||
|
|
||||||
|
// first see if this is a registered BasicType...
|
||||||
|
final BasicType<Object> registeredBasicType = typeConfiguration.getBasicTypeRegistry()
|
||||||
|
.getRegisteredType( definition.type().getName() );
|
||||||
|
if ( registeredBasicType != null ) {
|
||||||
|
this.explicitJavaTypeDescriptor = registeredBasicType.getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
else {
|
||||||
final JavaTypeDescriptorRegistry jtdRegistry = typeConfiguration.getJavaTypeDescriptorRegistry();
|
final JavaTypeDescriptorRegistry jtdRegistry = typeConfiguration.getJavaTypeDescriptorRegistry();
|
||||||
|
final JavaTypeDescriptor<Object> registeredJtd = jtdRegistry.getDescriptor( definition.type() );
|
||||||
|
final ManagedBeanRegistry beanRegistry = sessionFactory.getServiceRegistry().getService( ManagedBeanRegistry.class );
|
||||||
|
if ( BasicType.class.isAssignableFrom( registeredJtd.getJavaTypeClass() ) ) {
|
||||||
|
final ManagedBean<BasicType<?>> typeBean = (ManagedBean) beanRegistry.getBean( registeredJtd.getJavaTypeClass() );
|
||||||
|
resolvedBasicType = typeBean.getBeanInstance();
|
||||||
|
this.explicitJavaTypeDescriptor = resolvedBasicType.getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
else if ( UserType.class.isAssignableFrom( registeredJtd.getJavaTypeClass() ) ) {
|
||||||
|
final ManagedBean<UserType<?>> userTypeBean = (ManagedBean) beanRegistry.getBean( registeredJtd.getJavaTypeClass() );
|
||||||
|
// todo (6.0) : is this the best approach? or should we keep a Class<? extends UserType> -> CustomType mapping somewhere?
|
||||||
|
resolvedBasicType = new CustomType( userTypeBean.getBeanInstance(), sessionFactory.getTypeConfiguration() );
|
||||||
|
this.explicitJavaTypeDescriptor = resolvedBasicType.getJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
else {
|
||||||
this.explicitJavaTypeDescriptor = jtdRegistry.getDescriptor( definition.type() );
|
this.explicitJavaTypeDescriptor = jtdRegistry.getDescriptor( definition.type() );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
explicitType = null;
|
explicitType = resolvedBasicType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultMementoBasicStandard(
|
public ResultMementoBasicStandard(
|
||||||
|
|
|
@ -41,6 +41,11 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
||||||
String explicitColumnName,
|
String explicitColumnName,
|
||||||
BasicValuedMapping explicitType,
|
BasicValuedMapping explicitType,
|
||||||
JavaTypeDescriptor<?> explicitJavaTypeDescriptor) {
|
JavaTypeDescriptor<?> explicitJavaTypeDescriptor) {
|
||||||
|
assert explicitType == null || explicitType.getJdbcMapping()
|
||||||
|
.getJavaTypeDescriptor()
|
||||||
|
.getJavaTypeClass()
|
||||||
|
.isAssignableFrom( explicitJavaTypeDescriptor.getJavaTypeClass() );
|
||||||
|
|
||||||
this.explicitColumnName = explicitColumnName;
|
this.explicitColumnName = explicitColumnName;
|
||||||
this.explicitType = explicitType;
|
this.explicitType = explicitType;
|
||||||
this.explicitJavaTypeDescriptor = explicitJavaTypeDescriptor;
|
this.explicitJavaTypeDescriptor = explicitJavaTypeDescriptor;
|
||||||
|
@ -63,6 +68,35 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
||||||
columnName = jdbcResultsMetadata.resolveColumnName( resultPosition + 1 );
|
columnName = jdbcResultsMetadata.resolveColumnName( resultPosition + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// final int jdbcPosition;
|
||||||
|
// if ( explicitColumnName != null ) {
|
||||||
|
// jdbcPosition = jdbcResultsMetadata.resolveColumnPosition( explicitColumnName );
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// jdbcPosition = resultPosition + 1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final BasicValuedMapping basicType;
|
||||||
|
// if ( explicitType != null ) {
|
||||||
|
// basicType = explicitType;
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// basicType = jdbcResultsMetadata.resolveType( jdbcPosition, explicitJavaTypeDescriptor );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final SqlSelection sqlSelection = creationStateImpl.resolveSqlSelection(
|
||||||
|
// creationStateImpl.resolveSqlExpression(
|
||||||
|
// columnName,
|
||||||
|
// processingState -> {
|
||||||
|
// final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||||
|
// return new SqlSelectionImpl( valuesArrayPosition, basicType );
|
||||||
|
// }
|
||||||
|
// ),
|
||||||
|
// basicType.getExpressableJavaTypeDescriptor(),
|
||||||
|
// sessionFactory.getTypeConfiguration()
|
||||||
|
// );
|
||||||
|
|
||||||
|
|
||||||
final SqlSelection sqlSelection = creationStateImpl.resolveSqlSelection(
|
final SqlSelection sqlSelection = creationStateImpl.resolveSqlSelection(
|
||||||
creationStateImpl.resolveSqlExpression(
|
creationStateImpl.resolveSqlExpression(
|
||||||
columnName,
|
columnName,
|
||||||
|
@ -74,7 +108,6 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
||||||
else {
|
else {
|
||||||
jdbcPosition = resultPosition + 1;
|
jdbcPosition = resultPosition + 1;
|
||||||
}
|
}
|
||||||
final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition );
|
|
||||||
|
|
||||||
final BasicValuedMapping basicType;
|
final BasicValuedMapping basicType;
|
||||||
if ( explicitType != null ) {
|
if ( explicitType != null ) {
|
||||||
|
@ -83,6 +116,8 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
||||||
else {
|
else {
|
||||||
basicType = jdbcResultsMetadata.resolveType( jdbcPosition, explicitJavaTypeDescriptor );
|
basicType = jdbcResultsMetadata.resolveType( jdbcPosition, explicitJavaTypeDescriptor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||||
return new SqlSelectionImpl( valuesArrayPosition, basicType );
|
return new SqlSelectionImpl( valuesArrayPosition, basicType );
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
|
@ -2351,7 +2351,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
getFromClauseAccess()::findTableGroup
|
getFromClauseAccess()::findTableGroup
|
||||||
);
|
);
|
||||||
if ( localExpressable instanceof BasicType<?> ) {
|
if ( localExpressable instanceof BasicType<?> ) {
|
||||||
expressable = InferredBasicValueResolver.resolveSqlTypeIndicators( this, (BasicType<?>) localExpressable );
|
expressable = InferredBasicValueResolver.resolveSqlTypeIndicators(
|
||||||
|
this,
|
||||||
|
(BasicType<?>) localExpressable,
|
||||||
|
literal.getJavaTypeDescriptor()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
expressable = localExpressable;
|
expressable = localExpressable;
|
||||||
|
@ -2761,7 +2765,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
public Object visitCastTarget(SqmCastTarget target) {
|
public Object visitCastTarget(SqmCastTarget target) {
|
||||||
BasicValuedMapping targetType = (BasicValuedMapping) target.getType();
|
BasicValuedMapping targetType = (BasicValuedMapping) target.getType();
|
||||||
if ( targetType instanceof BasicType<?> ) {
|
if ( targetType instanceof BasicType<?> ) {
|
||||||
targetType = InferredBasicValueResolver.resolveSqlTypeIndicators( this, (BasicType<?>) targetType );
|
targetType = InferredBasicValueResolver.resolveSqlTypeIndicators(
|
||||||
|
this,
|
||||||
|
(BasicType<?>) targetType,
|
||||||
|
target.getNodeJavaTypeDescriptor()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return new CastTarget(
|
return new CastTarget(
|
||||||
targetType.getJdbcMapping(),
|
targetType.getJdbcMapping(),
|
||||||
|
|
|
@ -72,12 +72,12 @@ public abstract class AbstractStandardBasicType<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValueExtractor getJdbcValueExtractor() {
|
public ValueExtractor<T> getJdbcValueExtractor() {
|
||||||
return jdbcValueExtractor;
|
return jdbcValueExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValueBinder getJdbcValueBinder() {
|
public ValueBinder<T> getJdbcValueBinder() {
|
||||||
return jdbcValueBinder;
|
return jdbcValueBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,17 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* Extension contract for BasicType implementations that understand how to
|
||||||
|
* adjust themselves relative to where/how they are used (e.g. accounting
|
||||||
|
* for LOB, nationalized, primitive/wrapper, etc).
|
||||||
*/
|
*/
|
||||||
public interface SqlTypeDescriptorIndicatorCapable<J> extends BasicType<J> {
|
public interface AdjustableBasicType<J> extends BasicType<J> {
|
||||||
/**
|
/**
|
||||||
* For Types whose resolution can be affected by SqlTypeDescriptorIndicators
|
* Perform the adjustment
|
||||||
*/
|
*/
|
||||||
<X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators);
|
<X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators, JavaTypeDescriptor<X> domainJtd);
|
||||||
}
|
}
|
|
@ -48,6 +48,8 @@ public interface BasicType<T> extends Type, BasicDomainType<T>, MappingType, Bas
|
||||||
return getJavaTypeDescriptor();
|
return getJavaTypeDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default int forEachJdbcType(IndexedConsumer<JdbcMapping> action) {
|
default int forEachJdbcType(IndexedConsumer<JdbcMapping> action) {
|
||||||
action.accept( 0, this );
|
action.accept( 0, this );
|
||||||
|
|
|
@ -50,6 +50,11 @@ public class BasicTypeRegistry implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public <J> BasicType<J> getRegisteredType(java.lang.reflect.Type javaType) {
|
public <J> BasicType<J> getRegisteredType(java.lang.reflect.Type javaType) {
|
||||||
|
if ( javaType instanceof Class ) {
|
||||||
|
// using `javaType.getTypeName()` causes problems with arrays
|
||||||
|
//noinspection unchecked
|
||||||
|
return getRegisteredType( (Class<J>) javaType );
|
||||||
|
}
|
||||||
return getRegisteredType( javaType.getTypeName() );
|
return getRegisteredType( javaType.getTypeName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,17 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
|
import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between a {@link java.sql.Types#VARBINARY VARBINARY} and {@code byte[]}
|
* A type that maps between a {@link java.sql.Types#VARBINARY VARBINARY} and {@code byte[]}
|
||||||
|
@ -23,7 +29,7 @@ import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
||||||
*/
|
*/
|
||||||
public class BinaryType
|
public class BinaryType
|
||||||
extends AbstractSingleColumnStandardBasicType<byte[]>
|
extends AbstractSingleColumnStandardBasicType<byte[]>
|
||||||
implements VersionType<byte[]> {
|
implements VersionType<byte[]>, AdjustableBasicType<byte[]> {
|
||||||
|
|
||||||
public static final BinaryType INSTANCE = new BinaryType();
|
public static final BinaryType INSTANCE = new BinaryType();
|
||||||
|
|
||||||
|
@ -82,4 +88,18 @@ public class BinaryType
|
||||||
public Comparator<byte[]> getComparator() {
|
public Comparator<byte[]> getComparator() {
|
||||||
return PrimitiveByteArrayTypeDescriptor.INSTANCE.getComparator();
|
return PrimitiveByteArrayTypeDescriptor.INSTANCE.getComparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators, JavaTypeDescriptor<X> domainJtd) {
|
||||||
|
if ( ! indicators.isLob() ) {
|
||||||
|
return (BasicType<X>) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
final JdbcTypeDescriptor jdbcType = jdbcTypeRegistry.getDescriptor( Types.BLOB );
|
||||||
|
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,10 @@ package org.hibernate.type;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.type.descriptor.java.BooleanTypeDescriptor;
|
import org.hibernate.type.descriptor.java.BooleanTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
|
||||||
|
@ -22,7 +24,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
*/
|
*/
|
||||||
public class BooleanType
|
public class BooleanType
|
||||||
extends AbstractSingleColumnStandardBasicType<Boolean>
|
extends AbstractSingleColumnStandardBasicType<Boolean>
|
||||||
implements PrimitiveType<Boolean>, DiscriminatorType<Boolean>, SqlTypeDescriptorIndicatorCapable<Boolean> {
|
implements PrimitiveType<Boolean>, DiscriminatorType<Boolean>, AdjustableBasicType<Boolean> {
|
||||||
public static final BooleanType INSTANCE = new BooleanType();
|
public static final BooleanType INSTANCE = new BooleanType();
|
||||||
|
|
||||||
public BooleanType() {
|
public BooleanType() {
|
||||||
|
@ -32,6 +34,12 @@ public class BooleanType
|
||||||
protected BooleanType(JdbcTypeDescriptor jdbcTypeDescriptor, BooleanTypeDescriptor javaTypeDescriptor) {
|
protected BooleanType(JdbcTypeDescriptor jdbcTypeDescriptor, BooleanTypeDescriptor javaTypeDescriptor) {
|
||||||
super( jdbcTypeDescriptor, javaTypeDescriptor );
|
super( jdbcTypeDescriptor, javaTypeDescriptor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Incubating
|
||||||
|
public BooleanType(JdbcTypeDescriptor jdbcTypeDescriptor, JavaTypeDescriptor<Boolean> javaTypeDescriptor) {
|
||||||
|
super( jdbcTypeDescriptor, javaTypeDescriptor );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "boolean";
|
return "boolean";
|
||||||
|
@ -60,7 +68,9 @@ public class BooleanType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
final int preferredSqlTypeCodeForBoolean = indicators.getPreferredSqlTypeCodeForBoolean();
|
final int preferredSqlTypeCodeForBoolean = indicators.getPreferredSqlTypeCodeForBoolean();
|
||||||
final JdbcTypeDescriptor jdbcTypeDescriptor;
|
final JdbcTypeDescriptor jdbcTypeDescriptor;
|
||||||
// We treat BIT like BOOLEAN because it uses the same JDBC access methods
|
// We treat BIT like BOOLEAN because it uses the same JDBC access methods
|
||||||
|
|
|
@ -7,10 +7,13 @@
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor;
|
import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@code char[]}
|
* A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@code char[]}
|
||||||
|
@ -20,7 +23,7 @@ import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
||||||
*/
|
*/
|
||||||
public class CharArrayType
|
public class CharArrayType
|
||||||
extends AbstractSingleColumnStandardBasicType<char[]>
|
extends AbstractSingleColumnStandardBasicType<char[]>
|
||||||
implements SqlTypeDescriptorIndicatorCapable<char[]> {
|
implements AdjustableBasicType<char[]> {
|
||||||
public static final CharArrayType INSTANCE = new CharArrayType();
|
public static final CharArrayType INSTANCE = new CharArrayType();
|
||||||
|
|
||||||
public CharArrayType() {
|
public CharArrayType() {
|
||||||
|
@ -37,22 +40,23 @@ public class CharArrayType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
|
assert domainJtd != null;
|
||||||
|
|
||||||
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
|
||||||
|
final int jdbcTypeCode;
|
||||||
if ( indicators.isLob() ) {
|
if ( indicators.isLob() ) {
|
||||||
//noinspection unchecked
|
jdbcTypeCode = indicators.isNationalized() ? Types.NCLOB : Types.CLOB;
|
||||||
return (BasicType<X>) ( indicators.isNationalized() ? CharacterArrayNClobType.INSTANCE : CharacterArrayClobType.INSTANCE );
|
}
|
||||||
|
else {
|
||||||
|
jdbcTypeCode = indicators.isNationalized() ? Types.NVARCHAR : Types.VARCHAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( indicators.isNationalized() ) {
|
final JdbcTypeDescriptor jdbcType = jdbcTypeRegistry.getDescriptor( jdbcTypeCode );
|
||||||
final JdbcTypeDescriptor nvarcharType = indicators.getTypeConfiguration()
|
return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType );
|
||||||
.getJdbcTypeDescriptorRegistry()
|
|
||||||
.getDescriptor( Types.NVARCHAR );
|
|
||||||
|
|
||||||
//noinspection unchecked
|
|
||||||
return (BasicType<X>) indicators.getTypeConfiguration().getBasicTypeRegistry().resolve( getJavaTypeDescriptor(), nvarcharType );
|
|
||||||
}
|
|
||||||
|
|
||||||
//noinspection unchecked
|
|
||||||
return (BasicType<X>) this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,15 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
|
import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link Character Character[]}
|
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link Character Character[]}
|
||||||
|
@ -20,7 +26,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
*/
|
*/
|
||||||
public class CharacterArrayClobType
|
public class CharacterArrayClobType
|
||||||
extends AbstractSingleColumnStandardBasicType<Character[]>
|
extends AbstractSingleColumnStandardBasicType<Character[]>
|
||||||
implements SqlTypeDescriptorIndicatorCapable<Character[]> {
|
implements AdjustableBasicType<Character[]> {
|
||||||
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
|
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
|
||||||
|
|
||||||
public CharacterArrayClobType() {
|
public CharacterArrayClobType() {
|
||||||
|
@ -33,8 +39,23 @@ public class CharacterArrayClobType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
//noinspection unchecked
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
|
if ( domainJtd != null && domainJtd.getJavaTypeClass() == char[].class ) {
|
||||||
|
// domainJtd is a `char[]` instead of a `Character[]`....
|
||||||
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
final JdbcTypeDescriptor jdbcType = indicators.isNationalized()
|
||||||
|
? jdbcTypeRegistry.getDescriptor( Types.NCLOB )
|
||||||
|
: jdbcTypeRegistry.getDescriptor( Types.CLOB );
|
||||||
|
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( domainJtd.getJavaType() ),
|
||||||
|
jdbcType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (BasicType<X>) ( indicators.isNationalized() ? CharacterArrayNClobType.INSTANCE : this );
|
return (BasicType<X>) ( indicators.isNationalized() ? CharacterArrayNClobType.INSTANCE : this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,15 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
|
import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
import org.hibernate.type.descriptor.jdbc.NClobTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.NClobTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between {@link java.sql.Types#NCLOB NCLOB} and {@link Character Character[]}
|
* A type that maps between {@link java.sql.Types#NCLOB NCLOB} and {@link Character Character[]}
|
||||||
|
@ -17,7 +24,9 @@ import org.hibernate.type.descriptor.jdbc.NClobTypeDescriptor;
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class CharacterArrayNClobType extends AbstractSingleColumnStandardBasicType<Character[]> {
|
public class CharacterArrayNClobType
|
||||||
|
extends AbstractSingleColumnStandardBasicType<Character[]>
|
||||||
|
implements AdjustableBasicType<Character[]> {
|
||||||
public static final CharacterArrayNClobType INSTANCE = new CharacterArrayNClobType();
|
public static final CharacterArrayNClobType INSTANCE = new CharacterArrayNClobType();
|
||||||
|
|
||||||
public CharacterArrayNClobType() {
|
public CharacterArrayNClobType() {
|
||||||
|
@ -29,4 +38,23 @@ public class CharacterArrayNClobType extends AbstractSingleColumnStandardBasicTy
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
|
if ( domainJtd != null && domainJtd.getJavaTypeClass() == char[].class ) {
|
||||||
|
// domainJtd is a `char[]` instead of a `Character[]`....
|
||||||
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
final JdbcTypeDescriptor jdbcType = jdbcTypeRegistry.getDescriptor( Types.NCLOB );
|
||||||
|
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( domainJtd.getJavaType() ),
|
||||||
|
jdbcType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
return (BasicType<X>) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,11 @@ package org.hibernate.type;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
|
import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,7 +23,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
||||||
*/
|
*/
|
||||||
public class CharacterArrayType
|
public class CharacterArrayType
|
||||||
extends AbstractSingleColumnStandardBasicType<Character[]>
|
extends AbstractSingleColumnStandardBasicType<Character[]>
|
||||||
implements SqlTypeDescriptorIndicatorCapable<Character[]> {
|
implements AdjustableBasicType<Character[]> {
|
||||||
public static final CharacterArrayType INSTANCE = new CharacterArrayType();
|
public static final CharacterArrayType INSTANCE = new CharacterArrayType();
|
||||||
|
|
||||||
public CharacterArrayType() {
|
public CharacterArrayType() {
|
||||||
|
@ -38,26 +40,36 @@ public class CharacterArrayType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
if ( indicators.isNationalized() ) {
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
|
||||||
|
final int jdbcTypeCode;
|
||||||
if ( indicators.isLob() ) {
|
if ( indicators.isLob() ) {
|
||||||
//noinspection unchecked
|
jdbcTypeCode = indicators.isNationalized() ? Types.NCLOB : Types.CLOB;
|
||||||
return (BasicType<X>) CharacterArrayNClobType.INSTANCE;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final JdbcTypeDescriptor nvarcharType = typeConfiguration.getJdbcTypeDescriptorRegistry().getDescriptor( Types.NVARCHAR );
|
jdbcTypeCode = indicators.isNationalized() ? Types.NVARCHAR : Types.VARCHAR;
|
||||||
//noinspection unchecked
|
|
||||||
return (BasicType<X>) typeConfiguration.getBasicTypeRegistry().resolve( getJavaTypeDescriptor(), nvarcharType );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( indicators.isLob() ) {
|
final JdbcTypeDescriptor indicatedJdbcType = jdbcTypeRegistry.getDescriptor( jdbcTypeCode );
|
||||||
//noinspection unchecked
|
|
||||||
return (BasicType<X>) CharacterArrayClobType.INSTANCE;
|
if ( domainJtd != null && domainJtd.getJavaTypeClass() == Character[].class ) {
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
typeConfiguration.getJavaTypeDescriptorRegistry().resolveDescriptor( domainJtd.getJavaType() ),
|
||||||
|
indicatedJdbcType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//noinspection unchecked
|
if ( getJdbcTypeDescriptor() == indicatedJdbcType ) {
|
||||||
return (BasicType<X>) this;
|
return (BasicType<X>) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (BasicType<X>) typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
getJavaTypeDescriptor(),
|
||||||
|
indicatedJdbcType
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,16 @@
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.type.descriptor.java.CharacterTypeDescriptor;
|
import org.hibernate.type.descriptor.java.CharacterTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.CharTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.CharTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between {@link java.sql.Types#CHAR CHAR(1)} and {@link Character}
|
* A type that maps between {@link java.sql.Types#CHAR CHAR(1)} and {@link Character}
|
||||||
|
@ -21,7 +26,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
*/
|
*/
|
||||||
public class CharacterType
|
public class CharacterType
|
||||||
extends AbstractSingleColumnStandardBasicType<Character>
|
extends AbstractSingleColumnStandardBasicType<Character>
|
||||||
implements PrimitiveType<Character>, DiscriminatorType<Character>, SqlTypeDescriptorIndicatorCapable<Character> {
|
implements PrimitiveType<Character>, DiscriminatorType<Character>, AdjustableBasicType<Character> {
|
||||||
|
|
||||||
public static final CharacterType INSTANCE = new CharacterType();
|
public static final CharacterType INSTANCE = new CharacterType();
|
||||||
|
|
||||||
|
@ -55,7 +60,15 @@ public class CharacterType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
return (BasicType<X>) ( indicators.isNationalized() ? CharacterNCharType.INSTANCE : this );
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
final JdbcTypeDescriptor jdbcType = indicators.isNationalized()
|
||||||
|
? jdbcTypeRegistry.getDescriptor( Types.NCHAR )
|
||||||
|
: jdbcTypeRegistry.getDescriptor( Types.CHAR );
|
||||||
|
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,14 @@
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.type.descriptor.java.ClobTypeDescriptor;
|
import org.hibernate.type.descriptor.java.ClobTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link Clob}
|
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link Clob}
|
||||||
|
@ -18,7 +22,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class ClobType extends AbstractSingleColumnStandardBasicType<Clob> implements SqlTypeDescriptorIndicatorCapable<Clob> {
|
public class ClobType extends AbstractSingleColumnStandardBasicType<Clob> implements AdjustableBasicType<Clob> {
|
||||||
public static final ClobType INSTANCE = new ClobType();
|
public static final ClobType INSTANCE = new ClobType();
|
||||||
|
|
||||||
public ClobType() {
|
public ClobType() {
|
||||||
|
@ -40,16 +44,21 @@ public class ClobType extends AbstractSingleColumnStandardBasicType<Clob> implem
|
||||||
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeClob( original, target, session );
|
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeClob( original, target, session );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
@Override
|
@Override
|
||||||
public BasicType resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
@SuppressWarnings( "unchecked" )
|
||||||
// todo (6.0) : Support a "wrapped clob"? This would be a (N)VARCHAR column we handle as a Clob in-memory
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
// - might be especially interesting for streaming based (N)VARCHAR reading
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
if ( indicators.isNationalized() ) {
|
if ( ! indicators.isNationalized() ) {
|
||||||
return NClobType.INSTANCE;
|
return (BasicType<X>) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
domainJtd,
|
||||||
|
jdbcTypeRegistry.getDescriptor( Types.NCLOB )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,14 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||||
import org.hibernate.type.descriptor.ValueBinder;
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
import org.hibernate.type.descriptor.ValueExtractor;
|
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.JavaTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypedExpressable;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
|
import org.hibernate.type.internal.UserTypeJavaTypeWrapper;
|
||||||
|
import org.hibernate.type.internal.UserTypeSqlTypeAdapter;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import org.hibernate.usertype.EnhancedUserType;
|
import org.hibernate.usertype.EnhancedUserType;
|
||||||
import org.hibernate.usertype.LoggableUserType;
|
|
||||||
import org.hibernate.usertype.Sized;
|
import org.hibernate.usertype.Sized;
|
||||||
import org.hibernate.usertype.UserType;
|
import org.hibernate.usertype.UserType;
|
||||||
import org.hibernate.usertype.UserVersionType;
|
import org.hibernate.usertype.UserVersionType;
|
||||||
|
@ -51,23 +53,22 @@ import org.hibernate.usertype.UserVersionType;
|
||||||
*/
|
*/
|
||||||
public class CustomType
|
public class CustomType
|
||||||
extends AbstractType
|
extends AbstractType
|
||||||
implements BasicType, IdentifierType, DiscriminatorType, VersionType, StringRepresentableType, ProcedureParameterNamedBinder, ProcedureParameterExtractionAware, ValueBinder {
|
implements BasicType, IdentifierType, DiscriminatorType, VersionType, StringRepresentableType, ProcedureParameterNamedBinder, ProcedureParameterExtractionAware {
|
||||||
|
|
||||||
private final UserType userType;
|
private final UserType<Object> userType;
|
||||||
private final String[] registrationKeys;
|
private final String[] registrationKeys;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private final JavaTypeDescriptor mappedJavaTypeDescriptor;
|
private final BasicJavaDescriptor<Object> mappedJavaTypeDescriptor;
|
||||||
private final JdbcTypeDescriptor jdbcTypeDescriptor;
|
private final JdbcTypeDescriptor jdbcTypeDescriptor;
|
||||||
|
|
||||||
private final ValueExtractor valueExtractor;
|
private final ValueExtractor<Object> valueExtractor;
|
||||||
|
private final ValueBinder<Object> valueBinder;
|
||||||
|
|
||||||
private final Size dictatedSize;
|
private final Size dictatedSize;
|
||||||
private final Size defaultSize;
|
private final Size defaultSize;
|
||||||
|
|
||||||
private final boolean customLogging;
|
|
||||||
|
|
||||||
public CustomType(UserType userType, TypeConfiguration typeConfiguration) throws MappingException {
|
public CustomType(UserType userType, TypeConfiguration typeConfiguration) throws MappingException {
|
||||||
this( userType, ArrayHelper.EMPTY_STRING_ARRAY, typeConfiguration );
|
this( userType, ArrayHelper.EMPTY_STRING_ARRAY, typeConfiguration );
|
||||||
}
|
}
|
||||||
|
@ -76,9 +77,23 @@ public class CustomType
|
||||||
this.userType = userType;
|
this.userType = userType;
|
||||||
this.name = userType.getClass().getName();
|
this.name = userType.getClass().getName();
|
||||||
|
|
||||||
//noinspection unchecked
|
if ( userType instanceof BasicJavaDescriptor ) {
|
||||||
this.mappedJavaTypeDescriptor = typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( userType.returnedClass() );
|
//noinspection rawtypes
|
||||||
this.jdbcTypeDescriptor = typeConfiguration.getJdbcTypeDescriptorRegistry().getDescriptor( userType.sqlTypes()[0] );
|
this.mappedJavaTypeDescriptor = ( (BasicJavaDescriptor) userType );
|
||||||
|
}
|
||||||
|
else if ( userType instanceof JavaTypedExpressable ) {
|
||||||
|
//noinspection rawtypes
|
||||||
|
this.mappedJavaTypeDescriptor = (BasicJavaDescriptor) ( (JavaTypedExpressable) userType ).getExpressableJavaTypeDescriptor();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.mappedJavaTypeDescriptor = new UserTypeJavaTypeWrapper<>( userType );
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a JdbcTypeDescriptor adapter that uses the UserType binde/extract handling
|
||||||
|
this.jdbcTypeDescriptor = new UserTypeSqlTypeAdapter<>( userType, mappedJavaTypeDescriptor );
|
||||||
|
|
||||||
|
this.valueExtractor = jdbcTypeDescriptor.getExtractor( mappedJavaTypeDescriptor );
|
||||||
|
this.valueBinder = jdbcTypeDescriptor.getBinder( mappedJavaTypeDescriptor );
|
||||||
|
|
||||||
if ( userType instanceof Sized ) {
|
if ( userType instanceof Sized ) {
|
||||||
final Sized sized = (Sized) userType;
|
final Sized sized = (Sized) userType;
|
||||||
|
@ -90,35 +105,11 @@ public class CustomType
|
||||||
this.defaultSize = null;
|
this.defaultSize = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( userType instanceof ValueExtractor ) {
|
|
||||||
this.valueExtractor = (ValueExtractor) userType;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.valueExtractor = jdbcTypeDescriptor.getExtractor( mappedJavaTypeDescriptor );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.customLogging = userType instanceof LoggableUserType;
|
|
||||||
this.registrationKeys = registrationKeys;
|
this.registrationKeys = registrationKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public UserType getUserType() {
|
||||||
public ValueBinder<?> getJdbcValueBinder() {
|
return userType;
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bind(PreparedStatement st, Object value, int index, WrapperOptions options) throws SQLException {
|
|
||||||
userType.nullSafeSet( st, value, index, options.getSession() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bind(CallableStatement st, Object value, String name, WrapperOptions options) throws SQLException {
|
|
||||||
if ( userType instanceof ProcedureParameterNamedBinder ) {
|
|
||||||
final ProcedureParameterNamedBinder namedParamSupport = (ProcedureParameterNamedBinder) userType;
|
|
||||||
if ( namedParamSupport.canDoSetting() ) {
|
|
||||||
namedParamSupport.nullSafeSet( st, value, name, options.getSession() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -126,8 +117,9 @@ public class CustomType
|
||||||
return valueExtractor;
|
return valueExtractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserType getUserType() {
|
@Override
|
||||||
return userType;
|
public ValueBinder<?> getJdbcValueBinder() {
|
||||||
|
return valueBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -181,7 +173,7 @@ public class CustomType
|
||||||
String[] names,
|
String[] names,
|
||||||
SharedSessionContractImplementor session,
|
SharedSessionContractImplementor session,
|
||||||
Object owner) throws SQLException {
|
Object owner) throws SQLException {
|
||||||
return getUserType().nullSafeGet( rs, names, session, owner);
|
throw new UnsupportedOperationException( "Reading from ResultSet by name is no longer supported" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -190,7 +182,7 @@ public class CustomType
|
||||||
String columnName,
|
String columnName,
|
||||||
SharedSessionContractImplementor session,
|
SharedSessionContractImplementor session,
|
||||||
Object owner) throws SQLException {
|
Object owner) throws SQLException {
|
||||||
return nullSafeGet(rs, new String[] { columnName }, session, owner);
|
throw new UnsupportedOperationException( "Reading from ResultSet by name is no longer supported" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -285,14 +277,10 @@ public class CustomType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toLoggableString(Object value, SessionFactoryImplementor factory)
|
public String toLoggableString(Object value, SessionFactoryImplementor factory) {
|
||||||
throws HibernateException {
|
|
||||||
if ( value == null ) {
|
if ( value == null ) {
|
||||||
return "null";
|
return "null";
|
||||||
}
|
}
|
||||||
else if ( customLogging ) {
|
|
||||||
return ( ( LoggableUserType ) getUserType() ).toLoggableString( value, factory );
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
return toXMLString( value, factory );
|
return toXMLString( value, factory );
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,9 @@ import org.hibernate.type.descriptor.java.DoubleTypeDescriptor;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class DoubleType extends AbstractSingleColumnStandardBasicType<Double> implements PrimitiveType<Double> {
|
public class DoubleType
|
||||||
|
extends AbstractSingleColumnStandardBasicType<Double>
|
||||||
|
implements PrimitiveType<Double> {
|
||||||
public static final DoubleType INSTANCE = new DoubleType();
|
public static final DoubleType INSTANCE = new DoubleType();
|
||||||
|
|
||||||
public static final Double ZERO = 0.0;
|
public static final Double ZERO = 0.0;
|
||||||
|
|
|
@ -19,7 +19,6 @@ import javax.persistence.MapKeyEnumerated;
|
||||||
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.NotYetImplementedFor6Exception;
|
|
||||||
import org.hibernate.annotations.Nationalized;
|
import org.hibernate.annotations.Nationalized;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
|
@ -29,6 +28,8 @@ import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter;
|
import org.hibernate.metamodel.model.convert.internal.NamedEnumValueConverter;
|
||||||
import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter;
|
import org.hibernate.metamodel.model.convert.internal.OrdinalEnumValueConverter;
|
||||||
import org.hibernate.metamodel.model.convert.spi.EnumValueConverter;
|
import org.hibernate.metamodel.model.convert.spi.EnumValueConverter;
|
||||||
|
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.BasicJavaDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
|
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
|
@ -78,7 +79,10 @@ public class EnumType<T extends Enum<T>>
|
||||||
|
|
||||||
private Class<T> enumClass;
|
private Class<T> enumClass;
|
||||||
|
|
||||||
private EnumValueConverter<T,?> enumValueConverter;
|
private EnumValueConverter<T,Object> enumValueConverter;
|
||||||
|
private JdbcTypeDescriptor jdbcTypeDescriptor;
|
||||||
|
private ValueExtractor<T> jdbcValueExtractor;
|
||||||
|
private ValueBinder<T> jdbcValueBinder;
|
||||||
|
|
||||||
private TypeConfiguration typeConfiguration;
|
private TypeConfiguration typeConfiguration;
|
||||||
|
|
||||||
|
@ -90,8 +94,12 @@ public class EnumType<T extends Enum<T>>
|
||||||
EnumValueConverter enumValueConverter,
|
EnumValueConverter enumValueConverter,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
this.enumClass = enumClass;
|
this.enumClass = enumClass;
|
||||||
this.enumValueConverter = enumValueConverter;
|
|
||||||
this.typeConfiguration = typeConfiguration;
|
this.typeConfiguration = typeConfiguration;
|
||||||
|
|
||||||
|
this.enumValueConverter = enumValueConverter;
|
||||||
|
this.jdbcTypeDescriptor = typeConfiguration.getJdbcTypeDescriptorRegistry().getDescriptor( enumValueConverter.getJdbcTypeCode() );
|
||||||
|
this.jdbcValueExtractor = jdbcTypeDescriptor.getExtractor( enumValueConverter.getRelationalJavaDescriptor() );
|
||||||
|
this.jdbcValueBinder = jdbcTypeDescriptor.getBinder( enumValueConverter.getRelationalJavaDescriptor() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnumValueConverter getEnumValueConverter() {
|
public EnumValueConverter getEnumValueConverter() {
|
||||||
|
@ -171,6 +179,9 @@ public class EnumType<T extends Enum<T>>
|
||||||
}
|
}
|
||||||
|
|
||||||
this.enumValueConverter = interpretParameters( parameters );
|
this.enumValueConverter = interpretParameters( parameters );
|
||||||
|
this.jdbcTypeDescriptor = typeConfiguration.getJdbcTypeDescriptorRegistry().getDescriptor( enumValueConverter.getJdbcTypeCode() );
|
||||||
|
this.jdbcValueExtractor = (ValueExtractor) jdbcTypeDescriptor.getExtractor( enumValueConverter.getRelationalJavaDescriptor() );
|
||||||
|
this.jdbcValueBinder = (ValueBinder) jdbcTypeDescriptor.getBinder( enumValueConverter.getRelationalJavaDescriptor() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( LOG.isDebugEnabled() ) {
|
if ( LOG.isDebugEnabled() ) {
|
||||||
|
@ -217,7 +228,7 @@ public class EnumType<T extends Enum<T>>
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private EnumValueConverter<T,?> interpretParameters(Properties parameters) {
|
private EnumValueConverter<T,Object> interpretParameters(Properties parameters) {
|
||||||
//noinspection rawtypes
|
//noinspection rawtypes
|
||||||
final EnumJavaTypeDescriptor enumJavaDescriptor = (EnumJavaTypeDescriptor) typeConfiguration
|
final EnumJavaTypeDescriptor enumJavaDescriptor = (EnumJavaTypeDescriptor) typeConfiguration
|
||||||
.getJavaTypeDescriptorRegistry()
|
.getJavaTypeDescriptorRegistry()
|
||||||
|
@ -349,14 +360,14 @@ public class EnumType<T extends Enum<T>>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
|
public Object nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
|
||||||
throw new NotYetImplementedFor6Exception( getClass() );
|
verifyConfigured();
|
||||||
// verifyConfigured();
|
final Object relational = jdbcValueExtractor.extract( rs, position, session );
|
||||||
// return enumValueConverter.readValue( rs, names[0], session );
|
return enumValueConverter.toDomainValue( relational );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyConfigured() {
|
private void verifyConfigured() {
|
||||||
if ( enumValueConverter == null ) {
|
if ( enumValueConverter == null || jdbcValueBinder == null || jdbcValueExtractor == null ) {
|
||||||
throw new AssertionFailure( "EnumType (" + enumClass.getName() + ") not properly, fully configured" );
|
throw new AssertionFailure( "EnumType (" + enumClass.getName() + ") not properly, fully configured" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,15 @@
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link String}
|
* A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link String}
|
||||||
|
@ -18,7 +24,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
*/
|
*/
|
||||||
public class MaterializedClobType
|
public class MaterializedClobType
|
||||||
extends AbstractSingleColumnStandardBasicType<String>
|
extends AbstractSingleColumnStandardBasicType<String>
|
||||||
implements SqlTypeDescriptorIndicatorCapable<String> {
|
implements AdjustableBasicType<String> {
|
||||||
public static final MaterializedClobType INSTANCE = new MaterializedClobType();
|
public static final MaterializedClobType INSTANCE = new MaterializedClobType();
|
||||||
|
|
||||||
public MaterializedClobType() {
|
public MaterializedClobType() {
|
||||||
|
@ -30,10 +36,18 @@ public class MaterializedClobType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
if ( indicators.isNationalized() ) {
|
if ( indicators.isNationalized() ) {
|
||||||
//noinspection unchecked
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
return (BasicType<X>) MaterializedNClobType.INSTANCE;
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
final JdbcTypeDescriptor nclobType = jdbcTypeRegistry.getDescriptor( Types.NCLOB );
|
||||||
|
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
domainJtd,
|
||||||
|
nclobType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.Converter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles conversion to/from Boolean as `0` (false) or `1` (true)
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Converter
|
||||||
|
public class NumericBooleanConverter implements AttributeConverter<Boolean,Integer> {
|
||||||
|
@Override
|
||||||
|
public Integer convertToDatabaseColumn(Boolean attribute) {
|
||||||
|
return NumericBooleanType.NumericConverter.toRelational( attribute );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean convertToEntityAttribute(Integer dbData) {
|
||||||
|
return NumericBooleanType.NumericConverter.toDomain( dbData );
|
||||||
|
}
|
||||||
|
}
|
|
@ -60,9 +60,18 @@ public class NumericBooleanType
|
||||||
return CONVERTER;
|
return CONVERTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class NumericConverter implements BasicValueConverter<Boolean, Integer> {
|
public static class NumericConverter implements BasicValueConverter<Boolean, Integer> {
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final NumericConverter INSTANCE = new NumericConverter();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean toDomainValue(Integer relationalForm) {
|
public Boolean toDomainValue(Integer relationalForm) {
|
||||||
|
return toDomain( relationalForm );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean toDomain(Integer relationalForm) {
|
||||||
if ( relationalForm == null ) {
|
if ( relationalForm == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +89,10 @@ public class NumericBooleanType
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer toRelationalValue(Boolean domainForm) {
|
public Integer toRelationalValue(Boolean domainForm) {
|
||||||
|
return toRelational( domainForm );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer toRelational(Boolean domainForm) {
|
||||||
if ( domainForm == null ) {
|
if ( domainForm == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,14 @@
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor;
|
import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map a char[] to a Clob
|
* Map a char[] to a Clob
|
||||||
|
@ -16,7 +21,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
*/
|
*/
|
||||||
public class PrimitiveCharacterArrayClobType
|
public class PrimitiveCharacterArrayClobType
|
||||||
extends AbstractSingleColumnStandardBasicType<char[]>
|
extends AbstractSingleColumnStandardBasicType<char[]>
|
||||||
implements SqlTypeDescriptorIndicatorCapable<char[]> {
|
implements AdjustableBasicType<char[]> {
|
||||||
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
|
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
|
||||||
|
|
||||||
public PrimitiveCharacterArrayClobType() {
|
public PrimitiveCharacterArrayClobType() {
|
||||||
|
@ -29,13 +34,20 @@ public class PrimitiveCharacterArrayClobType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
@SuppressWarnings("unchecked")
|
||||||
if ( indicators.isNationalized() ) {
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
//noinspection unchecked
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
return (BasicType<X>) PrimitiveCharacterArrayNClobType.INSTANCE;
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
}
|
if ( ! indicators.isNationalized() ) {
|
||||||
|
|
||||||
//noinspection unchecked
|
|
||||||
return (BasicType<X>) this;
|
return (BasicType<X>) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
domainJtd,
|
||||||
|
jdbcTypeRegistry.getDescriptor( Types.NCLOB )
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
import java.io.Serializable;
|
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Additional contract for primitive / primitive wrapper types.
|
* Additional contract for primitive / primitive wrapper types.
|
||||||
|
@ -13,14 +16,14 @@ import java.io.Serializable;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface PrimitiveType<T> extends LiteralType<T> {
|
public interface PrimitiveType<T> extends LiteralType<T>, AdjustableBasicType<T> {
|
||||||
/**
|
/**
|
||||||
* Retrieve the primitive counterpart to the wrapper type identified by
|
* Retrieve the primitive counterpart to the wrapper type identified by
|
||||||
* {@link org.hibernate.type.Type#getReturnedClass()}.
|
* {@link org.hibernate.type.Type#getReturnedClass()}.
|
||||||
*
|
*
|
||||||
* @return The primitive Java type.
|
* @return The primitive Java type.
|
||||||
*/
|
*/
|
||||||
public abstract Class getPrimitiveClass();
|
Class<?> getPrimitiveClass();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the string representation of the given value.
|
* Retrieve the string representation of the given value.
|
||||||
|
@ -29,12 +32,18 @@ public interface PrimitiveType<T> extends LiteralType<T> {
|
||||||
*
|
*
|
||||||
* @return The string representation
|
* @return The string representation
|
||||||
*/
|
*/
|
||||||
public String toString(T value);
|
String toString(T value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get this type's default value.
|
* Get this type's default value.
|
||||||
*
|
*
|
||||||
* @return The default value.
|
* @return The default value.
|
||||||
*/
|
*/
|
||||||
public abstract Object getDefaultValue();
|
Object getDefaultValue();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators, JavaTypeDescriptor<X> domainJtd) {
|
||||||
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, getJdbcTypeDescriptor() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,19 +8,21 @@ package org.hibernate.type;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.SerializableTypeDescriptor;
|
import org.hibernate.type.descriptor.java.SerializableTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between a {@link java.sql.Types#VARBINARY VARBINARY} and {@link Serializable} classes.
|
* A type that maps between a {@link java.sql.Types#VARBINARY VARBINARY} and {@link Serializable} classes.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Notice specifically the 2 forms:<ul>
|
* Notice specifically the 3 constructors:<ul>
|
||||||
* <li>{@link #INSTANCE} indicates a mapping using the {@link Serializable} interface itself.</li>
|
* <li>{@link #INSTANCE} indicates a mapping using the {@link Serializable} interface itself.</li>
|
||||||
* <li>{@link #SerializableType(Class)} indicates a mapping using the specific class</li>
|
* <li>{@link #SerializableType(Class)} indicates a mapping using the specific class</li>
|
||||||
|
* <li>{@link #SerializableType(JavaTypeDescriptor)} indicates a mapping using the specific JavaTypeDescriptor</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* The important distinction has to do with locating the appropriate {@link ClassLoader} to use during deserialization.
|
* The important distinction has to do with locating the appropriate {@link ClassLoader} to use during deserialization.
|
||||||
* In the fist form we are always using the {@link ClassLoader} of the JVM (Hibernate will always fallback to trying
|
* In the fist form we are always using the {@link ClassLoader} of the JVM (Hibernate will always fallback to trying
|
||||||
* its classloader as well). The second form is better at targeting the needed {@link ClassLoader} actually needed.
|
* its classloader as well). The second and third forms are better at targeting the needed {@link ClassLoader} actually needed.
|
||||||
*
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -35,6 +37,11 @@ public class SerializableType<T extends Serializable> extends AbstractSingleColu
|
||||||
this.serializableClass = serializableClass;
|
this.serializableClass = serializableClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SerializableType(JavaTypeDescriptor<T> jtd) {
|
||||||
|
super( VarbinaryTypeDescriptor.INSTANCE, jtd );
|
||||||
|
this.serializableClass = jtd.getJavaTypeClass();
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return (serializableClass==Serializable.class) ? "serializable" : serializableClass.getName();
|
return (serializableClass==Serializable.class) ? "serializable" : serializableClass.getName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,15 @@
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
import java.sql.Types;
|
||||||
|
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@link String}
|
* A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@link String}
|
||||||
|
@ -18,7 +23,7 @@ import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
||||||
*/
|
*/
|
||||||
public class StringType
|
public class StringType
|
||||||
extends AbstractSingleColumnStandardBasicType<String>
|
extends AbstractSingleColumnStandardBasicType<String>
|
||||||
implements DiscriminatorType<String>, SqlTypeDescriptorIndicatorCapable<String> {
|
implements DiscriminatorType<String>, AdjustableBasicType<String> {
|
||||||
|
|
||||||
public static final StringType INSTANCE = new StringType();
|
public static final StringType INSTANCE = new StringType();
|
||||||
|
|
||||||
|
@ -47,14 +52,33 @@ public class StringType
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
@Override
|
@Override
|
||||||
public BasicType resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
@SuppressWarnings("unchecked")
|
||||||
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
|
if ( ! indicators.isLob() && ! indicators.isNationalized() ) {
|
||||||
|
return (BasicType<X>) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||||
|
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||||
|
final int jdbcTypeCode;
|
||||||
|
|
||||||
if ( indicators.isLob() ) {
|
if ( indicators.isLob() ) {
|
||||||
return indicators.isNationalized() ? MaterializedNClobType.INSTANCE : MaterializedClobType.INSTANCE;
|
jdbcTypeCode = indicators.isNationalized()
|
||||||
|
? Types.NCLOB
|
||||||
|
: Types.CLOB;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return indicators.isNationalized() ? StringNVarcharType.INSTANCE : this;
|
jdbcTypeCode = indicators.isNationalized()
|
||||||
|
? Types.NVARCHAR
|
||||||
|
: Types.VARCHAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||||
|
domainJtd,
|
||||||
|
jdbcTypeRegistry.getDescriptor( jdbcTypeCode )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type;
|
package org.hibernate.type;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.LongVarcharTypeDescriptor;
|
import org.hibernate.type.descriptor.jdbc.LongVarcharTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
|
@ -18,7 +19,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||||
*/
|
*/
|
||||||
public class TextType
|
public class TextType
|
||||||
extends AbstractSingleColumnStandardBasicType<String>
|
extends AbstractSingleColumnStandardBasicType<String>
|
||||||
implements SqlTypeDescriptorIndicatorCapable<String> {
|
implements AdjustableBasicType<String> {
|
||||||
public static final TextType INSTANCE = new TextType();
|
public static final TextType INSTANCE = new TextType();
|
||||||
|
|
||||||
public TextType() {
|
public TextType() {
|
||||||
|
@ -30,7 +31,9 @@ public class TextType
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
public <X> BasicType<X> resolveIndicatedType(
|
||||||
|
JdbcTypeDescriptorIndicators indicators,
|
||||||
|
JavaTypeDescriptor<X> domainJtd) {
|
||||||
if ( indicators.isNationalized() ) {
|
if ( indicators.isNationalized() ) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (BasicType<X>) NTextType.INSTANCE;
|
return (BasicType<X>) NTextType.INSTANCE;
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import javax.persistence.AttributeConverter;
|
||||||
|
import javax.persistence.Converter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles conversion to/from Boolean as `T` or `F`
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@Converter
|
||||||
|
public class TrueFalseConverter implements AttributeConverter<Boolean,Character> {
|
||||||
|
@Override
|
||||||
|
public Character convertToDatabaseColumn(Boolean attribute) {
|
||||||
|
return TrueFalseType.TrueFalseConverter.toRelational( attribute );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean convertToEntityAttribute(Character dbData) {
|
||||||
|
return TrueFalseType.TrueFalseConverter.toDomain( dbData );
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,9 +68,18 @@ public class TrueFalseType
|
||||||
return CONVERTER;
|
return CONVERTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TrueFalseConverter implements BasicValueConverter<Boolean, Character> {
|
public static class TrueFalseConverter implements BasicValueConverter<Boolean, Character> {
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final TrueFalseConverter INSTANCE = new TrueFalseConverter();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean toDomainValue(Character relationalForm) {
|
public Boolean toDomainValue(Character relationalForm) {
|
||||||
|
return toDomain( relationalForm );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean toDomain(Character relationalForm) {
|
||||||
if ( relationalForm == null ) {
|
if ( relationalForm == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +97,10 @@ public class TrueFalseType
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Character toRelationalValue(Boolean domainForm) {
|
public Character toRelationalValue(Boolean domainForm) {
|
||||||
|
return toRelational( domainForm );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Character toRelational(Boolean domainForm) {
|
||||||
if ( domainForm == null ) {
|
if ( domainForm == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue