HHH-15503 Add UUID support for MariaDB 10.7
This commit is contained in:
parent
56125e2614
commit
69668c32b7
|
@ -125,7 +125,7 @@ stage('Build') {
|
||||||
break;
|
break;
|
||||||
case "mariadb":
|
case "mariadb":
|
||||||
docker.withRegistry('https://index.docker.io/v1/', 'hibernateci.hub.docker.com') {
|
docker.withRegistry('https://index.docker.io/v1/', 'hibernateci.hub.docker.com') {
|
||||||
docker.image('mariadb:10.5.8').pull()
|
docker.image('mariadb:10.7.5').pull()
|
||||||
}
|
}
|
||||||
sh "./docker_db.sh mariadb"
|
sh "./docker_db.sh mariadb"
|
||||||
state[buildEnv.tag]['containerName'] = "mariadb"
|
state[buildEnv.tag]['containerName'] = "mariadb"
|
||||||
|
@ -148,7 +148,7 @@ stage('Build') {
|
||||||
break;
|
break;
|
||||||
case "oracle":
|
case "oracle":
|
||||||
docker.withRegistry('https://index.docker.io/v1/', 'hibernateci.hub.docker.com') {
|
docker.withRegistry('https://index.docker.io/v1/', 'hibernateci.hub.docker.com') {
|
||||||
docker.image('quillbuilduser/oracle-18-xe').pull()
|
docker.image('gvenzl/oracle-xe:18.4.0-full').pull()
|
||||||
}
|
}
|
||||||
sh "./docker_db.sh oracle_18"
|
sh "./docker_db.sh oracle_18"
|
||||||
state[buildEnv.tag]['containerName'] = "oracle"
|
state[buildEnv.tag]['containerName'] = "oracle"
|
||||||
|
|
|
@ -65,7 +65,7 @@ mysql_8_0() {
|
||||||
|
|
||||||
mariadb() {
|
mariadb() {
|
||||||
$CONTAINER_CLI rm -f mariadb || true
|
$CONTAINER_CLI rm -f mariadb || true
|
||||||
$CONTAINER_CLI run --name mariadb -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=hibernate_orm_test -p3306:3306 -d docker.io/mariadb:10.5.8 --character-set-server=utf8mb4 --collation-server=utf8mb4_bin --skip-character-set-client-handshake
|
$CONTAINER_CLI run --name mariadb -e MYSQL_USER=hibernate_orm_test -e MYSQL_PASSWORD=hibernate_orm_test -e MYSQL_DATABASE=hibernate_orm_test -e MYSQL_ROOT_PASSWORD=hibernate_orm_test -p3306:3306 -d docker.io/mariadb:10.7.5 --character-set-server=utf8mb4 --collation-server=utf8mb4_bin --skip-character-set-client-handshake
|
||||||
OUTPUT=
|
OUTPUT=
|
||||||
n=0
|
n=0
|
||||||
until [ "$n" -ge 5 ]
|
until [ "$n" -ge 5 ]
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.hibernate.boot.model.TypeContributions;
|
||||||
import org.hibernate.dialect.function.CommonFunctionFactory;
|
import org.hibernate.dialect.function.CommonFunctionFactory;
|
||||||
import org.hibernate.dialect.sequence.MariaDBSequenceSupport;
|
import org.hibernate.dialect.sequence.MariaDBSequenceSupport;
|
||||||
import org.hibernate.dialect.sequence.SequenceSupport;
|
import org.hibernate.dialect.sequence.SequenceSupport;
|
||||||
|
@ -18,6 +19,7 @@ import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
|
||||||
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
|
||||||
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
import org.hibernate.sql.ast.spi.StandardSqlAstTranslatorFactory;
|
||||||
|
@ -26,6 +28,13 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
|
||||||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorMariaDBDatabaseImpl;
|
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorMariaDBDatabaseImpl;
|
||||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
|
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
|
||||||
|
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
|
||||||
|
|
||||||
|
import static org.hibernate.type.SqlTypes.OTHER;
|
||||||
|
import static org.hibernate.type.SqlTypes.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@linkplain Dialect SQL dialect} for MariaDB
|
* A {@linkplain Dialect SQL dialect} for MariaDB
|
||||||
|
@ -80,6 +89,44 @@ public class MariaDBDialect extends MySQLDialect {
|
||||||
commonFunctionFactory.inverseDistributionOrderedSetAggregates_windowEmulation();
|
commonFunctionFactory.inverseDistributionOrderedSetAggregates_windowEmulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerColumnTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||||
|
super.registerColumnTypes( typeContributions, serviceRegistry );
|
||||||
|
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
|
||||||
|
if ( getVersion().isSameOrAfter( 10, 7 ) ) {
|
||||||
|
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JdbcType resolveSqlTypeDescriptor(
|
||||||
|
String columnTypeName,
|
||||||
|
int jdbcTypeCode,
|
||||||
|
int precision,
|
||||||
|
int scale,
|
||||||
|
JdbcTypeRegistry jdbcTypeRegistry) {
|
||||||
|
switch ( jdbcTypeCode ) {
|
||||||
|
case OTHER:
|
||||||
|
switch ( columnTypeName ) {
|
||||||
|
case "uuid":
|
||||||
|
jdbcTypeCode = UUID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return super.resolveSqlTypeDescriptor( columnTypeName, jdbcTypeCode, precision, scale, jdbcTypeRegistry );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
|
||||||
|
super.contributeTypes( typeContributions, serviceRegistry );
|
||||||
|
final JdbcTypeRegistry jdbcTypeRegistry = typeContributions.getTypeConfiguration()
|
||||||
|
.getJdbcTypeRegistry();
|
||||||
|
if ( getVersion().isSameOrAfter( 10, 7 ) ) {
|
||||||
|
jdbcTypeRegistry.addDescriptorIfAbsent( VarcharUUIDJdbcType.INSTANCE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
public SqlAstTranslatorFactory getSqlAstTranslatorFactory() {
|
||||||
return new StandardSqlAstTranslatorFactory() {
|
return new StandardSqlAstTranslatorFactory() {
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* 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.dialect;
|
||||||
|
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.hibernate.type.SqlTypes;
|
||||||
|
import org.hibernate.type.descriptor.ValueBinder;
|
||||||
|
import org.hibernate.type.descriptor.ValueExtractor;
|
||||||
|
import org.hibernate.type.descriptor.WrapperOptions;
|
||||||
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.BasicBinder;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
|
||||||
|
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialized type mapping for {@link UUID} and the UUID SQL data type,
|
||||||
|
* which binds and reads the UUID through JDBC <code>getString</code>/<code>setString</code> methods.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class VarcharUUIDJdbcType implements JdbcType {
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final VarcharUUIDJdbcType INSTANCE = new VarcharUUIDJdbcType();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getJdbcTypeCode() {
|
||||||
|
return SqlTypes.VARCHAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDefaultSqlTypeCode() {
|
||||||
|
return SqlTypes.UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MariaDBUUIDJdbcType";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getPreferredJavaTypeClass(WrapperOptions options) {
|
||||||
|
return UUID.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
|
||||||
|
return new BasicBinder<>( javaType, this ) {
|
||||||
|
@Override
|
||||||
|
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
|
||||||
|
throws SQLException {
|
||||||
|
st.setString( index, getJavaType().unwrap( value, String.class, options ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
|
||||||
|
throws SQLException {
|
||||||
|
st.setString( name, getJavaType().unwrap( value, String.class, options ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
|
||||||
|
return new BasicExtractor<>( javaType, this ) {
|
||||||
|
@Override
|
||||||
|
protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) throws SQLException {
|
||||||
|
return getJavaType().wrap( rs.getString( paramIndex ), options );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected X doExtract(CallableStatement statement, int index, WrapperOptions options) throws SQLException {
|
||||||
|
return getJavaType().wrap( statement.getString( index ), options );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException {
|
||||||
|
return getJavaType().wrap( statement.getString( name ), options );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,8 +13,10 @@ import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
|
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.dialect.MariaDBDialect;
|
||||||
import org.hibernate.dialect.MySQLDialect;
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
import org.hibernate.dialect.PostgreSQLDialect;
|
import org.hibernate.dialect.PostgreSQLDialect;
|
||||||
|
import org.hibernate.dialect.VarcharUUIDJdbcType;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.descriptor.java.UUIDJavaType;
|
import org.hibernate.type.descriptor.java.UUIDJavaType;
|
||||||
|
@ -50,11 +52,18 @@ public class UUIDBasedIdInterpretationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@JiraKey( "HHH-10564" )
|
@JiraKey( "HHH-10564" )
|
||||||
@RequiresDialect( value = MySQLDialect.class, majorVersion = 5 )
|
@RequiresDialect(value = MySQLDialect.class, matchSubTypes = false)
|
||||||
public void testMySQL(DomainModelScope scope) {
|
public void testMySQL(DomainModelScope scope) {
|
||||||
checkUuidTypeUsed( scope, VarbinaryJdbcType.class );
|
checkUuidTypeUsed( scope, VarbinaryJdbcType.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@JiraKey( "HHH-10564" )
|
||||||
|
@RequiresDialect(value = MariaDBDialect.class, majorVersion = 10, minorVersion = 7)
|
||||||
|
public void testMariaDB(DomainModelScope scope) {
|
||||||
|
checkUuidTypeUsed( scope, VarcharUUIDJdbcType.class );
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@JiraKey( "HHH-10564" )
|
@JiraKey( "HHH-10564" )
|
||||||
@RequiresDialect( value = PostgreSQLDialect.class, majorVersion = 9, minorVersion = 4 )
|
@RequiresDialect( value = PostgreSQLDialect.class, majorVersion = 9, minorVersion = 4 )
|
||||||
|
|
|
@ -9,4 +9,16 @@
|
||||||
This guide discusses migration from Hibernate ORM version 6.2. For migration from
|
This guide discusses migration from Hibernate ORM version 6.2. For migration from
|
||||||
earlier versions, see any other pertinent migration guides as well.
|
earlier versions, see any other pertinent migration guides as well.
|
||||||
|
|
||||||
* link:../../../6.0/migration-guide/migration-guide.html[6.2 Migration guide]
|
* link:../../../6.1/migration-guide/migration-guide.html[6.1 Migration guide]
|
||||||
|
* link:../../../6.0/migration-guide/migration-guide.html[6.0 Migration guide]
|
||||||
|
|
||||||
|
== Default DDL type changes
|
||||||
|
|
||||||
|
=== UUID mapping changes on MariaDB
|
||||||
|
|
||||||
|
On MariaDB, the type code `SqlType.UUID` now by default refers to the DDL type `uuid`, whereas before it was using `binary(16)`.
|
||||||
|
Due to this change, schema validation errors could occur on existing databases.
|
||||||
|
|
||||||
|
The migration to `uuid` requires a migration expression like `cast(old as uuid)`.
|
||||||
|
|
||||||
|
To retain backwards compatibility, configure the setting `hibernate.type.preferred_uuid_jdbc_type` to `BINARY`.
|
||||||
|
|
Loading…
Reference in New Issue