diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacyDialect.java index 21e177efc6b2..ded2daa3f29e 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacyDialect.java @@ -127,7 +127,7 @@ protected void registerColumnTypes(TypeContributions typeContributions, ServiceR @Override public AggregateSupport getAggregateSupport() { return getVersion().isSameOrAfter( 10, 2 ) - ? MySQLAggregateSupport.LONGTEXT_INSTANCE + ? MySQLAggregateSupport.forMariaDB( this ) : AggregateSupportImpl.INSTANCE; } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java index 21b07ca2e852..9c8852793f8b 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java @@ -392,9 +392,7 @@ protected void registerColumnTypes(TypeContributions typeContributions, ServiceR @Override public AggregateSupport getAggregateSupport() { - return getMySQLVersion().isSameOrAfter( 5, 7 ) - ? MySQLAggregateSupport.JSON_INSTANCE - : super.getAggregateSupport(); + return MySQLAggregateSupport.forMySQL( this ); } @Deprecated diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBDialect.java index 938f893bfbcc..66d36064cdcc 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBDialect.java @@ -125,7 +125,7 @@ protected void registerColumnTypes(TypeContributions typeContributions, ServiceR @Override public AggregateSupport getAggregateSupport() { - return MySQLAggregateSupport.LONGTEXT_INSTANCE; + return MySQLAggregateSupport.forMariaDB( this ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java index b7003b2729a4..56dba9f4e1c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java @@ -440,7 +440,7 @@ protected void registerColumnTypes(TypeContributions typeContributions, ServiceR @Override public AggregateSupport getAggregateSupport() { - return MySQLAggregateSupport.JSON_INSTANCE; + return MySQLAggregateSupport.forMySQL( this ); } @Deprecated(since="6.4") diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/TiDBDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/TiDBDialect.java index 93ed1d8e4a4c..2bc449af0ff0 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/TiDBDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/TiDBDialect.java @@ -5,6 +5,8 @@ package org.hibernate.dialect; import org.hibernate.LockOptions; +import org.hibernate.dialect.aggregate.AggregateSupport; +import org.hibernate.dialect.aggregate.MySQLAggregateSupport; import org.hibernate.dialect.sequence.SequenceSupport; import org.hibernate.dialect.sequence.TiDBSequenceSupport; import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo; @@ -90,6 +92,11 @@ public SequenceSupport getSequenceSupport() { return TiDBSequenceSupport.INSTANCE; } + @Override + public AggregateSupport getAggregateSupport() { + return MySQLAggregateSupport.forTiDB( this ); + } + @Override public SequenceInformationExtractor getSequenceInformationExtractor() { return SequenceInformationExtractorTiDBDatabaseImpl.INSTANCE; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/aggregate/MySQLAggregateSupport.java b/hibernate-core/src/main/java/org/hibernate/dialect/aggregate/MySQLAggregateSupport.java index 6ac777a3d493..3abbf4cbe5ce 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/aggregate/MySQLAggregateSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/aggregate/MySQLAggregateSupport.java @@ -4,6 +4,7 @@ */ package org.hibernate.dialect.aggregate; +import org.hibernate.dialect.Dialect; import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.Column; import org.hibernate.metamodel.mapping.JdbcMapping; @@ -48,13 +49,32 @@ public class MySQLAggregateSupport extends AggregateSupportImpl { - public static final AggregateSupport JSON_INSTANCE = new MySQLAggregateSupport( true ); - public static final AggregateSupport LONGTEXT_INSTANCE = new MySQLAggregateSupport( false ); + private static final AggregateSupport JSON_INSTANCE = new MySQLAggregateSupport( true, false ); + private static final AggregateSupport JSON_WITH_UUID_INSTANCE = new MySQLAggregateSupport( true, true ); + private static final AggregateSupport LONGTEXT_INSTANCE = new MySQLAggregateSupport( false, false ); private final boolean jsonType; + private final boolean uuidFunctions; - public MySQLAggregateSupport(boolean jsonType) { + private MySQLAggregateSupport(boolean jsonType, boolean uuidFunctions) { this.jsonType = jsonType; + this.uuidFunctions = uuidFunctions; + } + + public static AggregateSupport forMySQL(Dialect dialect) { + return dialect.getVersion().isSameOrAfter( 8 ) + ? JSON_WITH_UUID_INSTANCE + : dialect.getVersion().isSameOrAfter( 5, 7 ) + ? JSON_INSTANCE + : AggregateSupportImpl.INSTANCE; + } + + public static AggregateSupport forTiDB(Dialect dialect) { + return JSON_WITH_UUID_INSTANCE; + } + + public static AggregateSupport forMariaDB(Dialect dialect) { + return LONGTEXT_INSTANCE; } @Override @@ -92,10 +112,19 @@ public String aggregateComponentCustomReadExpression( ); case UUID: if ( column.getJdbcMapping().getJdbcType().isBinary() ) { - return template.replace( - placeholder, - "unhex(replace(json_unquote(" + queryExpression( aggregateParentReadExpression, columnExpression ) + "),'-',''))" - ); + if ( uuidFunctions ) { + return template.replace( + placeholder, + "uuid_to_bin(json_unquote(" + queryExpression( aggregateParentReadExpression, columnExpression ) + "))" + ); + } + else { + return template.replace( + placeholder, + "unhex(replace(json_unquote(" + queryExpression( aggregateParentReadExpression, + columnExpression ) + "),'-',''))" + ); + } } // Fall-through intended default: @@ -142,7 +171,7 @@ private String queryExpression(String aggregateParentReadExpression, String colu } } - private static String jsonCustomWriteExpression(String customWriteExpression, JdbcMapping jdbcMapping) { + private String jsonCustomWriteExpression(String customWriteExpression, JdbcMapping jdbcMapping) { final int sqlTypeCode = jdbcMapping.getJdbcType().getDefaultSqlTypeCode(); switch ( sqlTypeCode ) { case BINARY: @@ -159,7 +188,12 @@ private static String jsonCustomWriteExpression(String customWriteExpression, Jd return "date_format(" + customWriteExpression + ",'%Y-%m-%dT%T.%fZ')"; case UUID: if ( jdbcMapping.getJdbcType().isBinary() ) { - return "regexp_replace(lower(hex(" + customWriteExpression + ")),'^(.{8})(.{4})(.{4})(.{4})(.{12})$','$1-$2-$3-$4-$5')"; + if ( uuidFunctions ) { + return "bin_to_uuid(" + customWriteExpression + ")"; + } + else { + return "regexp_replace(lower(hex(" + customWriteExpression + ")),'^(.{8})(.{4})(.{4})(.{4})(.{12})$','$1-$2-$3-$4-$5')"; + } } // Fall-through intended default: diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/instant/InstantWithNormalizedTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/instant/InstantWithNormalizedTest.java index 1170b3af0ecb..f5686aca920c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/instant/InstantWithNormalizedTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/instant/InstantWithNormalizedTest.java @@ -10,6 +10,7 @@ import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.JdbcSettings; import org.hibernate.dialect.MySQLDialect; +import org.hibernate.dialect.TiDBDialect; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; import org.hibernate.testing.orm.junit.Jpa; import org.hibernate.testing.orm.junit.Setting; @@ -31,6 +32,7 @@ {@Setting(name = AvailableSettings.TIMEZONE_DEFAULT_STORAGE, value = "NORMALIZE"), @Setting(name = JdbcSettings.JDBC_TIME_ZONE, value = "+01:00")}) @SkipForDialect(dialectClass = MySQLDialect.class, reason = "MySQL hangs dropping the table") +@SkipForDialect(dialectClass = TiDBDialect.class, reason = "Values stored in timestamp DDL type columns get the JDBC time zone offset subtracted") public class InstantWithNormalizedTest { @Test public void test(EntityManagerFactoryScope scope) {