213 lines
12 KiB
Plaintext
213 lines
12 KiB
Plaintext
= 5.3 Migration Guide
|
|
:toc:
|
|
|
|
This guide discusses migration from Hibernate ORM version 5.2 to version 5.3. For migration from
|
|
earlier versions, see any other pertinent migration guides as well.
|
|
|
|
== Background
|
|
|
|
Hibernate 5.3 adds support for the JPA 2.2 specification
|
|
|
|
|
|
== Known changes
|
|
|
|
=== Changes to positional query parameter handling
|
|
|
|
This really breaks down into 2 related changes:
|
|
|
|
* Support for JDBC-style parameter declarations in HQL/JPQL queries has been removed. This feature
|
|
has been deprecated since 4.1 and removing it made implementing the second change, so we decided
|
|
to remove that support. JDBC-style parameter declaration is still supported in native-queries.
|
|
* Since JPA positional parameters really behave more like named parameters (they can be repeated,
|
|
declared in any order, etc.) Hibernate used to treat them as named parameters - it relied on
|
|
Hibernate's JPA wrapper to interpret the JPA setParameter calls and properly handle delegating to
|
|
the named variant. This is actually a regression in 5.2 as it causes
|
|
`javax.persistence.Parameter#getPosition` to report `null`.
|
|
|
|
For JDBC-style parameter declarations in native queries, we have also moved to using one-based
|
|
instead of zero-based parameter binding to be consistent with JPA. That can temporarily be
|
|
reverted by setting the `hibernate.query.sql.jdbc_style_params_base` setting to `true` which
|
|
reverts to expecting zero-based binding.
|
|
|
|
|
|
=== Change in the `@TableGenerator` stored value
|
|
|
|
In order to be compliant with the JPA specification, the sequence value stored by Hibernate 5.3 in the database table used by the `javax.persistence.TableGenerator`
|
|
is the *last* generated value. Previously, Hibernate stored the *next* sequence value.
|
|
|
|
For backward compatibility, a new setting called `hibernate.id.generator.stored_last_used` was introduced, which gives you the opportunity to fall back to the old Hibernate behavior.
|
|
|
|
[NOTE]
|
|
====
|
|
Existing applications migrating to 5.3 and using the `@TableGenerator` have to set the `hibernate.id.generator.stored_last_used` configuration property to `false`.
|
|
====
|
|
|
|
=== Query parameters
|
|
|
|
Method `org.hibernate.type.Type getType()` in `org.hibernate.query.QueryParameter` was renamed to `getHibernateType()`.
|
|
|
|
This was done in order to allow for the re-introduction of `Class<T> getType()` in a sub-interface, `org.hibernate.procedure.ParameterRegistration`. That second method had been removed in 5.2, breaking compatibility with 5.1.
|
|
|
|
=== Second-level cache provider SPI changes
|
|
|
|
Hibernate's second-level cache SPI needed to be redesigned to match with expectations between
|
|
Hibernate and the various caching providers. And the SPI did not really clarify the intention.
|
|
These mis-matched expectations certainly had the potential to lead to bugs. Although it was
|
|
originally slated for 6.0 to delay the SPI changes, we decided to back-port the work to
|
|
5.3 to address a number of bugs that could have been avoided with a clarified SPI.
|
|
|
|
The changes also allow the caching providers to perform serious optimizations based on
|
|
the users configuration of domain data caching in Hibernate.
|
|
|
|
Details can be seen on the https://hibernate.atlassian.net/browse/HHH-11356[HHH-11356] Jira issue
|
|
|
|
One potential upgrade concern is any custom `org.hibernate.cache.spi.QueryCacheFactory` implementations.
|
|
`org.hibernate.cache.spi.QueryCacheFactory` was meant as a means to allow service providers the
|
|
ability to define query result caching, generally with more stale-tolerant query result invalidation handling.
|
|
However, the contract also bound it to the old second level cache contracts so they had to be
|
|
updated. Its responsibilities also changed so we also decided to "rename it" to
|
|
`org.hibernate.cache.spi.TimestampsCacheFactory`
|
|
|
|
Another specific change to be aware of is accessing cache entries via `SecondLevelCacheStatistics#getEntries`
|
|
and `NaturalIdCacheStatistics#getEntries`. These methods have been deprecated, however the new
|
|
caching SPI does not really require caching providers to support this. As of 5.3 these methods
|
|
inherently return an empty Map (`Collections#emptyMap`). This has always been something that providers
|
|
did not implement "correctly" anyway
|
|
|
|
|
|
=== Statistics changes
|
|
|
|
The change for HHH-11356 required changes in its consumers. One such consumer is the Hibernate
|
|
Statistics system....
|
|
|
|
=== Native (non-JPA) Pagination changes
|
|
|
|
When hibernate-entitymanager module was merged into hibernate-core in Hibernate ORM 5.2, the contracts for the
|
|
following pre-existing `org.hibernate.Query` methods were changed to be specified by JPA `javax.persistence.Query`
|
|
methods: `getFirstResult()`, `setFirstResult(int)`, `getMaxResults()`, and `setMaxResults()`.
|
|
|
|
In 5.3.2, the following methods were temporarily added to
|
|
http://docs.jboss.org/hibernate/orm/5.3/javadocs/org/hibernate/Query.html[`org.hibernate.Query`] to make it
|
|
easier to migrate native applications from Hibernate ORM 5.1 to 5.3, and maintain 5.1 pagination behavior:
|
|
|
|
* http://docs.jboss.org/hibernate/orm/5.3/javadocs/org/hibernate/Query.html#setHibernateFirstResult-int-[`setHibernateFirstResult(int)`]
|
|
behaves the same as the 5.1 version of `setFirstResult()`, with a small difference -- calling
|
|
`setHibernateFirstResult(int)` with a negative value will result in `getHibernateFirstResult()` returning 0, instead
|
|
of the negative value. Note that this behavior differs from JPA in that `javax.persistence.Query.setFirstResult(int)`
|
|
throws `IllegalArgumentException` when called with a negative value.
|
|
* http://docs.jboss.org/hibernate/orm/5.3/javadocs/org/hibernate/Query.html#getHibernateFirstResult--[`getHibernateFirstResult()`]
|
|
behaves the same as the 5.1 version of `getFirstResult()`, except for the difference mentioned above when `setHibernateFirstResult(int)` is called with a negative number. This method returns `null` if no value was set
|
|
via `setHibernateFirstResult(int)` (or `setFirstResult(int)`). Note that this behavior differs from JPA in that
|
|
`javax.persistence.Query.getFirstResult()` returns 0 when uninitialized.
|
|
* http://docs.jboss.org/hibernate/orm/5.3/javadocs/org/hibernate/Query.html#setHibernateMaxResults-int-[`setHibernateMaxResults`]
|
|
behaves the same as the 5.1 version of `setMaxResults()`; setting a value less than or equal to 0 is
|
|
considered uninitialized, resulting in *no limit* on the number of results. Note that this behavior differs
|
|
from JPA `javax.persistence.Query.setMaxResults(int)`, which, when called with a negative value,
|
|
throws `IllegalArgumentException`, and when called with a value of 0, indicates that the query should return
|
|
*no results*.
|
|
* http://docs.jboss.org/hibernate/orm/5.3/javadocs/org/hibernate/Query.html#getHibernateMaxResults--[`getHibernateMaxResults`]
|
|
behaves the same as the 5.1 version of `#getMaxResults`. This method returns `null` if uninitialized or
|
|
a value less than or equal to 0 was set via `setHibernateMaxResults(int)` (or `setMaxResults(int)`).
|
|
Note that this behavior differs from JPA in that `javax.persistence.Query.getMaxResults() returns
|
|
`Integer.MAX_VALUE` when uninitialized.
|
|
|
|
These methods are deprecated, and will be removed in a future version. To be portable with future Hibernate
|
|
versions, applications should be changed to use the JPA methods.
|
|
|
|
=== Drop hibernate-infinispan module
|
|
|
|
Support for using Infinispan as a Hibernate 2nd-level cache provider has been moved to the Infinispan project so
|
|
the `hibernate-infinispan` module has been dropped.
|
|
|
|
A relocation pom which is pointing to `org.infinispan:infinispan-hibernate-cache` dependency is still generated,
|
|
therefore, avoiding the need of updating any library dependency.
|
|
|
|
[WARN]
|
|
====
|
|
The relocation pom may be dropped in a future release.
|
|
====
|
|
|
|
|
|
=== EnhancementTask changes
|
|
|
|
The API of the `org.hibernate.tool.enhance.EnhancementTask` Ant task was changed, specifically
|
|
the `#addFileset` method was dropped in favor of `#setBase` and `#setDir`
|
|
|
|
See details on the https://hibernate.atlassian.net/browse/HHH-11795[HHH-11795] Jira issue.
|
|
|
|
The main gist is that EnhancementTask was fixed (through a contribution) to actually work with
|
|
`Enhancer` from `BytecodeProvider`. Previously it had not. And part of fixing that required this
|
|
change.
|
|
|
|
|
|
=== Many-to-one association in embeddable collection elements and composite IDs
|
|
|
|
A bug introduced in 4.3 caused many-to-one associations in embeddable collection elements and
|
|
composite IDs to be eagerly fetched, even when explicitly mapped as lazy.
|
|
|
|
This bug does not affect many-to-one associations that are not in a composite ID or embeddable
|
|
collection element.
|
|
|
|
In 5.3.2, this bug was fixed. As a result, such associations will be fetched as specified
|
|
by their mappings.
|
|
|
|
Many-to-one associations mapped by using native HBM xml are lazy by default. In order to keep
|
|
the associations eager in 5.3.2 and later, mappings will need to explicitly specify that
|
|
they are non-lazy.
|
|
|
|
When mapped with annotations, many-to-one associations use `FetchType.EAGER` by default.
|
|
Starting in 5.3.2, if an association is mapped with `FetchType.LAZY`, the assocation will
|
|
be lazily fetched, as expected.
|
|
|
|
See details on the https://hibernate.atlassian.net/browse/HHH-12687[HHH-12687] Jira issue.
|
|
|
|
=== JpaIntegrator removed
|
|
|
|
JPA and native implementations of Hibernate event listeners were unified (see https://hibernate.atlassian.net/browse/HHH-11264)
|
|
making the `org.hibernate.jpa.event.spi.JpaIntegrator` no longer needed.
|
|
|
|
[NOTE]
|
|
====
|
|
Existing applications migrating to 5.3 with classes extending `org.hibernate.jpa.event.spi.JpaIntegrator` have to change these classes to implement the `org.hibernate.integrator.spi.Integrator` interface.
|
|
====
|
|
|
|
=== Persister changes
|
|
|
|
Due to changes to SPIs for persisters (in `org.hibernate.persister` package), custom persisters will need
|
|
to be updated to follow the new SPIs.
|
|
|
|
=== 5.1 -> 5.3 exception handling changes
|
|
|
|
In 5.3 (as well as 5.2), exception handling for a `SessionFactory` built via Hibernate's native
|
|
bootstrapping wraps or converts `HibernateException` according to the JPA specification unless the
|
|
operation is Hibernate-specific (e.g., `Session#save`, `Session#saveOrUpdate`).
|
|
|
|
In 5.3.3, a property was added, `hibernate.native_exception_handling_51_compliance`, which
|
|
indicates if exception handling for a `SessionFactory` built via Hibernate's native bootstrapping
|
|
should behave the same as native exception handling in Hibernate ORM 5.1. When set to `true`,
|
|
`HibernateException` will not be wrapped or converted according to the JPA specification. This
|
|
setting will be ignored for a `SessionFactory` built via JPA bootstrapping.
|
|
|
|
== 5.1 -> 5.3 entity class "where" mapping changes
|
|
|
|
Starting in 5.2.0, when an entity class uses annotations to map a "where" clause (i.e., `@Where(clause="...")`),
|
|
that "where" clause is taken into account when loading one-to-many and many-to-many associations.
|
|
|
|
Starting in 5.3.5, the same functionality applies to an entity's where clause mapped using hbm.xml
|
|
(e.g., `<entity ... where="..."/>)
|
|
|
|
In 5.3.7, a new property was added, `hibernate.use_entity_where_clause_for_collections`, that provides
|
|
control over whether the entity's "where" clause is taken into account when loading one-to-many or
|
|
many-to-many collections of that type of entity. The property is set to `true` by default. You can go
|
|
back to the previous behavior (ignoring the entity's mapped where clause) by setting
|
|
`hibernate.use_entity_where_clause_for_collections` to false.
|
|
|
|
=== 5.3 -> 6.0 compatibility changes
|
|
|
|
The original driving force behind these series of changes is an effort to be as proactive as possible
|
|
about designing compatibility between 5.3 and 6.0.
|
|
|
|
==== Type system changes
|
|
|
|
Use of NavigableRole, back-ported from 6.0 rather than plain String
|