This guide discusses migration to Hibernate ORM version 8.0. For migration from earlier versions, see any other pertinent migration guides as well.
Requirements
See the website for the list of requirements for the 8.0 series.
Jakarta Persistence 4.0
One specific requirement change that is important to call out is the move to from Jakarta Persistence version 3.2 to 4.0 which has a number of impacts, many of which are discussed below.
See this issue for more details.
New Features
See the website for the list of new features in the 8.0 series.
Changes to API
This section describes changes to contracts (classes, interfaces, methods, etc.) which are considered API.
StatelessSession
Jakarta Persistence now defines a contract for "stateless" processing, named EntityAgent, similar to Hibernate’s StatelessSession.
Hibernate’s StatelessSession now implements EntityAgent.
2 methods on EntityAgent clash with methods already defined on StatelessSession -
-
insert()-EntityAgentdefines avoidreturn type, whereas Hibernate has historically returned the identifier of the inserted entity. -
fetch()-EntityAgentdefines that the fetched value be returned, whereasStatelessSessionhas historically defined avoidreturn type.
In both cases, StatelessSession has been changed to match the EntityAgent signatures.
Query and Transaction Timeouts
Historically, both Hibernate and Jakarta Persistence have defined timeouts as integer values.
Confusingly, Hibernate generally used second precision while Jakarta Persistence used millisecond precision.
Starting in 3.2, Jakarta Persistence added a new Timeout class which helps alleviate this potential confusion.
Originally this new Timeout type was not exposed on any API directly, so there was no impact from an API perspective.
However, this has changed a bit in 4.0 where Timeout is now exposed on certain APIs.
This causes a signature conflict with a few of Hibernate API methods; as part of fixing those conflicts, it was decided to change all exposures of timeout in Hibernate APIs to use Timeout as this helps clarify these confusions.
Query API
One of the biggest changes in Jakarta Persistence 4.0 is the better modeling of "queries" into selections (TypedQuery) and mutations (its new Statement contract),
aligning closely with Hibernate’s already existing SelectionQuery and MutationQuery contracts.
At the same time, it deprecated all "operation methods" from its "raw" Query contract.
Hibernate’s Query contracts implement the Jakarta Persistence ones, so changes were needed here.
Another impact is that @NamedQuery and @NamedNativeQuery (as well as Hibernate’s variants) may no longer be used to define mutation queries -
-
@NamedQuery- ASelectionQuerydefined using HQL/JPQL -
@NamedStatement- AMutationQuerydefined using HQL/JPQL -
@NamedNativeQuery- ASelectionQuerydefined using native SQL -
@NamedNativeStatement- AMutationQuerydefined using native SQL
AttributeNode Subgraphs
As part of its support for "entity graphs", Hibernate’s org.hibernate.graph.AttributeNode contract extends fropm the Jakarta Persistence jakarta.persistence.AttributeNode.
Starting in version 4.0, Jakarta Persistence has "fixed" the use of raw types for the AttributeNode#getSubgraphs and AttributeNode#getKeySubgraphs methods.
Hibernate has therefore needed to do the same in its org.hibernate.graph.AttributeNode.
Changes to SPI
This section describes changes to contracts (classes, interfaces, methods, etc.) which are considered SPI.
Classmate removal
The dependency on Classmate was removed, which had a minor impact on certain SPIs.
In particular, ClassmateContext was completely removed.
Raw types in JPA Bootstrap
Raw Map types were eliminated from the signatures of methods of the class
org.hibernate.jpa.boot.spi.Bootstrap.
Query Memento
Hibernate uses a number of implementations of its NamedQueryMemento contract to
model "named queries". Starting in version 3.2, Jakarta Persistence added the
TypedQueryReference contract intended to serve the much the same goal.
Hibernate’s NamedQueryMemento implementations were changed to extend from
TypedQueryReference.
In version 4.0, Jakarta Persistence has added some additional methods to
TypedQueryReference which now conflict with some of Hibernate’s existing methods
requiring a rename. Notably, the addition of TypedQueryReference#getParameterTypes
caused conflict’s with Hibernate’s NamedSqmQueryMemento#getParameterTypes. To
address this conflict, we’ve renamed the NamedSqmQueryMemento method to
#getAnticipatedParameterTypes.
Changes in Behavior
This section describes changes in behavior that applications should be aware of.
Collections belonging to read-only entities
Previously, collections belonging to an entity loaded in read-only mode were not marked as read-only and could be modified. This behavior was surprising and significantly undermined the benefits of the read-only mode. A collection is now set to read-only when its owning entity is read-only, and modifications to the collection result in an error.
Result deduplication
In Hibernate 6.x query result lists with duplicate results were handled in an
ad hoc and inconsistent way by getSingleResult() and getSingleResultOrNull().
As of Hibernate 7.3, these methods always throw when the result list contains
more than one element (which is faithful to the documented semantics of these
methods). If automatic deduplication is required, use:
query.setResultListTransformer(ResultListTransformer.uniqueResultTransformer())
which collapses duplicate results according to value equality.
Session.get
Jakarta Persistence now defines a series of overloaded EntityHandler.get() methods as corollaries to EntityHandler.find().
These methods are defined to throw an EntityNotFoundException rather than return null.
This operates quite differently from the older Hibernate Session.get() methods which
-
still returned null if no entity with that is was found
-
force initialized the entity, if there was one and it was previously uninitialized.
Applications which use(d) Session.get() should be aware of this change in behavior.
Changes in XSD
This section describes changes in XML Schema Descriptors
[[xsd-comments] === Table and Column Comments
Previous versions of the mapping.xsd defined table and column comments (for schema export)
using XSD attributes. This was a decision made at the time to facilitate users migrating
from hbm.xml mapping format. In the intervening period, Jakarta Persistence has
also added comments to its table and column XSD types, but using dedicated element.
We now align with the Jakarta Persistence approach of using elements. This will require
changes any mapping.xml documents which define table or column comments. E.g.,
<entity ...>
<table ... comment="some comment"/>
</entity>
would need to be changed to
<entity ...>
<table>
<comment>some comment</comment>
</table>
</entity>