-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Migration Guide 5.2
This guide discusses migration from Hibernate ORM version 5.1 to version 5.2. For migration from earlier versions, see any other pertinent migration guides as well.
Lots of work has been done for 6.0. One of the things 6.0 will need is a unified view of "type systems" including its own type system (Type, EntityPersister, CollectionPersister, etc) and JPA’s type system - which would mean unifying all of this in hibernate-core. Because of this and the other large changes slated for 6.0 we decided to release a 5.2 that showed a clear migration path to the changes in 6.0 but that still supported the older calls and expectations as much as possible.
Hibernate 5.2 is built using Java 8 JDK and will require Java 8 JRE at runtime (we are investigating whether Java 9 will also work). This has a number of implications:
-
The hibernate-java8 module has been merged into hibernate-core and the Java 8 date/time types are now natively supported.
-
(todo) support for Java 8 Optional
-
(todo) support for other Java 8 features?
The hibernate-entitymanager module has also been merged into hibernate-core.
-
org.hibernate.SessionFactory
now extendsjavax.persistence.EntityManagerFactory
- temporarily it technically extendsorg.hibernate.jpa.HibernateEntityManagerFactory
(which in turn extendsjavax.persistence.EntityManagerFactory
) for backwards compatibility.HibernateEntityManagerFactory
is deprecated. -
org.hibernate.Session
now extendsjavax.persistence.EntityManager
- temporarily it technically extendsorg.hibernate.jpa.HibernateEntityManager
(which in turn extendsjavax.persistence.EntityManager
) for backwards compatibility.HibernateEntityManager
is deprecated. -
org.hibernate.Query
(deprecated in favor of neworg.hibernate.query.Query
) now extends the JPA contractsjavax.persistence.Query
andjavax.persistence.TypedQuery
.ProcedureCall
andStoredProcedureQuery
as well. -
org.hibernate.HibernateException
now extendsjavax.persistence.PersistenceExceptions
. Hibernate methods that "override" methods from their JPA counterparts now will also throw various JDK defined RuntimeExceptions (such asIllegalArgumentException
,IllegalStateException
, etc) as required by the JPA contract. -
Persister/type access is now exposed through
org.hibernate.Metamodel
, which extendsjavax.persistence.metamodel.Metamodel
. MetamodelImpl now manages all aspects of type system (see below). -
Cache management has also been consolidated.
org.hibernate.Cache
now extendsjavax.persistence.Cache
. CacheImpl now manages all aspects of cache regions (see below).
As part of merging hibernate-entitymanager into hibernate-core, I also wanted to take a moment to clean up some of these very old contracts. In conjunction with the move to Java 8 (default methods) and needing to implement JPA methods now in core I decided to implement more of a composition approach here, thus:
-
SessionFactoryImplementor used to have a number of methods pertaining to managing and accessing entity and collection persisters. Since we need to deal with JPA Metamodel contract anyway, I went ahead and moved all of that code into our new
org.hibernate.metamodel.spi.MetamodelImplementor
-
SessionFactory and SessionFactoryImplementor each had a number of methods dealing with cache regions. Many of these methods have been deprecated since 5.0 and those will be removed. However, the functionality has been moved into the
org.hibernate.Cache
andorg.hibernate.engine.spi.CacheImplementor
contracts helping implement JPA’sjavax.persistence.Cache
role.
This one can effect implementors of certain extension contracts. Specifically those previously accepting a SessionImplementor
will likely now accept a SharedSessionContract
.
In Hibernate 4.3, dialect implementations that did not support a limit offset would fetch all rows for a query and perform pagination in-memory. This solution, while functional, could have severe performance penalties. In 5.x, we preferred to favor performance optimizations which meant dialect implementations would throw an exception if a limit offset was specified but the dialect didn’t support such syntax.
As of 5.2.5.Final, we have introduced a new setting, hibernate.legacy_limit_handler
, that is designed to allow
users to enable the legacy 4.3 limit handler behavior. By default, this setting is false.
The specific dialects impacted by this change are restricted to the following.
-
Cache71Dialect
-
DB2390Dialect
-
InformixDialect
-
IngresDialect
-
RDMSOS2200Dialect
-
SQLServerDialect
-
TimesTenDialect
Note
|
If a dialect that extends any in the above list but overrides the limit handler implementation, then those dialects remain unchanged, e.g. SQLServer2005Dialect. |
In 5.2.3, a new strategy for retrieving database tables was introduced that improves SchemaMigrator and SchemaValidator
performance. This strategy executes a single java.sql.DatabaseMetaData#getTables(String, String, String, String[])
call to determine if each javax.persistence.Entity
has a mapped database table.
This strategy is the default, and uses the property setting hibernate.hbm2ddl.jdbc_metadata_extraction_strategy=grouped
.
This strategy may require hibernate.default_schema
and/or hibernate.default_catalog
to be provided.
To use the old strategy, which executes a java.sql.DatabaseMetaData#getTables(String, String, String, String[])
call for
each javax.persistence.Entity, use the property setting hibernate.hbm2ddl.jdbc_metadata_extraction_strategy=individually
.
Up to and including 5.2.8, Clob
values and values for String
, character[]
, and Character[]
attributes that are
annotated with @Lob
were:
-
bound using
Clob
representations of the data (usingPreparedStatement#setClob
orCallableStatement#setClob
); -
retrieved as
Clob
values (usingResultSet#getClob
orCallableStatement#getClob
), which were converted to the appropriate Java type; -
stored as PostgreSQL Large Objects; i.e., an
OID
for the value is stored in atext
column, which refers to the actual data stored in a different (PostgreSQL-specific) table.
In 5.2.9 and 5.2.10, due to the fix for HHH-11477, Clob
values and values for String
, character[]
, and Character[]
attributes that are annotated with @Lob
were:
-
bound using
String
representations of the data (usingPreparedStatement#setString
orCallableStatement#setString
); -
retrieved as
String
values (usingResultSet#getString
orCallableStatement#getString
), which were converted to the appropriate Java type; -
stored as variable-length character strings.
As a consequence of these changes, data persisted using a version of Hibernate prior to 5.2.9 cannot be read using 5.2.9 or 5.2.10. Data persisted using Hibernate 5.2.9 or 5.2.10 can no longer be read using 5.2.11 or later.
A workaround that can be used in 5.2.9 and 5.2.10 that will restore the 5.2.8/5.2.11 behavior is to override the PostgreSQL dialect with:
public SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
if( sqlCode == Types.CLOB ){
return ClobTypeDescriptor.CLOB_BINDING;
}
return super.getSqlTypeDescriptorOverride( sqlCode );
}
In addition, any Clob
values and values for String
, character[]
, Character[]
attributes that are annotated with
@Lob
that were stored as variable-length character strings using 5.2.9 or 5.2.10 should be updated to store the values
as PostgreSQL Large Objects before migrating to 5.2.11.
For example, if variable-length character strings were stored by 5.2.9 or 5.2.10 for the following mapping:
@Entity(name = "TestEntity")
@Table(name = "TEST_ENTITY")
public static class TestEntity {
@Id
@GeneratedValue
private long id;
@Lob
String firstLobField;
@Lob
String secondLobField;
@Lob
Clob clobField;
...
}
the variable-length character strings can be converted to PostgreSQL Large Objects by executing the following SQL:
update test_entity
set clobfield = lo_from_bytea( 0, cast( clobfield as bytea ) ),
firstlobfield = lo_from_bytea( 0, cast( firstlobfield as bytea ) ),
secondlobfield = lo_from_bytea( 0, cast( secondlobfield as bytea ) )
Important
|
From 5.2.13 the id generator name scope was considered global but realizing this change may cause troubles for few existing projects (HHH-12454), starting from 5.2.17 the scope of the id generators names
will be considered local by default (which is the pre-5.2.13 behavior) and a new configuration setting hibernate.jpa.compliance.global_id_generators
can be used to enable the JPA compliant global scoping.
|
-
QueryCacheFactory contract changed
-
RegionFactory contract changes
-
todo : merge AvailableSettings together
-
org.hibernate.Transaction now extends JPA’s EntityTransaction and follows its pre- and post- assertions. e.g. begin() now throws an exception if transaction is already active.
-
(todo) following the above one, JPA also says that only PersistenceUnitTransactionType#JTA EntiytManagers are allowed to access EntityTransactions. Need a strategy to handle this
-
Session#getFlushMode and Query#getFlushMode clash in terms of Hibernate (FlushMode) and JPA (FlushModeType) returns. #getFlushMode has been altered to return JPA’s FlushModeType. The Hibernate FlushMode is still available via #getHibernateFlushMode and #setHibernateFlushMode. Same for Session#getFlushMode and EntityManager#getFlushMode.
-
Setting
hibernate.listeners.envers.autoRegister
has been deprecated in favor ofhibernate.envers.autoRegisterListeners
. -
AuditReader#getCurrentRevision has been deprecated in favor of
org.hibernate.envers.RevisionListener
. -
As of 5.2.11, NoopOptimizer#generate will no longer skip negative values and 0 when it has a positive increment size; instead it will return the value obtained from the database.