From 29865361b0552b20b1ddb90deba96a39d4d3a53b Mon Sep 17 00:00:00 2001 From: Gavin King Date: Fri, 11 Jul 2025 16:08:16 +0200 Subject: [PATCH] HHH-19608 automatically add @PartitionKey to the primary key on databases where this is required also enable support for table partitioning on MySQL and Maria --- .../main/java/org/hibernate/dialect/Dialect.java | 10 ++++++++++ .../java/org/hibernate/dialect/MySQLDialect.java | 10 ++++++++++ .../org/hibernate/dialect/PostgreSQLDialect.java | 5 +++++ .../id/enhanced/ExportableColumnHelper.java | 5 +++++ .../java/org/hibernate/mapping/Collection.java | 5 +++++ .../main/java/org/hibernate/mapping/OneToMany.java | 5 +++++ .../org/hibernate/mapping/PersistentClass.java | 14 +++++++++++++- .../src/main/java/org/hibernate/mapping/Value.java | 2 ++ 8 files changed, 55 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 87f41aefa8d4..310d9615da6d 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -4622,6 +4622,16 @@ public boolean supportsPartitionBy() { return false; } + /** + * Does this dialect require that the columns listed in + * {@code partition by} also occur in the primary key? + * + * @since 7.1 + */ + public boolean addPartitionKeyToPrimaryKey() { + return false; + } + /** * Override {@link DatabaseMetaData#supportsNamedParameters()}. * 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 e6bfb8f5ba81..ea9acb405913 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java @@ -1099,6 +1099,16 @@ public String getSelectGUIDString() { return "select uuid()"; } + @Override + public boolean supportsPartitionBy() { + return true; + } + + @Override + public boolean addPartitionKeyToPrimaryKey() { + return true; + } + @Override public boolean supportsCommentOn() { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java index 0a0d4af2d63d..e2573e5142b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java @@ -821,6 +821,11 @@ public boolean supportsPartitionBy() { return true; } + @Override + public boolean addPartitionKeyToPrimaryKey() { + return true; + } + @Override public boolean supportsNonQueryWithCTE() { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/ExportableColumnHelper.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/ExportableColumnHelper.java index 4d4826160701..c0dba2aa18b8 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/ExportableColumnHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/ExportableColumnHelper.java @@ -143,6 +143,11 @@ public boolean isColumnInsertable(int index) { public boolean isColumnUpdateable(int index) { return true; } + + @Override + public boolean isPartitionKey() { + return false; + } } ); return column; } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java b/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java index 0b7d492b6647..5831e511037d 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Collection.java @@ -897,4 +897,9 @@ public Supplier getDeleteAllExpectation() { public void setDeleteAllExpectation(Supplier deleteAllExpectation) { this.deleteAllExpectation = deleteAllExpectation; } + + @Override + public boolean isPartitionKey() { + return false; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/OneToMany.java b/hibernate-core/src/main/java/org/hibernate/mapping/OneToMany.java index db94b2c516e6..5edd4cd6dac9 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/OneToMany.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/OneToMany.java @@ -234,4 +234,9 @@ public boolean isColumnUpdateable(int index) { public String toString() { return getClass().getSimpleName(); } + + @Override + public boolean isPartitionKey() { + return false; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java b/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java index 0df36e9a3e8c..7af9f69cce1b 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/PersistentClass.java @@ -427,10 +427,22 @@ public void createPrimaryKey() { final PrimaryKey pk = new PrimaryKey( table ); pk.setName( PK_ALIAS.toAliasString( table.getName() ) ); pk.addColumns( getKey() ); - + if ( addPartitionKeyToPrimaryKey() ) { + for ( Property property : getProperties() ) { + if ( property.getValue().isPartitionKey() ) { + pk.addColumns( property.getValue() ); + } + } + } table.setPrimaryKey( pk ); } + private boolean addPartitionKeyToPrimaryKey() { + return metadataBuildingContext.getMetadataCollector() + .getDatabase().getDialect() + .addPartitionKeyToPrimaryKey(); + } + public abstract String getWhere(); public int getBatchSize() { diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Value.java b/hibernate-core/src/main/java/org/hibernate/mapping/Value.java index faf04a75b197..a31aab07297d 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Value.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Value.java @@ -123,6 +123,8 @@ private Type getIdType(EntityType entityType) { boolean isAlternateUniqueKey(); + boolean isPartitionKey(); + boolean isNullable(); void createForeignKey();