186 lines
7.3 KiB
Plaintext
186 lines
7.3 KiB
Plaintext
= 7.0 Migration Guide
|
|
:toc:
|
|
:toclevels: 4
|
|
:docsBase: https://docs.jboss.org/hibernate/orm
|
|
:versionDocBase: {docsBase}/7.0
|
|
:userGuideBase: {versionDocBase}/userguide/html_single/Hibernate_User_Guide.html
|
|
:javadocsBase: {versionDocBase}/javadocs
|
|
|
|
|
|
This guide discusses migration to Hibernate ORM version 7.0. For migration from
|
|
earlier versions, see any other pertinent migration guides as well.
|
|
|
|
[[jpa-32]]
|
|
== Jakarta Persistence 3.2
|
|
|
|
7.0 migrates to Jakarta Persistence 3.2 which is fairly disruptive, mainly around:
|
|
|
|
* type parameters
|
|
** Affects much of the Criteria API - especially roots, joins, paths
|
|
** Affects much of the Graph API -
|
|
*** org.hibernate.graph.Graph.addAttributeNode(java.lang.String) defines a return while
|
|
`jakarta.persistence.Graph.addAttributeNode(java.lang.String)` does not.
|
|
* new JPA features colliding with previous Hibernate extension features
|
|
** `Nulls` (JPA) v. `NullPrecedence` (Hibernate), including JPA's new `Order#getNullPrecedence()` returning `Nulls`
|
|
colliding with Hibernate's `SqmSortSpecification#getNullPrecedence` returning `NullPrecedence`. Hibernate's form
|
|
was renamed to `SqmSortSpecification#getHibernateNullPrecedence` to avoid the collision.
|
|
** `SchemaManager` is now also a JPA contract exposed as `EntityManagerFactory#getSchemaManager` which leads to type issues for
|
|
Hibernate's `SessionFactory#getSchemaManager`. Hibernate's `SchemaManager` now extends the new JPA `SchemaManager`.
|
|
But that is a bytecode incompatibility.
|
|
** JPA has added support in its Graph API for things Hibernate has supported for some time. Some of those are collisions
|
|
requiring changes to the Hibernate API.
|
|
** `Transaction#getTimeout`. JPA 3.2 adds `#getTimeout` but uses `Integer` whereas Hibernate has historically used `int`. Note that this raises the possibility of a `NullPointerException` during migration if, e.g., performing direct comparisons on the timeout value against an in (auto unboxing).
|
|
|
|
See this https://in.relation.to/2024/04/01/jakarta-persistence-3/[blog post] for a good discussion of the changes in Jakarta Persistence 3.2.
|
|
|
|
|
|
[[hibernate-models]]
|
|
== Hibernate Models
|
|
|
|
For many years Hibernate has used the Hibernate Commons Annotations (HCANN) library for handling various low-level tasks
|
|
related to understanding the structure of an application domain model, reading annotations and weaving in XML
|
|
mapping documents.
|
|
|
|
However, HCANN suffers from a number of limitations that continue to be problematic. And given
|
|
the use of HCANN across multiple projects, doing the needed refactoring was simply not possible.
|
|
|
|
The https://github.com/hibernate/hibernate-models[Hibernate Models] project was developed to be a better alternative
|
|
to HCANN. Hibernate Models is essentially an abstraction over reflection (`Type`, `Class`, `Member`, ...) and
|
|
annotations. Check out its project page for complete details.
|
|
|
|
7.0 uses Hibernate Models in place of HCANN.
|
|
|
|
NOTE: Currently, the `hibernate-envers` module still uses HCANN. That will change during continued 7.0 development.
|
|
|
|
|
|
|
|
[[annotation-validation]]
|
|
== Annotation Validations
|
|
|
|
7.0 adds many more checks about illegal use of annotations.
|
|
|
|
|
|
=== PersistentAttributeType
|
|
|
|
As of 7.0, Hibernate applies much better validation of an attribute specifying multiple PersistentAttributeTypes.
|
|
Jakarta Persistence 3.2 has clarified this in the specification. E.g., the following examples are all now illegal -
|
|
|
|
[source,java]
|
|
----
|
|
@Basic
|
|
@ManyToOne
|
|
private Employee manager;
|
|
----
|
|
|
|
or
|
|
|
|
[source,java]
|
|
----
|
|
@Lob
|
|
@ManyToOne
|
|
private Employee manager;
|
|
----
|
|
|
|
|
|
[[misplaced-annotations]]
|
|
=== Misplaced Annotations
|
|
|
|
7.0 does much more in-depth checking that annotations appear in the proper place. While previous versions
|
|
did not necessarily throw errors, in most cases these annotations were simply ignored. E.g.
|
|
|
|
|
|
[source,java]
|
|
----
|
|
@Entity
|
|
class Book {
|
|
// defines FIELD access-type
|
|
@Id
|
|
Integer id;
|
|
|
|
// previously ignored, this is an error now
|
|
@Column(name="category")
|
|
String getType() { ... }
|
|
|
|
...
|
|
}
|
|
----
|
|
|
|
|
|
[[auto-cascade-persist]]
|
|
== Cascading persistence for `@Id` and `@MapsId` fields
|
|
|
|
Previously Hibernate automatically enabled `cascade=PERSIST` for association fields annotated `@Id` or `@MapsId`.
|
|
This was undocumented and unexpected behavior, and arguably against the intent of the Persistence specification.
|
|
|
|
Existing code which relies on this behavior should be modified by addition of explicit `cascade=PERSIST` to the association field.
|
|
|
|
|
|
[[enum-checks]]
|
|
== Enums and Check Constraints
|
|
|
|
Hibernate previously added support for generating check constraints for enums mapped using `@Enumerated`
|
|
as part of schema generation. 7.0 adds the same capability for enums mapped using an `AttributeConverter`,
|
|
by asking the converter to convert all the enum constants on start up.
|
|
|
|
|
|
[[java-beans]]
|
|
== JavaBean Conventions
|
|
|
|
Previous versions allowed some questionable (at best) attribute naming patterns. These are no longer supported. E.g.
|
|
|
|
[source,java]
|
|
----
|
|
@Basic
|
|
String isDefault();
|
|
----
|
|
|
|
|
|
|
|
[[cleanup]]
|
|
== Some Cleanup
|
|
|
|
* Removed `SqmQualifiedJoin`. All joins are qualified.
|
|
* Removed `AdditionalJaxbMappingProducer`, deprecated in favor of `AdditionalMappingContributor`
|
|
* Removed `MetadataContributor`, deprecated in favor of `AdditionalMappingContributor`
|
|
* Removed `@Persister`.
|
|
* Removed `hibernate.mapping.precedence` and friends
|
|
|
|
|
|
[[ddl-implicit-datatype-timestamp]]
|
|
== Default precision for timestamp on some databases
|
|
|
|
The default precision for Oracle timestamps was changed to 9 i.e. nanosecond precision.
|
|
The default precision for SQL Server timestamps was changed to 7 i.e. 100 nanosecond precision.
|
|
|
|
|
|
[[sf-name]]
|
|
== SessionFactory Name (and JNDI)
|
|
|
|
Hibernate defines `SessionFactory#getName` (specified via `cfg.xml` or `hibernate.session_factory_name`) which is used to
|
|
help with (de)serializing a `SessionFactory`. It is also, unless `hibernate.session_factory_name_is_jndi` is set to `false`,
|
|
used in biding the `SessionFactory` into JNDI.
|
|
|
|
This `SessionFactory#getName` method pre-dates Jakarta Persistence (and JPA). It now implements `EntityManagerFactory#getName`
|
|
inherited from Jakarta Persistence, which states that this name should come from the persistence-unit name.
|
|
To align with Jakarta Persistence (the 3.2 TCK tests this), Hibernate now considers the persistence-unit name if no
|
|
`hibernate.session_factory_name` is specified.
|
|
|
|
However, because `hibernate.session_factory_name` is also a trigger to attempt to bind the SessionFactory into JNDI,
|
|
this change to consider persistence-unit name, means that each `SessionFactory` created through Jakarta Persistence now
|
|
have a name and Hibernate attempted to bind these to JNDI.
|
|
|
|
To work around this we have introduced a new `hibernate.session_factory_jndi_name` setting that can be used to explicitly
|
|
specify a name for JNDI binding. The new behavior is as follows (assuming `hibernate.session_factory_name_is_jndi` is not explicitly configured):
|
|
|
|
* If `hibernate.session_factory_jndi_name` is specified, the name is used to bind into JNDI
|
|
* If `hibernate.session_factory_name` is specified, the name is used to bind into JNDI
|
|
|
|
Hibernate can use the persistence-unit name for binding into JNDI as well, but `hibernate.session_factory_name_is_jndi`
|
|
must be explicitly set to true.
|
|
|
|
|
|
[[todo]]
|
|
== Todos (dev)
|
|
|
|
* Look for `todo (jpa 3.2)` comments
|
|
* Look for `todo (7.0)` comments |