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] )
|
||||
}
|
||||
|
||||
//tasks.test.include 'org/hibernate/'
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// grouping tasks - declaration, see below for task dependency definitions
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -300,6 +302,10 @@ task renderIntegrationGuide(type: AsciidoctorTask, group: 'Documentation') {
|
|||
|
||||
// Testing
|
||||
|
||||
test {
|
||||
include '**/mapping/basic/**'
|
||||
}
|
||||
|
||||
// resources inherently exclude sources
|
||||
sourceSets.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].
|
||||
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.
|
||||
- [[[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/Legacy_Bootstrap.adoc[]
|
||||
include::appendices/Legacy_DomainModel.adoc[]
|
||||
include::appendices/LegacyBasicTypeResolution.adoc[]
|
||||
include::appendices/Legacy_Criteria.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.
|
||||
|
||||
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]]
|
||||
==== `@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]]
|
||||
== Batching
|
||||
: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
|
||||
|
||||
[[batch-jdbcbatch]]
|
||||
|
|
|
@ -29,4 +29,3 @@ include::natural_id.adoc[]
|
|||
include::dynamic_model.adoc[]
|
||||
include::inheritance.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
|
||||
*
|
||||
* 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>.
|
||||
* 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.flush;
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class AlwaysFlushTest extends BaseEntityManagerFunctionalTestCase {
|
|||
Session session = entityManager.unwrap( Session.class);
|
||||
assertTrue(((Number) session
|
||||
.createNativeQuery("select count(*) from Person")
|
||||
.setFlushMode( FlushMode.ALWAYS)
|
||||
.setHibernateFlushMode( FlushMode.ALWAYS)
|
||||
.uniqueResult()).intValue() == 1);
|
||||
//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 BitSetType() {
|
||||
super( VarcharTypeDescriptor.INSTANCE, BitSetTypeDescriptor.INSTANCE );
|
||||
super( VarcharTypeDescriptor.INSTANCE, BitSetJavaType.INSTANCE );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,48 +10,54 @@ import java.util.BitSet;
|
|||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.annotations.TypeDef;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
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.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class BitSetTypeDefTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
@DomainModel( annotatedClasses = BitSetTypeDefTest.Product.class )
|
||||
@SessionFactory
|
||||
public class BitSetTypeDefTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
public void test(SessionFactoryScope scope) {
|
||||
|
||||
//tag::basic-custom-type-BitSetTypeDef-persistence-example[]
|
||||
BitSet bitSet = BitSet.valueOf( new long[] {1, 2, 3} );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
Product product = new Product( );
|
||||
product.setId( 1 );
|
||||
product.setBitSet( bitSet );
|
||||
session.persist( product );
|
||||
} );
|
||||
scope.inTransaction(
|
||||
(session) -> {
|
||||
Product product = new Product( );
|
||||
product.setId( 1 );
|
||||
product.setBitSet( bitSet );
|
||||
session.persist( product );
|
||||
}
|
||||
);
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
Product product = session.get( Product.class, 1 );
|
||||
assertEquals(bitSet, product.getBitSet());
|
||||
} );
|
||||
scope.inTransaction(
|
||||
(session) -> {
|
||||
final Product product = session.get( Product.class, 1 );
|
||||
assertEquals(bitSet, product.getBitSet());
|
||||
}
|
||||
);
|
||||
//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[]
|
||||
@Entity(name = "Product")
|
||||
@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
|
||||
public Object nullSafeGet(
|
||||
ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
|
||||
throws HibernateException, SQLException {
|
||||
String columnName = names[0];
|
||||
String columnValue = (String) rs.getObject( columnName );
|
||||
log.debugv("Result set column {0} value is {1}", columnName, columnValue);
|
||||
return columnValue == null ? null :
|
||||
BitSetTypeDescriptor.INSTANCE.fromString( columnValue );
|
||||
public Object nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
|
||||
String columnValue = (String) rs.getObject( position );
|
||||
if ( rs.wasNull() ) {
|
||||
columnValue = null;
|
||||
}
|
||||
|
||||
log.debugv("Result set column {0} value is {1}", position, columnValue);
|
||||
return BitSetHelper.stringToBitSet( columnValue );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -67,7 +67,7 @@ public class BitSetUserType implements UserType {
|
|||
st.setNull( index, Types.VARCHAR );
|
||||
}
|
||||
else {
|
||||
String stringValue = BitSetTypeDescriptor.INSTANCE.toString( (BitSet) value );
|
||||
String stringValue = BitSetHelper.bitSetToString( (BitSet) value );
|
||||
log.debugv("Binding {0} to parameter {1} ", stringValue, index);
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
public class ClobCharArrayTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
@Jpa( annotatedClasses = ClobCharArrayTest.Product.class )
|
||||
public class ClobCharArrayTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Integer productId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Product product = new Product( );
|
||||
product.setId( 1 );
|
||||
product.setName( "Mobile phone" );
|
||||
product.setWarranty( "My product warranty".toCharArray() );
|
||||
public void test(EntityManagerFactoryScope scope) {
|
||||
Integer productId = scope.fromTransaction(
|
||||
(em) -> {
|
||||
final Product product = new Product( );
|
||||
product.setId( 1 );
|
||||
product.setName( "Mobile phone" );
|
||||
product.setWarranty( "My product warranty".toCharArray() );
|
||||
|
||||
entityManager.persist( product );
|
||||
return product.getId();
|
||||
} );
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Product product = entityManager.find( Product.class, productId );
|
||||
assertArrayEquals( "My product warranty".toCharArray(), product.getWarranty() );
|
||||
} );
|
||||
em.persist( product );
|
||||
return product.getId();
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
(em) -> {
|
||||
final Product product = em.find( Product.class, productId );
|
||||
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[]
|
||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.userguide.mapping.basic;
|
|||
import java.math.BigDecimal;
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
|
@ -18,6 +17,7 @@ import org.hibernate.dialect.H2Dialect;
|
|||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.hibernate.testing.RequiresDialect;
|
||||
import org.hibernate.testing.orm.junit.NotImplementedYet;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
|
@ -26,6 +26,10 @@ import static org.junit.Assert.assertEquals;
|
|||
/**
|
||||
* @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)
|
||||
public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
|
@ -43,13 +47,15 @@ public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
|||
//tag::basic-datetime-temporal-date-persist-example[]
|
||||
Savings savings = new Savings( );
|
||||
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 );
|
||||
} );
|
||||
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
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[]
|
||||
}
|
||||
|
@ -61,14 +67,12 @@ public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
|||
@Id
|
||||
private Long id;
|
||||
|
||||
@Embedded
|
||||
@ColumnTransformer(
|
||||
forColumn = "money",
|
||||
read = "money / 100",
|
||||
write = "? * 100"
|
||||
read = "amount / 100",
|
||||
write = "? * 100"
|
||||
)
|
||||
// todo (6.0): needs a composite user type mechanism e.g. by providing a custom ComponentTuplizer/Instantiator
|
||||
private MonetaryAmount wallet;
|
||||
private BigDecimal amount;
|
||||
private Currency currency;
|
||||
|
||||
//Getters and setters omitted for brevity
|
||||
|
||||
|
@ -81,12 +85,20 @@ public class ColumnTransformerTest extends BaseEntityManagerFunctionalTestCase {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public MonetaryAmount getWallet() {
|
||||
return wallet;
|
||||
public BigDecimal getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setWallet(MonetaryAmount wallet) {
|
||||
this.wallet = wallet;
|
||||
public void setAmount(BigDecimal amount) {
|
||||
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 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.testing.SkipForDialect;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
|
@ -25,14 +21,6 @@ import static org.junit.Assert.assertArrayEquals;
|
|||
/**
|
||||
* @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 {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,12 +11,10 @@ import javax.persistence.Id;
|
|||
import javax.persistence.Lob;
|
||||
|
||||
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.testing.SkipForDialect;
|
||||
import org.hibernate.testing.DialectChecks;
|
||||
import org.hibernate.testing.RequiresDialectFeature;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
|
@ -25,14 +23,6 @@ import static org.junit.Assert.assertEquals;
|
|||
/**
|
||||
* @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 {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,89 +15,71 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.Lob;
|
||||
|
||||
import org.hibernate.Session;
|
||||
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.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.junit.Test;
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
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.fail;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@SkipForDialect(
|
||||
value = {
|
||||
PostgreSQL81Dialect.class,
|
||||
MySQL5Dialect.class,
|
||||
AbstractHANADialect.class,
|
||||
CockroachDialect.class,
|
||||
DB2Dialect.class
|
||||
},
|
||||
@Jpa(annotatedClasses = NClobTest.Product.class)
|
||||
@RequiresDialectFeature(
|
||||
feature = DialectFeatureChecks.SupportsNationalizedDataTypes.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 NClobTest extends BaseEntityManagerFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
|
||||
public class NClobTest {
|
||||
@Test
|
||||
public void test() {
|
||||
Integer productId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Session session = entityManager.unwrap( Session.class );
|
||||
public void test(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
(entityManager) -> {
|
||||
//tag::basic-nclob-persist-example[]
|
||||
String warranty = "My product warranty";
|
||||
|
||||
//tag::basic-nclob-persist-example[]
|
||||
String warranty = "My product warranty";
|
||||
final Product product = new Product();
|
||||
product.setId( 1 );
|
||||
product.setName( "Mobile phone" );
|
||||
|
||||
final Product product = new Product();
|
||||
product.setId( 1 );
|
||||
product.setName( "Mobile phone" );
|
||||
product.setWarranty( NClobProxy.generateProxy( warranty ) );
|
||||
|
||||
product.setWarranty( NClobProxy.generateProxy( warranty ) );
|
||||
|
||||
entityManager.persist( product );
|
||||
//end::basic-nclob-persist-example[]
|
||||
|
||||
return product.getId();
|
||||
} );
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
try {
|
||||
//tag::basic-nclob-find-example[]
|
||||
|
||||
Product product = entityManager.find( Product.class, productId );
|
||||
|
||||
try (Reader reader = product.getWarranty().getCharacterStream()) {
|
||||
assertEquals( "My product warranty", toString( reader ) );
|
||||
entityManager.persist( product );
|
||||
//end::basic-nclob-persist-example[]
|
||||
}
|
||||
//end::basic-nclob-find-example[]
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e.getMessage() );
|
||||
}
|
||||
} );
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
(entityManager) -> {
|
||||
try {
|
||||
//tag::basic-nclob-find-example[]
|
||||
Product product = entityManager.find( Product.class, 1 );
|
||||
|
||||
try ( Reader reader = product.getWarranty().getCharacterStream() ) {
|
||||
assertEquals( "My product warranty", toString( reader ) );
|
||||
}
|
||||
//end::basic-nclob-find-example[]
|
||||
}
|
||||
catch (Exception e) {
|
||||
fail( e.getMessage() );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private String toString(Reader reader) throws IOException {
|
||||
BufferedReader bufferedReader = new BufferedReader( reader);
|
||||
BufferedReader bufferedReader = new BufferedReader( reader );
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
|
||||
int result = bufferedReader.read();
|
||||
|
||||
while(result != -1) {
|
||||
byteArrayOutputStream.write((byte) result);
|
||||
while ( result != -1 ) {
|
||||
byteArrayOutputStream.write( (byte) result );
|
||||
result = bufferedReader.read();
|
||||
}
|
||||
|
||||
|
@ -122,7 +104,7 @@ public class NClobTest extends BaseEntityManagerFunctionalTestCase {
|
|||
|
||||
//Getters and setters are omitted for brevity
|
||||
|
||||
//end::basic-nclob-example[]
|
||||
//end::basic-nclob-example[]
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -150,4 +132,4 @@ public class NClobTest extends BaseEntityManagerFunctionalTestCase {
|
|||
//tag::basic-nclob-example[]
|
||||
}
|
||||
//end::basic-nclob-example[]
|
||||
}
|
||||
}
|
|
@ -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,84 +16,163 @@ import javax.persistence.Table;
|
|||
import org.hibernate.annotations.Subselect;
|
||||
import org.hibernate.annotations.Synchronize;
|
||||
import org.hibernate.dialect.DerbyDialect;
|
||||
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.junit.Test;
|
||||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@SkipForDialect(value = DerbyDialect.class, comment = "Derby doesn't support a CONCAT function")
|
||||
public class SubselectTest extends BaseEntityManagerFunctionalTestCase {
|
||||
@Jpa(
|
||||
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
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Client.class,
|
||||
Account.class,
|
||||
AccountTransaction.class,
|
||||
AccountSummary.class
|
||||
};
|
||||
@Test
|
||||
public void testNormalLifecycle(EntityManagerFactoryScope scope) {
|
||||
// same as `#testRefreshLifecycle` except that here we do not rely on
|
||||
// `Session#refresh` which atm in 6.0 dev does not appear to work properly
|
||||
// at least in this scenario
|
||||
|
||||
// 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
|
||||
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[]
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
Client client = new Client();
|
||||
client.setId( 1L );
|
||||
client.setFirstName( "John" );
|
||||
client.setLastName( "Doe" );
|
||||
entityManager.persist( client );
|
||||
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 );
|
||||
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 );
|
||||
AccountTransaction transaction = new AccountTransaction();
|
||||
transaction.setAccount( account );
|
||||
transaction.setDescription( "Salary" );
|
||||
transaction.setCents( 100 * 7000 );
|
||||
entityManager.persist( transaction );
|
||||
|
||||
AccountSummary summary = entityManager.createQuery(
|
||||
"select s " +
|
||||
"from AccountSummary s " +
|
||||
"where s.id = :id", AccountSummary.class)
|
||||
.setParameter( "id", account.getId() )
|
||||
.getSingleResult();
|
||||
AccountSummary summary = entityManager.createQuery(
|
||||
"select s " +
|
||||
"from AccountSummary s " +
|
||||
"where s.id = :id", AccountSummary.class)
|
||||
.setParameter( "id", account.getId() )
|
||||
.getSingleResult();
|
||||
|
||||
assertEquals( "John Doe", summary.getClientName() );
|
||||
assertEquals( 100 * 7000, summary.getBalance() );
|
||||
} );
|
||||
assertEquals( "John Doe", summary.getClientName() );
|
||||
assertEquals( 100 * 7000, summary.getBalance() );
|
||||
}
|
||||
);
|
||||
//end::mapping-Subselect-entity-find-example[]
|
||||
|
||||
//tag::mapping-Subselect-entity-refresh-example[]
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
AccountSummary summary = entityManager.find( AccountSummary.class, 1L );
|
||||
assertEquals( "John Doe", summary.getClientName() );
|
||||
assertEquals( 100 * 7000, summary.getBalance() );
|
||||
scope.inTransaction(
|
||||
(entityManager) -> {
|
||||
AccountSummary summary = entityManager.find( AccountSummary.class, 1L );
|
||||
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 );
|
||||
entityManager.flush();
|
||||
|
||||
entityManager.refresh( summary );
|
||||
assertEquals( 100 * 4800, summary.getBalance() );
|
||||
} );
|
||||
AccountTransaction transaction = new AccountTransaction();
|
||||
transaction.setAccount( entityManager.getReference( Account.class, 1L ) );
|
||||
transaction.setDescription( "Shopping" );
|
||||
transaction.setCents( -100 * 2200 );
|
||||
entityManager.persist( transaction );
|
||||
entityManager.flush();
|
||||
|
||||
entityManager.refresh( summary );
|
||||
assertEquals( 100 * 4800, summary.getBalance() );
|
||||
}
|
||||
);
|
||||
//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[]
|
||||
@Entity(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 IMPORT_SQL_PCKG = 'org.hibernate.grammars.importsql'
|
||||
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.Target;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Marks a character data type (String, Character, character, Clob) as being a nationalized variant
|
||||
* (NVARCHAR, NCHAR, NCLOB, etc).
|
||||
* Used to indicate that the annotated character data should be stored with
|
||||
* 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
|
||||
*/
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.boot.model.process.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
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.OrdinalEnumValueConverter;
|
||||
import org.hibernate.metamodel.model.domain.AllowableTemporalParameterType;
|
||||
import org.hibernate.type.AdjustableBasicType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CustomType;
|
||||
import org.hibernate.type.SerializableType;
|
||||
import org.hibernate.type.SqlTypeDescriptorIndicatorCapable;
|
||||
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
|
||||
import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor;
|
||||
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.jdbc.JdbcTypeDescriptor;
|
||||
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.spi.TypeConfiguration;
|
||||
|
||||
|
@ -76,23 +78,57 @@ public class InferredBasicValueResolver {
|
|||
explicitJavaType,
|
||||
explicitJdbcType
|
||||
);
|
||||
legacyType = jdbcMapping;
|
||||
}
|
||||
else {
|
||||
// infer the STD
|
||||
// we need to infer the JdbcTypeDescriptor and use that to build the value-mapping
|
||||
final JdbcTypeDescriptor inferredJdbcType = explicitJavaType.getRecommendedJdbcType( stdIndicators );
|
||||
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
|
||||
explicitJavaType,
|
||||
inferredJdbcType
|
||||
);
|
||||
}
|
||||
if ( inferredJdbcType instanceof ObjectJdbcTypeDescriptor ) {
|
||||
// have a "fallback" JDBC type... see if we can decide a better choice
|
||||
|
||||
legacyType = jdbcMapping;
|
||||
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(
|
||||
explicitJavaType,
|
||||
inferredJdbcType
|
||||
);
|
||||
legacyType = jdbcMapping;
|
||||
}
|
||||
}
|
||||
else {
|
||||
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
|
||||
explicitJavaType,
|
||||
inferredJdbcType
|
||||
);
|
||||
legacyType = jdbcMapping;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( reflectedJtd != null ) {
|
||||
// we were able to determine the "reflected java-type"
|
||||
|
||||
if ( explicitJdbcType != null ) {
|
||||
// we also have an explicit @SqlType(Code)
|
||||
// we also have an explicit @JdbcType(Code)
|
||||
|
||||
jdbcMapping = typeConfiguration.getBasicTypeRegistry().resolve(
|
||||
reflectedJtd,
|
||||
|
@ -107,8 +143,8 @@ public class InferredBasicValueResolver {
|
|||
if ( reflectedJtd instanceof EnumJavaTypeDescriptor ) {
|
||||
return fromEnum(
|
||||
(EnumJavaTypeDescriptor) reflectedJtd,
|
||||
explicitJavaTypeAccess.apply( typeConfiguration ),
|
||||
explicitSqlTypeAccess.apply( typeConfiguration ),
|
||||
null,
|
||||
null,
|
||||
stdIndicators,
|
||||
typeConfiguration
|
||||
);
|
||||
|
@ -116,8 +152,8 @@ public class InferredBasicValueResolver {
|
|||
else if ( reflectedJtd instanceof TemporalJavaTypeDescriptor ) {
|
||||
return fromTemporal(
|
||||
(TemporalJavaTypeDescriptor) reflectedJtd,
|
||||
explicitJavaTypeAccess,
|
||||
explicitSqlTypeAccess,
|
||||
null,
|
||||
null,
|
||||
stdIndicators,
|
||||
typeConfiguration
|
||||
);
|
||||
|
@ -128,12 +164,11 @@ public class InferredBasicValueResolver {
|
|||
final BasicType registeredType = typeConfiguration.getBasicTypeRegistry().getRegisteredType( reflectedJtd.getJavaType() );
|
||||
|
||||
if ( registeredType != null ) {
|
||||
// reuse the "legacy type"
|
||||
legacyType = resolveSqlTypeIndicators( stdIndicators, registeredType );
|
||||
legacyType = resolveSqlTypeIndicators( stdIndicators, registeredType, reflectedJtd );
|
||||
jdbcMapping = legacyType;
|
||||
}
|
||||
else if ( reflectedJtd instanceof SerializableTypeDescriptor ) {
|
||||
legacyType = new SerializableType<>( reflectedJtd.getJavaTypeClass() );
|
||||
else if ( reflectedJtd instanceof SerializableTypeDescriptor || reflectedJtd.getJavaType() instanceof Serializable ) {
|
||||
legacyType = new SerializableType<>( reflectedJtd );
|
||||
jdbcMapping = legacyType;
|
||||
}
|
||||
else {
|
||||
|
@ -154,7 +189,7 @@ public class InferredBasicValueResolver {
|
|||
explicitJdbcType
|
||||
);
|
||||
|
||||
jdbcMapping = resolveSqlTypeIndicators( stdIndicators, resolved );
|
||||
jdbcMapping = resolveSqlTypeIndicators( stdIndicators, resolved, recommendedJtd );
|
||||
legacyType = jdbcMapping;
|
||||
}
|
||||
else {
|
||||
|
@ -193,10 +228,11 @@ public class InferredBasicValueResolver {
|
|||
@SuppressWarnings("rawtypes")
|
||||
public static BasicType<?> resolveSqlTypeIndicators(
|
||||
JdbcTypeDescriptorIndicators stdIndicators,
|
||||
BasicType<?> resolved) {
|
||||
if ( resolved instanceof SqlTypeDescriptorIndicatorCapable ) {
|
||||
final SqlTypeDescriptorIndicatorCapable indicatorCapable = (SqlTypeDescriptorIndicatorCapable) resolved;
|
||||
final BasicType indicatedType = indicatorCapable.resolveIndicatedType( stdIndicators );
|
||||
BasicType<?> resolved,
|
||||
JavaTypeDescriptor<?> domainJtd) {
|
||||
if ( resolved instanceof AdjustableBasicType ) {
|
||||
final AdjustableBasicType indicatorCapable = (AdjustableBasicType) resolved;
|
||||
final BasicType indicatedType = indicatorCapable.resolveIndicatedType( stdIndicators, domainJtd );
|
||||
return indicatedType != null ? indicatedType : resolved;
|
||||
}
|
||||
else {
|
||||
|
@ -322,28 +358,12 @@ public class InferredBasicValueResolver {
|
|||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static InferredBasicValueResolution fromTemporal(
|
||||
TemporalJavaTypeDescriptor reflectedJtd,
|
||||
Function<TypeConfiguration, BasicJavaDescriptor> explicitJavaTypeAccess,
|
||||
Function<TypeConfiguration, JdbcTypeDescriptor> explicitSqlTypeAccess,
|
||||
BasicJavaDescriptor explicitJavaType,
|
||||
JdbcTypeDescriptor explicitJdbcType,
|
||||
JdbcTypeDescriptorIndicators stdIndicators,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
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
|
||||
|
||||
|
|
|
@ -40,7 +40,10 @@ import org.hibernate.engine.config.spi.StandardConverters;
|
|||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.BasicTypeRegistry;
|
||||
import org.hibernate.type.CustomType;
|
||||
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.spi.TypeConfiguration;
|
||||
import org.hibernate.usertype.UserType;
|
||||
|
@ -355,16 +358,33 @@ public class MetadataBuildingProcess {
|
|||
@Override
|
||||
public void contributeType(org.hibernate.type.BasicType 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
|
||||
public void contributeType(BasicType type, String... keys) {
|
||||
getBasicTypeRegistry().register( type, keys );
|
||||
conditionallyRegisterJtd( type.getJavaTypeDescriptor() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeType(UserType type, String[] keys) {
|
||||
getBasicTypeRegistry().register( type, keys );
|
||||
contributeType( new CustomType( type, keys, getTypeConfiguration() ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -383,7 +403,7 @@ public class MetadataBuildingProcess {
|
|||
}
|
||||
|
||||
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.Immutable;
|
||||
import org.hibernate.annotations.JavaType;
|
||||
import org.hibernate.annotations.JdbcType;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.annotations.MapKeyJavaType;
|
||||
import org.hibernate.annotations.MapKeyJdbcType;
|
||||
import org.hibernate.annotations.MapKeyJdbcTypeCode;
|
||||
|
@ -33,8 +35,6 @@ import org.hibernate.annotations.MapKeyType;
|
|||
import org.hibernate.annotations.Mutability;
|
||||
import org.hibernate.annotations.Nationalized;
|
||||
import org.hibernate.annotations.Parameter;
|
||||
import org.hibernate.annotations.JdbcType;
|
||||
import org.hibernate.annotations.JdbcTypeCode;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.annotations.common.reflection.XClass;
|
||||
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.SetBasicValueTypeSecondPass;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.NationalizationSupport;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
|
@ -256,7 +257,7 @@ public class BasicValueBinder<T> implements JdbcTypeDescriptorIndicators {
|
|||
isLob = modelXProperty.isAnnotationPresent( Lob.class );
|
||||
}
|
||||
|
||||
if ( getDialect().supportsNationalizedTypes() ) {
|
||||
if ( getDialect().getNationalizationSupport() == NationalizationSupport.EXPLICIT ) {
|
||||
isNationalized = modelXProperty.isAnnotationPresent( Nationalized.class )
|
||||
|| buildingContext.getBuildingOptions().useNationalizedCharacterData();
|
||||
}
|
||||
|
|
|
@ -234,8 +234,9 @@ public class CockroachDialect extends Dialect {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNationalizedTypes() {
|
||||
return false;
|
||||
public NationalizationSupport getNationalizationSupport() {
|
||||
// TEXT / STRING inherently support nationalized data
|
||||
return NationalizationSupport.IMPLICIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -74,6 +74,7 @@ public class DerbyDialect extends Dialect {
|
|||
|
||||
// KNOWN LIMITATIONS:
|
||||
|
||||
// no support for nationalized data (nchar, nvarchar, nclob)
|
||||
// * limited set of fields for extract()
|
||||
// (no 'day of xxxx', nor 'week of xxxx')
|
||||
// * no support for format()
|
||||
|
@ -160,6 +161,11 @@ public class DerbyDialect extends Dialect {
|
|||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NationalizationSupport getNationalizationSupport() {
|
||||
return NationalizationSupport.IMPLICIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFloatPrecision() {
|
||||
return 23;
|
||||
|
|
|
@ -82,6 +82,10 @@ import org.hibernate.type.Type;
|
|||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.ClobTypeDescriptor;
|
||||
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 javax.persistence.TemporalType;
|
||||
|
@ -958,7 +962,15 @@ public abstract class Dialect implements ConversionContext {
|
|||
* @param serviceRegistry The service registry
|
||||
*/
|
||||
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 {
|
||||
|
@ -3441,9 +3453,18 @@ public abstract class Dialect implements ConversionContext {
|
|||
* Does this dialect supports Nationalized Types
|
||||
*
|
||||
* @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() {
|
||||
return true;
|
||||
@Deprecated
|
||||
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
|
||||
public boolean supportsNationalizedTypes() {
|
||||
return false;
|
||||
public NationalizationSupport getNationalizationSupport() {
|
||||
return NationalizationSupport.IMPLICIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -14,7 +14,6 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
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.AttributeConverterTypeAdapter;
|
||||
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.NationalizedTypeMappings;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
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.results.ResultBuilderBasicValued;
|
||||
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.CustomType;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
import org.hibernate.usertype.UserType;
|
||||
|
||||
/**
|
||||
* Implementation of ResultMappingMemento for scalar (basic) results.
|
||||
|
@ -60,6 +64,8 @@ public class ResultMementoBasicStandard implements ResultMementoBasic {
|
|||
ResultSetMappingResolutionContext context) {
|
||||
this.explicitColumnName = definition.name();
|
||||
|
||||
BasicType resolvedBasicType = null;
|
||||
|
||||
final Class<?> definedType = definition.type();
|
||||
if ( void.class == definedType ) {
|
||||
explicitJavaTypeDescriptor = null;
|
||||
|
@ -67,11 +73,35 @@ public class ResultMementoBasicStandard implements ResultMementoBasic {
|
|||
else {
|
||||
final SessionFactoryImplementor sessionFactory = context.getSessionFactory();
|
||||
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
||||
final JavaTypeDescriptorRegistry jtdRegistry = typeConfiguration.getJavaTypeDescriptorRegistry();
|
||||
this.explicitJavaTypeDescriptor = jtdRegistry.getDescriptor( definition.type() );
|
||||
|
||||
// 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 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() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
explicitType = null;
|
||||
explicitType = resolvedBasicType;
|
||||
}
|
||||
|
||||
public ResultMementoBasicStandard(
|
||||
|
|
|
@ -41,6 +41,11 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
|||
String explicitColumnName,
|
||||
BasicValuedMapping explicitType,
|
||||
JavaTypeDescriptor<?> explicitJavaTypeDescriptor) {
|
||||
assert explicitType == null || explicitType.getJdbcMapping()
|
||||
.getJavaTypeDescriptor()
|
||||
.getJavaTypeClass()
|
||||
.isAssignableFrom( explicitJavaTypeDescriptor.getJavaTypeClass() );
|
||||
|
||||
this.explicitColumnName = explicitColumnName;
|
||||
this.explicitType = explicitType;
|
||||
this.explicitJavaTypeDescriptor = explicitJavaTypeDescriptor;
|
||||
|
@ -63,6 +68,35 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
|||
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(
|
||||
creationStateImpl.resolveSqlExpression(
|
||||
columnName,
|
||||
|
@ -74,7 +108,6 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
|||
else {
|
||||
jdbcPosition = resultPosition + 1;
|
||||
}
|
||||
final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||
|
||||
final BasicValuedMapping basicType;
|
||||
if ( explicitType != null ) {
|
||||
|
@ -83,6 +116,8 @@ public class CompleteResultBuilderBasicValuedStandard implements CompleteResultB
|
|||
else {
|
||||
basicType = jdbcResultsMetadata.resolveType( jdbcPosition, explicitJavaTypeDescriptor );
|
||||
}
|
||||
|
||||
final int valuesArrayPosition = ResultsHelper.jdbcPositionToValuesArrayPosition( jdbcPosition );
|
||||
return new SqlSelectionImpl( valuesArrayPosition, basicType );
|
||||
}
|
||||
),
|
||||
|
|
|
@ -2351,7 +2351,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
getFromClauseAccess()::findTableGroup
|
||||
);
|
||||
if ( localExpressable instanceof BasicType<?> ) {
|
||||
expressable = InferredBasicValueResolver.resolveSqlTypeIndicators( this, (BasicType<?>) localExpressable );
|
||||
expressable = InferredBasicValueResolver.resolveSqlTypeIndicators(
|
||||
this,
|
||||
(BasicType<?>) localExpressable,
|
||||
literal.getJavaTypeDescriptor()
|
||||
);
|
||||
}
|
||||
else {
|
||||
expressable = localExpressable;
|
||||
|
@ -2761,7 +2765,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
public Object visitCastTarget(SqmCastTarget target) {
|
||||
BasicValuedMapping targetType = (BasicValuedMapping) target.getType();
|
||||
if ( targetType instanceof BasicType<?> ) {
|
||||
targetType = InferredBasicValueResolver.resolveSqlTypeIndicators( this, (BasicType<?>) targetType );
|
||||
targetType = InferredBasicValueResolver.resolveSqlTypeIndicators(
|
||||
this,
|
||||
(BasicType<?>) targetType,
|
||||
target.getNodeJavaTypeDescriptor()
|
||||
);
|
||||
}
|
||||
return new CastTarget(
|
||||
targetType.getJdbcMapping(),
|
||||
|
|
|
@ -72,12 +72,12 @@ public abstract class AbstractStandardBasicType<T>
|
|||
}
|
||||
|
||||
@Override
|
||||
public ValueExtractor getJdbcValueExtractor() {
|
||||
public ValueExtractor<T> getJdbcValueExtractor() {
|
||||
return jdbcValueExtractor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueBinder getJdbcValueBinder() {
|
||||
public ValueBinder<T> getJdbcValueBinder() {
|
||||
return jdbcValueBinder;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
default int forEachJdbcType(IndexedConsumer<JdbcMapping> action) {
|
||||
action.accept( 0, this );
|
||||
|
|
|
@ -50,6 +50,11 @@ public class BasicTypeRegistry implements Serializable {
|
|||
}
|
||||
|
||||
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() );
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,17 @@
|
|||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import java.sql.Types;
|
||||
import java.util.Comparator;
|
||||
|
||||
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.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
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[]}
|
||||
|
@ -23,7 +29,7 @@ import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
|||
*/
|
||||
public class BinaryType
|
||||
extends AbstractSingleColumnStandardBasicType<byte[]>
|
||||
implements VersionType<byte[]> {
|
||||
implements VersionType<byte[]>, AdjustableBasicType<byte[]> {
|
||||
|
||||
public static final BinaryType INSTANCE = new BinaryType();
|
||||
|
||||
|
@ -82,4 +88,18 @@ public class BinaryType
|
|||
public Comparator<byte[]> 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.sql.Types;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
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.JdbcTypeDescriptorIndicators;
|
||||
|
||||
|
@ -22,7 +24,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
|||
*/
|
||||
public class BooleanType
|
||||
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 BooleanType() {
|
||||
|
@ -32,6 +34,12 @@ public class BooleanType
|
|||
protected BooleanType(JdbcTypeDescriptor jdbcTypeDescriptor, BooleanTypeDescriptor javaTypeDescriptor) {
|
||||
super( jdbcTypeDescriptor, javaTypeDescriptor );
|
||||
}
|
||||
|
||||
@Incubating
|
||||
public BooleanType(JdbcTypeDescriptor jdbcTypeDescriptor, JavaTypeDescriptor<Boolean> javaTypeDescriptor) {
|
||||
super( jdbcTypeDescriptor, javaTypeDescriptor );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "boolean";
|
||||
|
@ -60,7 +68,9 @@ public class BooleanType
|
|||
}
|
||||
|
||||
@Override
|
||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
||||
public <X> BasicType<X> resolveIndicatedType(
|
||||
JdbcTypeDescriptorIndicators indicators,
|
||||
JavaTypeDescriptor<X> domainJtd) {
|
||||
final int preferredSqlTypeCodeForBoolean = indicators.getPreferredSqlTypeCodeForBoolean();
|
||||
final JdbcTypeDescriptor jdbcTypeDescriptor;
|
||||
// We treat BIT like BOOLEAN because it uses the same JDBC access methods
|
||||
|
|
|
@ -7,10 +7,13 @@
|
|||
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.jdbc.JdbcTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
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[]}
|
||||
|
@ -20,7 +23,7 @@ import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
|||
*/
|
||||
public class CharArrayType
|
||||
extends AbstractSingleColumnStandardBasicType<char[]>
|
||||
implements SqlTypeDescriptorIndicatorCapable<char[]> {
|
||||
implements AdjustableBasicType<char[]> {
|
||||
public static final CharArrayType INSTANCE = new CharArrayType();
|
||||
|
||||
public CharArrayType() {
|
||||
|
@ -37,22 +40,23 @@ public class CharArrayType
|
|||
}
|
||||
|
||||
@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() ) {
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) ( indicators.isNationalized() ? CharacterArrayNClobType.INSTANCE : CharacterArrayClobType.INSTANCE );
|
||||
jdbcTypeCode = indicators.isNationalized() ? Types.NCLOB : Types.CLOB;
|
||||
}
|
||||
else {
|
||||
jdbcTypeCode = indicators.isNationalized() ? Types.NVARCHAR : Types.VARCHAR;
|
||||
}
|
||||
|
||||
if ( indicators.isNationalized() ) {
|
||||
final JdbcTypeDescriptor nvarcharType = indicators.getTypeConfiguration()
|
||||
.getJdbcTypeDescriptorRegistry()
|
||||
.getDescriptor( Types.NVARCHAR );
|
||||
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) indicators.getTypeConfiguration().getBasicTypeRegistry().resolve( getJavaTypeDescriptor(), nvarcharType );
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) this;
|
||||
final JdbcTypeDescriptor jdbcType = jdbcTypeRegistry.getDescriptor( jdbcTypeCode );
|
||||
return typeConfiguration.getBasicTypeRegistry().resolve( domainJtd, jdbcType );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,15 @@
|
|||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
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.JdbcTypeDescriptor;
|
||||
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[]}
|
||||
|
@ -20,7 +26,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
|||
*/
|
||||
public class CharacterArrayClobType
|
||||
extends AbstractSingleColumnStandardBasicType<Character[]>
|
||||
implements SqlTypeDescriptorIndicatorCapable<Character[]> {
|
||||
implements AdjustableBasicType<Character[]> {
|
||||
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
|
||||
|
||||
public CharacterArrayClobType() {
|
||||
|
@ -33,8 +39,23 @@ public class CharacterArrayClobType
|
|||
}
|
||||
|
||||
@Override
|
||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
||||
//noinspection unchecked
|
||||
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 = 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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,15 @@
|
|||
*/
|
||||
package org.hibernate.type;
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
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.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* 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 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 CharacterArrayNClobType() {
|
||||
|
@ -29,4 +38,23 @@ public class CharacterArrayNClobType extends AbstractSingleColumnStandardBasicTy
|
|||
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 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.VarcharTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -21,7 +23,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
*/
|
||||
public class CharacterArrayType
|
||||
extends AbstractSingleColumnStandardBasicType<Character[]>
|
||||
implements SqlTypeDescriptorIndicatorCapable<Character[]> {
|
||||
implements AdjustableBasicType<Character[]> {
|
||||
public static final CharacterArrayType INSTANCE = new CharacterArrayType();
|
||||
|
||||
public CharacterArrayType() {
|
||||
|
@ -38,26 +40,36 @@ public class CharacterArrayType
|
|||
}
|
||||
|
||||
@Override
|
||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
||||
if ( indicators.isNationalized() ) {
|
||||
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||
if ( indicators.isLob() ) {
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) CharacterArrayNClobType.INSTANCE;
|
||||
}
|
||||
else {
|
||||
final JdbcTypeDescriptor nvarcharType = typeConfiguration.getJdbcTypeDescriptorRegistry().getDescriptor( Types.NVARCHAR );
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) typeConfiguration.getBasicTypeRegistry().resolve( getJavaTypeDescriptor(), nvarcharType );
|
||||
}
|
||||
}
|
||||
public <X> BasicType<X> resolveIndicatedType(
|
||||
JdbcTypeDescriptorIndicators indicators,
|
||||
JavaTypeDescriptor<X> domainJtd) {
|
||||
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||
|
||||
final int jdbcTypeCode;
|
||||
if ( indicators.isLob() ) {
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) CharacterArrayClobType.INSTANCE;
|
||||
jdbcTypeCode = indicators.isNationalized() ? Types.NCLOB : Types.CLOB;
|
||||
}
|
||||
else {
|
||||
jdbcTypeCode = indicators.isNationalized() ? Types.NVARCHAR : Types.VARCHAR;
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) this;
|
||||
final JdbcTypeDescriptor indicatedJdbcType = jdbcTypeRegistry.getDescriptor( jdbcTypeCode );
|
||||
|
||||
if ( domainJtd != null && domainJtd.getJavaTypeClass() == Character[].class ) {
|
||||
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||
typeConfiguration.getJavaTypeDescriptorRegistry().resolveDescriptor( domainJtd.getJavaType() ),
|
||||
indicatedJdbcType
|
||||
);
|
||||
}
|
||||
|
||||
if ( getJdbcTypeDescriptor() == indicatedJdbcType ) {
|
||||
return (BasicType<X>) this;
|
||||
}
|
||||
|
||||
return (BasicType<X>) typeConfiguration.getBasicTypeRegistry().resolve(
|
||||
getJavaTypeDescriptor(),
|
||||
indicatedJdbcType
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,16 @@
|
|||
package org.hibernate.type;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
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.JdbcTypeDescriptor;
|
||||
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}
|
||||
|
@ -21,7 +26,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
|||
*/
|
||||
public class CharacterType
|
||||
extends AbstractSingleColumnStandardBasicType<Character>
|
||||
implements PrimitiveType<Character>, DiscriminatorType<Character>, SqlTypeDescriptorIndicatorCapable<Character> {
|
||||
implements PrimitiveType<Character>, DiscriminatorType<Character>, AdjustableBasicType<Character> {
|
||||
|
||||
public static final CharacterType INSTANCE = new CharacterType();
|
||||
|
||||
|
@ -55,7 +60,15 @@ public class CharacterType
|
|||
}
|
||||
|
||||
@Override
|
||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
||||
return (BasicType<X>) ( indicators.isNationalized() ? CharacterNCharType.INSTANCE : this );
|
||||
public <X> BasicType<X> resolveIndicatedType(
|
||||
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;
|
||||
|
||||
import java.sql.Clob;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
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.spi.JdbcTypeDescriptorRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* 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 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 ClobType() {
|
||||
|
@ -40,16 +44,21 @@ public class ClobType extends AbstractSingleColumnStandardBasicType<Clob> implem
|
|||
return session.getJdbcServices().getJdbcEnvironment().getDialect().getLobMergeStrategy().mergeClob( original, target, session );
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Override
|
||||
public BasicType resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
||||
// todo (6.0) : Support a "wrapped clob"? This would be a (N)VARCHAR column we handle as a Clob in-memory
|
||||
// - might be especially interesting for streaming based (N)VARCHAR reading
|
||||
|
||||
if ( indicators.isNationalized() ) {
|
||||
return NClobType.INSTANCE;
|
||||
@SuppressWarnings( "unchecked" )
|
||||
public <X> BasicType<X> resolveIndicatedType(
|
||||
JdbcTypeDescriptorIndicators indicators,
|
||||
JavaTypeDescriptor<X> domainJtd) {
|
||||
if ( ! indicators.isNationalized() ) {
|
||||
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.type.descriptor.ValueBinder;
|
||||
import org.hibernate.type.descriptor.ValueExtractor;
|
||||
import org.hibernate.type.descriptor.WrapperOptions;
|
||||
import org.hibernate.type.descriptor.java.BasicJavaDescriptor;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.JavaTypedExpressable;
|
||||
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.usertype.EnhancedUserType;
|
||||
import org.hibernate.usertype.LoggableUserType;
|
||||
import org.hibernate.usertype.Sized;
|
||||
import org.hibernate.usertype.UserType;
|
||||
import org.hibernate.usertype.UserVersionType;
|
||||
|
@ -51,23 +53,22 @@ import org.hibernate.usertype.UserVersionType;
|
|||
*/
|
||||
public class CustomType
|
||||
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 name;
|
||||
|
||||
private final JavaTypeDescriptor mappedJavaTypeDescriptor;
|
||||
private final BasicJavaDescriptor<Object> mappedJavaTypeDescriptor;
|
||||
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 defaultSize;
|
||||
|
||||
private final boolean customLogging;
|
||||
|
||||
public CustomType(UserType userType, TypeConfiguration typeConfiguration) throws MappingException {
|
||||
this( userType, ArrayHelper.EMPTY_STRING_ARRAY, typeConfiguration );
|
||||
}
|
||||
|
@ -76,9 +77,23 @@ public class CustomType
|
|||
this.userType = userType;
|
||||
this.name = userType.getClass().getName();
|
||||
|
||||
//noinspection unchecked
|
||||
this.mappedJavaTypeDescriptor = typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( userType.returnedClass() );
|
||||
this.jdbcTypeDescriptor = typeConfiguration.getJdbcTypeDescriptorRegistry().getDescriptor( userType.sqlTypes()[0] );
|
||||
if ( userType instanceof BasicJavaDescriptor ) {
|
||||
//noinspection rawtypes
|
||||
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 ) {
|
||||
final Sized sized = (Sized) userType;
|
||||
|
@ -90,35 +105,11 @@ public class CustomType
|
|||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueBinder<?> getJdbcValueBinder() {
|
||||
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() );
|
||||
}
|
||||
}
|
||||
public UserType getUserType() {
|
||||
return userType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -126,8 +117,9 @@ public class CustomType
|
|||
return valueExtractor;
|
||||
}
|
||||
|
||||
public UserType getUserType() {
|
||||
return userType;
|
||||
@Override
|
||||
public ValueBinder<?> getJdbcValueBinder() {
|
||||
return valueBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -181,7 +173,7 @@ public class CustomType
|
|||
String[] names,
|
||||
SharedSessionContractImplementor session,
|
||||
Object owner) throws SQLException {
|
||||
return getUserType().nullSafeGet( rs, names, session, owner);
|
||||
throw new UnsupportedOperationException( "Reading from ResultSet by name is no longer supported" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -190,7 +182,7 @@ public class CustomType
|
|||
String columnName,
|
||||
SharedSessionContractImplementor session,
|
||||
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
|
||||
|
@ -285,14 +277,10 @@ public class CustomType
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toLoggableString(Object value, SessionFactoryImplementor factory)
|
||||
throws HibernateException {
|
||||
public String toLoggableString(Object value, SessionFactoryImplementor factory) {
|
||||
if ( value == null ) {
|
||||
return "null";
|
||||
}
|
||||
else if ( customLogging ) {
|
||||
return ( ( LoggableUserType ) getUserType() ).toLoggableString( value, factory );
|
||||
}
|
||||
else {
|
||||
return toXMLString( value, factory );
|
||||
}
|
||||
|
|
|
@ -17,7 +17,9 @@ import org.hibernate.type.descriptor.java.DoubleTypeDescriptor;
|
|||
* @author Gavin King
|
||||
* @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 Double ZERO = 0.0;
|
||||
|
|
|
@ -19,7 +19,6 @@ import javax.persistence.MapKeyEnumerated;
|
|||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.annotations.Nationalized;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
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.OrdinalEnumValueConverter;
|
||||
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.EnumJavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
|
@ -78,7 +79,10 @@ public class EnumType<T extends Enum<T>>
|
|||
|
||||
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;
|
||||
|
||||
|
@ -90,8 +94,12 @@ public class EnumType<T extends Enum<T>>
|
|||
EnumValueConverter enumValueConverter,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
this.enumClass = enumClass;
|
||||
this.enumValueConverter = enumValueConverter;
|
||||
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() {
|
||||
|
@ -171,6 +179,9 @@ public class EnumType<T extends Enum<T>>
|
|||
}
|
||||
|
||||
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() ) {
|
||||
|
@ -217,7 +228,7 @@ public class EnumType<T extends Enum<T>>
|
|||
return null;
|
||||
}
|
||||
|
||||
private EnumValueConverter<T,?> interpretParameters(Properties parameters) {
|
||||
private EnumValueConverter<T,Object> interpretParameters(Properties parameters) {
|
||||
//noinspection rawtypes
|
||||
final EnumJavaTypeDescriptor enumJavaDescriptor = (EnumJavaTypeDescriptor) typeConfiguration
|
||||
.getJavaTypeDescriptorRegistry()
|
||||
|
@ -349,14 +360,14 @@ public class EnumType<T extends Enum<T>>
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
|
||||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
// verifyConfigured();
|
||||
// return enumValueConverter.readValue( rs, names[0], session );
|
||||
public Object nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
|
||||
verifyConfigured();
|
||||
final Object relational = jdbcValueExtractor.extract( rs, position, session );
|
||||
return enumValueConverter.toDomainValue( relational );
|
||||
}
|
||||
|
||||
private void verifyConfigured() {
|
||||
if ( enumValueConverter == null ) {
|
||||
if ( enumValueConverter == null || jdbcValueBinder == null || jdbcValueExtractor == null ) {
|
||||
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>.
|
||||
*/
|
||||
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.jdbc.ClobTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor;
|
||||
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}
|
||||
|
@ -18,7 +24,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
|||
*/
|
||||
public class MaterializedClobType
|
||||
extends AbstractSingleColumnStandardBasicType<String>
|
||||
implements SqlTypeDescriptorIndicatorCapable<String> {
|
||||
implements AdjustableBasicType<String> {
|
||||
public static final MaterializedClobType INSTANCE = new MaterializedClobType();
|
||||
|
||||
public MaterializedClobType() {
|
||||
|
@ -30,10 +36,18 @@ public class MaterializedClobType
|
|||
}
|
||||
|
||||
@Override
|
||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
||||
public <X> BasicType<X> resolveIndicatedType(
|
||||
JdbcTypeDescriptorIndicators indicators,
|
||||
JavaTypeDescriptor<X> domainJtd) {
|
||||
if ( indicators.isNationalized() ) {
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) MaterializedNClobType.INSTANCE;
|
||||
final TypeConfiguration typeConfiguration = indicators.getTypeConfiguration();
|
||||
final JdbcTypeDescriptorRegistry jdbcTypeRegistry = typeConfiguration.getJdbcTypeDescriptorRegistry();
|
||||
final JdbcTypeDescriptor nclobType = jdbcTypeRegistry.getDescriptor( Types.NCLOB );
|
||||
|
||||
return typeConfiguration.getBasicTypeRegistry().resolve(
|
||||
domainJtd,
|
||||
nclobType
|
||||
);
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
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
|
||||
public Boolean toDomainValue(Integer relationalForm) {
|
||||
return toDomain( relationalForm );
|
||||
}
|
||||
|
||||
public static Boolean toDomain(Integer relationalForm) {
|
||||
if ( relationalForm == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -80,6 +89,10 @@ public class NumericBooleanType
|
|||
|
||||
@Override
|
||||
public Integer toRelationalValue(Boolean domainForm) {
|
||||
return toRelational( domainForm );
|
||||
}
|
||||
|
||||
public static Integer toRelational(Boolean domainForm) {
|
||||
if ( domainForm == 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>.
|
||||
*/
|
||||
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.jdbc.ClobTypeDescriptor;
|
||||
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
|
||||
|
@ -16,7 +21,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
|||
*/
|
||||
public class PrimitiveCharacterArrayClobType
|
||||
extends AbstractSingleColumnStandardBasicType<char[]>
|
||||
implements SqlTypeDescriptorIndicatorCapable<char[]> {
|
||||
implements AdjustableBasicType<char[]> {
|
||||
public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
|
||||
|
||||
public PrimitiveCharacterArrayClobType() {
|
||||
|
@ -29,13 +34,20 @@ public class PrimitiveCharacterArrayClobType
|
|||
}
|
||||
|
||||
@Override
|
||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
||||
if ( indicators.isNationalized() ) {
|
||||
//noinspection unchecked
|
||||
return (BasicType<X>) PrimitiveCharacterArrayNClobType.INSTANCE;
|
||||
@SuppressWarnings("unchecked")
|
||||
public <X> BasicType<X> resolveIndicatedType(
|
||||
JdbcTypeDescriptorIndicators indicators,
|
||||
JavaTypeDescriptor<X> domainJtd) {
|
||||
if ( ! indicators.isNationalized() ) {
|
||||
return (BasicType<X>) this;
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
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>.
|
||||
*/
|
||||
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.
|
||||
|
@ -13,14 +16,14 @@ import java.io.Serializable;
|
|||
* @author Gavin King
|
||||
* @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
|
||||
* {@link org.hibernate.type.Type#getReturnedClass()}.
|
||||
*
|
||||
* @return The primitive Java type.
|
||||
*/
|
||||
public abstract Class getPrimitiveClass();
|
||||
Class<?> getPrimitiveClass();
|
||||
|
||||
/**
|
||||
* Retrieve the string representation of the given value.
|
||||
|
@ -29,12 +32,18 @@ public interface PrimitiveType<T> extends LiteralType<T> {
|
|||
*
|
||||
* @return The string representation
|
||||
*/
|
||||
public String toString(T value);
|
||||
String toString(T value);
|
||||
|
||||
/**
|
||||
* Get this type's 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 org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.SerializableTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.VarbinaryTypeDescriptor;
|
||||
|
||||
/**
|
||||
* A type that maps between a {@link java.sql.Types#VARBINARY VARBINARY} and {@link Serializable} classes.
|
||||
* <p/>
|
||||
* Notice specifically the 2 forms:<ul>
|
||||
* <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>
|
||||
* Notice specifically the 3 constructors:<ul>
|
||||
* <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(JavaTypeDescriptor)} indicates a mapping using the specific JavaTypeDescriptor</li>
|
||||
* </ul>
|
||||
* 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
|
||||
* 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 Steve Ebersole
|
||||
|
@ -35,6 +37,11 @@ public class SerializableType<T extends Serializable> extends AbstractSingleColu
|
|||
this.serializableClass = serializableClass;
|
||||
}
|
||||
|
||||
public SerializableType(JavaTypeDescriptor<T> jtd) {
|
||||
super( VarbinaryTypeDescriptor.INSTANCE, jtd );
|
||||
this.serializableClass = jtd.getJavaTypeClass();
|
||||
}
|
||||
|
||||
public String 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>.
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
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}
|
||||
|
@ -18,7 +23,7 @@ import org.hibernate.type.descriptor.jdbc.VarcharTypeDescriptor;
|
|||
*/
|
||||
public class StringType
|
||||
extends AbstractSingleColumnStandardBasicType<String>
|
||||
implements DiscriminatorType<String>, SqlTypeDescriptorIndicatorCapable<String> {
|
||||
implements DiscriminatorType<String>, AdjustableBasicType<String> {
|
||||
|
||||
public static final StringType INSTANCE = new StringType();
|
||||
|
||||
|
@ -47,14 +52,33 @@ public class StringType
|
|||
return value;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@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() ) {
|
||||
return indicators.isNationalized() ? MaterializedNClobType.INSTANCE : MaterializedClobType.INSTANCE;
|
||||
jdbcTypeCode = indicators.isNationalized()
|
||||
? Types.NCLOB
|
||||
: Types.CLOB;
|
||||
}
|
||||
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>.
|
||||
*/
|
||||
package org.hibernate.type;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.java.StringTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.LongVarcharTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
|
@ -18,7 +19,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
|||
*/
|
||||
public class TextType
|
||||
extends AbstractSingleColumnStandardBasicType<String>
|
||||
implements SqlTypeDescriptorIndicatorCapable<String> {
|
||||
implements AdjustableBasicType<String> {
|
||||
public static final TextType INSTANCE = new TextType();
|
||||
|
||||
public TextType() {
|
||||
|
@ -30,7 +31,9 @@ public class TextType
|
|||
}
|
||||
|
||||
@Override
|
||||
public <X> BasicType<X> resolveIndicatedType(JdbcTypeDescriptorIndicators indicators) {
|
||||
public <X> BasicType<X> resolveIndicatedType(
|
||||
JdbcTypeDescriptorIndicators indicators,
|
||||
JavaTypeDescriptor<X> domainJtd) {
|
||||
if ( indicators.isNationalized() ) {
|
||||
//noinspection unchecked
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
public Boolean toDomainValue(Character relationalForm) {
|
||||
return toDomain( relationalForm );
|
||||
}
|
||||
|
||||
public static Boolean toDomain(Character relationalForm) {
|
||||
if ( relationalForm == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -88,6 +97,10 @@ public class TrueFalseType
|
|||
|
||||
@Override
|
||||
public Character toRelationalValue(Boolean domainForm) {
|
||||
return toRelational( domainForm );
|
||||
}
|
||||
|
||||
public static Character toRelational(Boolean domainForm) {
|
||||
if ( domainForm == null ) {
|
||||
return null;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue