This guide discusses migration from Hibernate ORM version 6.1. For migration from earlier versions, see any other pertinent migration guides as well.
Basic array/collection mapping
Basic arrays, other than byte[]
/Byte[] and char[]
/Character[]
, and basic collections (only subtypes of Collection
)
now map to the type code SqlTypes.ARRAY
by default, which maps to the SQL standard array
type if possible,
as determined via the new methods getArrayTypeName
and supportsStandardArrays
of org.hibernate.dialect.Dialect
.
If SQL standard array types are not available, data will be modeled as SqlTypes.JSON
, SqlTypes.XML
or SqlTypes.VARBINARY
,
depending on the database support as determined via the new method org.hibernate.dialect.Dialect.getPreferredSqlTypeCodeForArray
.
Due to this change, schema validation errors could occur as 5.x and 6.0 used the type code SqlTypes.VARBINARY
unconditionally
and serialized the contents with Java serialization. The migration to native array or JSON/XML types is non-trivial and requires
that the data is first read through the Java serialization mechanism and then written back through the respective JDBC method for the type.
A possible migration could involve the following steps in a migration script:
-
Execute
alter table tbl rename column array_col to array_col_old
to have the old format available -
Execute
alter table tbl add column array_col DATATYPE array
to add the column like the new mapping expects it to be -
Run the query
select t.primary_key, t.array_col_old from table t
-
For every result, deserialize the old representation via e.g.
org.hibernate.internal.util.SerializationHelper.deserialize(java.io.InputStream)
-
For every result, load the Hibernate entity by primary key and set the deserialized value
-
Finally, drop the old column
alter table tbl drop column array_col_old
Alternatively, to revert to pre-6.1 behavior, annotate your array property with @JdbcTypeCode(SqlTypes.VARBINARY)
:
@Basic
@JdbcTypeCode(SqlTypes.VARBINARY)
double[] myArray;
Enum mapping changes
Enums now map to the type code SqlType.SMALLINT
by default, whereas before it mapped to TINYINT
.
This mapping was not quite correct as Java effectively allows up to 32K enum entries, but TINYINT
is only a 1 byte type.
In practice, this isn’t a big issue though for two reasons. A lot of databases do not support a 1 byte integer DDL type,
so Hibernate falls back to the 2+ byte integer type as DDL type. Apart from that, enums in ORM models usually do not exceed the 255 value limit.
Note that the migration is not required as schema validation is able to handle the use of SMALLINT
when the DDL type is TINYINT
.
The migration usually requires running only a simple alter command alter table tbl alter column enum_col smallint
or alter table tbl modify column enum_col smallint
, depending on your database dialect.
The following dialects currently have DDL types registered for TINYINT
and might produce a different schema now:
-
Cachè
-
Ingres
-
Teradata
-
TimesTen
-
H2
-
HSQL
-
MySQL
-
MariaDB
-
Oracle