Do some renaming for consistency and update documentation for new SQL types

This commit is contained in:
Christian Beikov 2022-03-29 17:10:52 +02:00
parent 814c164c81
commit a9d1035806
16 changed files with 263 additions and 43 deletions

View File

@ -61,6 +61,8 @@ dependencies {
requireCapability 'org.ehcache.modules:ehcache-xml-jakarta' requireCapability 'org.ehcache.modules:ehcache-xml-jakarta'
} }
} }
// Needed for JSON tests
testRuntimeOnly libraries.jackson
} }

View File

@ -408,6 +408,7 @@ In other words, the database schema will reflect the Bean Validation constraints
To disable constraint propagation to DDL, set up `hibernate.validator.apply_to_ddl` to `false` in the configuration file. To disable constraint propagation to DDL, set up `hibernate.validator.apply_to_ddl` to `false` in the configuration file.
Such a need is very uncommon and not recommended. Such a need is very uncommon and not recommended.
[[misc-options]]
==== Misc options ==== Misc options
`*hibernate.create_empty_composites.enabled*` (e.g. `true` or `false` (default value)):: `*hibernate.create_empty_composites.enabled*` (e.g. `true` or `false` (default value))::

View File

@ -190,10 +190,8 @@ map basic value to the database.
This includes removal of the following deprecated legacy annotations: This includes removal of the following deprecated legacy annotations:
* `@Type`
* `@TypeDef` * `@TypeDef`
* `@TypeDefs` * `@TypeDefs`
* `@MapKeyType`
* `@CollectionId#type` * `@CollectionId#type`
* `@AnyMetaDef#metaType` * `@AnyMetaDef#metaType`
* `@AnyMetaDef#idType` * `@AnyMetaDef#idType`
@ -982,7 +980,7 @@ include::{sourcedir}/basic/BlobByteArrayTest.java[tags=basic-blob-byte-array-exa
==== Duration ==== Duration
By default, Hibernate will map `Duration` to the `NUMERIC` JDBC type. By default, Hibernate will map `Duration` to the `INTERVAL_SECOND` SQL type and fallback to `NUMERIC` if necessary.
[[basic-duration-example]] [[basic-duration-example]]
.Mapping Duration .Mapping Duration
@ -999,7 +997,7 @@ include::{sourcedir}/basic/DurationMappingTests.java[tags=basic-duration-example
==== Instant ==== Instant
`Instant` is mapped to the `TIMESTAMP` JDBC type. `Instant` is mapped to the `TIMESTAMP_UTC` SQL type.
[[basic-instant-example]] [[basic-instant-example]]
@ -1299,7 +1297,8 @@ include::{sourcedir}/basic/LocaleMappingTests.java[tags=basic-Locale-example]
==== UUID ==== UUID
Hibernate allows mapping UUID values in a number of ways. By default, Hibernate will Hibernate allows mapping UUID values in a number of ways. By default, Hibernate will
store UUID values in their binary form. store UUID values in the native form by using the SQL type `UUID` or in binary form with the `BINARY` JDBC type
if the database does not have a native UUID type.
[NOTE] [NOTE]
@ -1308,8 +1307,7 @@ The default uses the binary representation because it uses a more efficient colu
However, many applications prefer the readability of the character-based column storage. However, many applications prefer the readability of the character-based column storage.
// todo (6.0) : develop a better way to expose this to users To switch the default mapping, set the `*hibernate.type.preferred_uuid_jdbc_type*` configuration to `CHAR`.
To switch the default mapping, simply call `MetadataBuilder.applyBasicType( UUIDCharType.INSTANCE, UUID.class.getName() )`.
==== ====
===== UUID as binary ===== UUID as binary
@ -1323,23 +1321,41 @@ Chosen as the default simply because it is generally more efficient from a stora
Maps the UUID to a String using `java.util.UUID#toString` and `java.util.UUID#fromString` and stores that as `CHAR` or `VARCHAR` data. Maps the UUID to a String using `java.util.UUID#toString` and `java.util.UUID#fromString` and stores that as `CHAR` or `VARCHAR` data.
===== PostgreSQL-specific UUID
[IMPORTANT]
====
When using one of the PostgreSQL Dialects, the PostgreSQL-specific UUID Hibernate type becomes the default UUID mapping.
====
Maps the UUID using the PostgreSQL-specific UUID data type.
The PostgreSQL JDBC driver chooses to map its UUID type to the `OTHER` code.
Note that this can cause difficulty as the driver chooses to map many different data types to `OTHER`.
===== UUID as identifier ===== UUID as identifier
Hibernate supports using UUID values as identifiers, and they can even be generated on the user's behalf. Hibernate supports using UUID values as identifiers, and they can even be generated on the user's behalf.
For details, see the discussion of generators in <<chapters/domain/identifiers.adoc#identifiers,_Identifiers_>>. For details, see the discussion of generators in <<chapters/domain/identifiers.adoc#identifiers,_Identifiers_>>.
==== InetAddress
By default, Hibernate will map `InetAddress` to the `INET` SQL type and fallback to `BINARY` if necessary.
[[basic-inet-address-example]]
.Mapping InetAddress
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/InetAddressMappingTests.java[tags=basic-inet-address-example]
----
====
[[basic-mapping-json]]
==== JSON mapping
Hibernate will only use the `JSON` type if explicitly configured through `@JdbcTypeCode( SqlTypes.JSON )`.
The JSON library used for serialization/deserialization is detected automatically,
but can be overridden by setting `hibernate.type.json_format_mapper`
as can be read in the <<appendices/Configurations.adoc#misc-options,Configurations>> section.
[[basic-json-example]]
.Mapping JSON
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/JsonMappingTests.java[tags=basic-json-example]
----
====
[[basic-mapping-composition]] [[basic-mapping-composition]]
@ -1530,9 +1546,8 @@ Another approach is to supply the implementation of the `org.hibernate.usertype.
There are also corresponding, specialized forms of `@Type` for specific model parts: There are also corresponding, specialized forms of `@Type` for specific model parts:
* When mapping a Map, `@Type` describes the Map value while `@MapKeyCustomType` describe the Map key * When mapping a Map, `@Type` describes the Map value while `@MapKeyType` describe the Map key
* When mapping a List or array, `@Type` describes the elements while `@ListIndexCustomType` describes the index * When mapping an id-bag, `@Type` describes the elements while `@CollectionIdType` describes the collection-id
* When mapping an id-bag, `@Type` describes the elements while `CollectionIdType` describes the collection-id
* For other collection mappings, `@Type` describes the elements * For other collection mappings, `@Type` describes the elements
* For discriminated association mappings (`@Any` and `@ManyToAny`), `@Type` describes the discriminator value * For discriminated association mappings (`@Any` and `@ManyToAny`), `@Type` describes the discriminator value

View File

@ -0,0 +1,99 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.userguide.mapping.basic;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.jdbc.AdjustableJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
/**
* @author Christian Beikov
*/
@DomainModel(annotatedClasses = InetAddressMappingTests.EntityWithInetAddress.class)
@SessionFactory
public class InetAddressMappingTests {
@Test
public void verifyMappings(SessionFactoryScope scope) {
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
.getRuntimeMetamodels()
.getMappingMetamodel();
final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor( EntityWithInetAddress.class);
final JdbcTypeRegistry jdbcTypeRegistry = mappingMetamodel.getTypeConfiguration().getJdbcTypeRegistry();
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("address");
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo(InetAddress.class));
final JdbcType intervalType = jdbcTypeRegistry.getDescriptor(SqlTypes.INET);
final JdbcType realType;
if (intervalType instanceof AdjustableJdbcType) {
realType = ((AdjustableJdbcType) intervalType).resolveIndicatedType(
() -> mappingMetamodel.getTypeConfiguration(),
jdbcMapping.getJavaTypeDescriptor()
);
}
else {
realType = intervalType;
}
assertThat( jdbcMapping.getJdbcType(), is( realType));
scope.inTransaction(
(session) -> {
try {
session.persist( new EntityWithInetAddress( 1, InetAddress.getLocalHost() ) );
}
catch (UnknownHostException e) {
throw new RuntimeException( e );
}
}
);
scope.inTransaction(
(session) -> session.find( EntityWithInetAddress.class, 1)
);
}
@Entity(name = "EntityWithInetAddress")
@Table(name = "EntityWithInetAddress")
public static class EntityWithInetAddress {
@Id
private Integer id;
//tag::basic-inet-address-example[]
private InetAddress address;
//end::basic-inet-address-example[]
public EntityWithInetAddress() {
}
public EntityWithInetAddress(Integer id, InetAddress address) {
this.id = id;
this.address = address;
}
}
}

View File

@ -0,0 +1,95 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.userguide.mapping.basic;
import java.util.Map;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.jdbc.AdjustableJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
/**
* @author Christian Beikov
*/
@DomainModel(annotatedClasses = JsonMappingTests.EntityWithJson.class)
@SessionFactory
public class JsonMappingTests {
@Test
public void verifyMappings(SessionFactoryScope scope) {
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
.getRuntimeMetamodels()
.getMappingMetamodel();
final EntityPersister entityDescriptor = mappingMetamodel.findEntityDescriptor( EntityWithJson.class);
final JdbcTypeRegistry jdbcTypeRegistry = mappingMetamodel.getTypeConfiguration().getJdbcTypeRegistry();
final BasicAttributeMapping duration = (BasicAttributeMapping) entityDescriptor.findAttributeMapping("payload");
final JdbcMapping jdbcMapping = duration.getJdbcMapping();
assertThat(jdbcMapping.getJavaTypeDescriptor().getJavaTypeClass(), equalTo(Map.class));
final JdbcType intervalType = jdbcTypeRegistry.getDescriptor(SqlTypes.JSON);
final JdbcType realType;
if (intervalType instanceof AdjustableJdbcType) {
realType = ((AdjustableJdbcType) intervalType).resolveIndicatedType(
() -> mappingMetamodel.getTypeConfiguration(),
jdbcMapping.getJavaTypeDescriptor()
);
}
else {
realType = intervalType;
}
assertThat( jdbcMapping.getJdbcType(), is( realType));
scope.inTransaction(
(session) -> {
session.persist( new EntityWithJson( 1, Map.of( "name", "ABC" ) ) );
}
);
scope.inTransaction(
(session) -> session.find( EntityWithJson.class, 1)
);
}
@Entity(name = "EntityWithJson")
@Table(name = "EntityWithJson")
public static class EntityWithJson {
@Id
private Integer id;
//tag::basic-json-example[]
@JdbcTypeCode( SqlTypes.JSON )
private Map<String, String> payload;
//end::basic-json-example[]
public EntityWithJson() {
}
public EntityWithJson(Integer id, Map<String, String> payload) {
this.id = id;
this.payload = payload;
}
}
}

View File

@ -93,10 +93,10 @@ public class MimerSQLDialect extends Dialect {
return columnType( LONG32NVARCHAR ); return columnType( LONG32NVARCHAR );
//default length is 1M, which is quite low //default length is 1M, which is quite low
case BLOB: case BLOB:
return "blob($l)"; return "blob(2G)";
case CLOB: case CLOB:
case NCLOB: case NCLOB:
return "nclob($l)"; return "nclob(2G)";
} }
return super.columnType( sqlTypeCode ); return super.columnType( sqlTypeCode );
} }

View File

@ -13,7 +13,7 @@ import org.hibernate.usertype.CompositeUserType;
* *
* @since 6.0 * @since 6.0
*/ */
public @interface MapKeyCustomCompositeType { public @interface MapKeyCompositeType {
/** /**
* The custom type implementor class * The custom type implementor class
* *

View File

@ -13,7 +13,7 @@ import org.hibernate.usertype.UserType;
* *
* @since 6.0 * @since 6.0
*/ */
public @interface MapKeyCustomType { public @interface MapKeyType {
/** /**
* The custom type implementor class * The custom type implementor class
* *

View File

@ -12,7 +12,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.time.OffsetDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -73,7 +72,7 @@ import org.hibernate.annotations.LazyToOne;
import org.hibernate.annotations.LazyToOneOption; import org.hibernate.annotations.LazyToOneOption;
import org.hibernate.annotations.ListIndexBase; import org.hibernate.annotations.ListIndexBase;
import org.hibernate.annotations.ManyToAny; import org.hibernate.annotations.ManyToAny;
import org.hibernate.annotations.MapKeyCustomType; import org.hibernate.annotations.MapKeyType;
import org.hibernate.annotations.MapKeyJavaType; import org.hibernate.annotations.MapKeyJavaType;
import org.hibernate.annotations.MapKeyJdbcType; import org.hibernate.annotations.MapKeyJdbcType;
import org.hibernate.annotations.MapKeyJdbcTypeCode; import org.hibernate.annotations.MapKeyJdbcTypeCode;
@ -2593,7 +2592,7 @@ public final class AnnotationBinder {
|| property.isAnnotationPresent(MapKeyJdbcTypeCode.class) || property.isAnnotationPresent(MapKeyJdbcTypeCode.class)
|| property.isAnnotationPresent(MapKeyMutability.class) || property.isAnnotationPresent(MapKeyMutability.class)
|| property.isAnnotationPresent(MapKey.class) || property.isAnnotationPresent(MapKey.class)
|| property.isAnnotationPresent(MapKeyCustomType.class); || property.isAnnotationPresent( MapKeyType.class);
} }
private static void bindAny( private static void bindAny(

View File

@ -13,7 +13,7 @@ import java.util.Map;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.annotations.CollectionType; import org.hibernate.annotations.CollectionType;
import org.hibernate.annotations.ManyToAny; import org.hibernate.annotations.ManyToAny;
import org.hibernate.annotations.MapKeyCustomType; import org.hibernate.annotations.MapKeyType;
import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty; import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor; import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
@ -347,7 +347,7 @@ public class CollectionPropertyHolder extends AbstractPropertyHolder {
else if ( collectionProperty.isAnnotationPresent( MapKeyClass.class ) ) { else if ( collectionProperty.isAnnotationPresent( MapKeyClass.class ) ) {
canKeyBeConverted = false; canKeyBeConverted = false;
} }
else if ( collectionProperty.isAnnotationPresent( MapKeyCustomType.class ) ) { else if ( collectionProperty.isAnnotationPresent( MapKeyType.class ) ) {
canKeyBeConverted = false; canKeyBeConverted = false;
} }
} }

View File

@ -35,7 +35,7 @@ import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.ListIndexJavaType; import org.hibernate.annotations.ListIndexJavaType;
import org.hibernate.annotations.ListIndexJdbcType; import org.hibernate.annotations.ListIndexJdbcType;
import org.hibernate.annotations.ListIndexJdbcTypeCode; import org.hibernate.annotations.ListIndexJdbcTypeCode;
import org.hibernate.annotations.MapKeyCustomType; import org.hibernate.annotations.MapKeyType;
import org.hibernate.annotations.MapKeyJavaType; import org.hibernate.annotations.MapKeyJavaType;
import org.hibernate.annotations.MapKeyJdbcType; import org.hibernate.annotations.MapKeyJdbcType;
import org.hibernate.annotations.MapKeyJdbcTypeCode; import org.hibernate.annotations.MapKeyJdbcTypeCode;
@ -1347,7 +1347,7 @@ public class BasicValueBinder implements JdbcTypeIndicators {
@Override @Override
public Class<? extends UserType<?>> customType(XProperty xProperty) { public Class<? extends UserType<?>> customType(XProperty xProperty) {
final MapKeyCustomType customType = findAnnotation( xProperty, MapKeyCustomType.class ); final MapKeyType customType = findAnnotation( xProperty, MapKeyType.class );
if ( customType == null ) { if ( customType == null ) {
return null; return null;
} }
@ -1357,7 +1357,7 @@ public class BasicValueBinder implements JdbcTypeIndicators {
@Override @Override
public Parameter[] customTypeParameters(XProperty xProperty) { public Parameter[] customTypeParameters(XProperty xProperty) {
final MapKeyCustomType customType = findAnnotation( xProperty, MapKeyCustomType.class ); final MapKeyType customType = findAnnotation( xProperty, MapKeyType.class );
if ( customType == null ) { if ( customType == null ) {
return null; return null;
} }

View File

@ -15,7 +15,7 @@ import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode; import org.hibernate.FetchMode;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.annotations.MapKeyCustomCompositeType; import org.hibernate.annotations.MapKeyCompositeType;
import org.hibernate.annotations.NotFoundAction; import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty; import org.hibernate.annotations.common.reflection.XProperty;
@ -383,7 +383,7 @@ public class MapBinder extends CollectionBinder {
XProperty property, XProperty property,
XClass returnedClass, XClass returnedClass,
MetadataBuildingContext context) { MetadataBuildingContext context) {
final MapKeyCustomCompositeType compositeType = property.getAnnotation( MapKeyCustomCompositeType.class ); final MapKeyCompositeType compositeType = property.getAnnotation( MapKeyCompositeType.class );
if ( compositeType != null ) { if ( compositeType != null ) {
return compositeType.value(); return compositeType.value();
} }

View File

@ -144,9 +144,9 @@ public class DB2Dialect extends Dialect {
// Note that 31 is the maximum precision DB2 supports // Note that 31 is the maximum precision DB2 supports
return columnType( DECIMAL ); return columnType( DECIMAL );
case BLOB: case BLOB:
return "blob($l)"; return "blob";
case CLOB: case CLOB:
return "clob($l)"; return "clob";
case TIMESTAMP_WITH_TIMEZONE: case TIMESTAMP_WITH_TIMEZONE:
return "timestamp($p)"; return "timestamp($p)";
case TIME_WITH_TIMEZONE: case TIME_WITH_TIMEZONE:

View File

@ -136,10 +136,10 @@ public class DerbyDialect extends Dialect {
case LONG32VARCHAR: case LONG32VARCHAR:
return "long varchar"; return "long varchar";
case BLOB: case BLOB:
return "blob($l)"; return "blob";
case CLOB: case CLOB:
case NCLOB: case NCLOB:
return "clob($l)"; return "clob";
case TIMESTAMP: case TIMESTAMP:
case TIMESTAMP_WITH_TIMEZONE: case TIMESTAMP_WITH_TIMEZONE:
return "timestamp"; return "timestamp";

View File

@ -61,7 +61,7 @@ public class InetAddressJavaType extends AbstractClassJavaType<InetAddress> {
return (X) value.getAddress(); return (X) value.getAddress();
} }
if ( String.class.isAssignableFrom( type ) ) { if ( String.class.isAssignableFrom( type ) ) {
return (X) value.toString(); return (X) value.getHostAddress();
} }
throw unknownUnwrap( type ); throw unknownUnwrap( type );
} }

View File

@ -110,7 +110,7 @@ We decided this is the right time since 6.0 is a major release and most of the t
contracts were already changing to implement the <<read-jdbc,read-by-position>> changes. contracts were already changing to implement the <<read-jdbc,read-by-position>> changes.
One part of this work was the removal of various String-based approaches for specifying Types to use from annotations, including One part of this work was the removal of various String-based approaches for specifying Types to use from annotations, including
the removal of `@Type`, `@AnyMetaDef`, `@AnyMetaDefs`, `@MapKeyType`, @TypeDef` and `@TypeDefs`, as well as the removal of `@AnyMetaDef`, `@AnyMetaDefs`, `@TypeDef` and `@TypeDefs`, as well as
removing annotation attributes accepting the type to use as a String (e.g. `org.hibernate.annotations.CollectionType#type`) removing annotation attributes accepting the type to use as a String (e.g. `org.hibernate.annotations.CollectionType#type`)
The https://docs.jboss.org/hibernate/orm/6.0/userguide/html_single/Hibernate_User_Guide.html#domain-model[User Guide] The https://docs.jboss.org/hibernate/orm/6.0/userguide/html_single/Hibernate_User_Guide.html#domain-model[User Guide]
@ -280,8 +280,17 @@ In either case, schema validation errors could occur as 5.x used the type code `
Migration to `numeric(21)` should be easy. The migration to `interval second` might require a migration expression like Migration to `numeric(21)` should be easy. The migration to `interval second` might require a migration expression like
`cast(cast(old as numeric(21,9) / 1000000000) as interval second(9))`. `cast(cast(old as numeric(21,9) / 1000000000) as interval second(9))`.
To retain backwards compatibility, configure the setting `hibernate.type.preferred_duration_jdbc_type` to `2` To retain backwards compatibility, configure the setting `hibernate.type.preferred_duration_jdbc_type` to `NUMERIC`.
which stands for `Types.NUMERIC`.
=== UUID mapping changes
UUID now maps to the type code `SqlType.UUID` by default, which maps to the SQL type `uuid`
if possible, and falls back to `binary(16)`.
Due to the change to the native `uuid` type, schema validation errors could occur on database with native data type support.
The migration to `uuid` might require a migration expression like `cast(old as uuid)`.
To retain backwards compatibility, configure the setting `hibernate.type.preferred_uuid_jdbc_type` to `BINARY`.
[[query]] [[query]]
== Query == Query