diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java index c8093ae603..19a4868e55 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteDeleteHandler.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Map; import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping; @@ -182,18 +183,20 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele @Override protected String getCteTableName(String tableExpression) { + final Dialect dialect = getSessionFactory().getJdbcServices().getDialect(); if ( Identifier.isQuoted( tableExpression ) ) { tableExpression = tableExpression.substring( 1, tableExpression.length() - 1 ); - return DELETE_RESULT_TABLE_NAME_PREFIX + tableExpression; } - return DELETE_RESULT_TABLE_NAME_PREFIX + tableExpression; + return Identifier.toIdentifier( DELETE_RESULT_TABLE_NAME_PREFIX + tableExpression ).render( dialect ); } protected String getCteTableName(PluralAttributeMapping pluralAttribute) { + final Dialect dialect = getSessionFactory().getJdbcServices().getDialect(); final String hibernateEntityName = pluralAttribute.findContainingEntityMapping().getEntityName(); final String jpaEntityName = getSessionFactory().getJpaMetamodel().entity( hibernateEntityName ).getName(); - return DELETE_RESULT_TABLE_NAME_PREFIX + jpaEntityName + "_" + pluralAttribute.getRootPathName().substring( - hibernateEntityName.length() + 1 - ); + return Identifier.toIdentifier( + DELETE_RESULT_TABLE_NAME_PREFIX + jpaEntityName + "_" + + pluralAttribute.getRootPathName().substring( hibernateEntityName.length() + 1 ) + ).render( dialect ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java index 30ac0c382c..f75ebc3c9a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java @@ -17,6 +17,7 @@ import java.util.Map; import java.util.function.BiConsumer; import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.dialect.Dialect; import org.hibernate.dialect.temptable.TemporaryTable; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -1151,14 +1152,11 @@ public class CteInsertHandler implements InsertHandler { } protected String getCteTableName(String tableExpression, String subPrefix) { + final Dialect dialect = sessionFactory.getJdbcServices().getDialect(); if ( Identifier.isQuoted( tableExpression ) ) { - tableExpression = unquote( tableExpression ); - return DML_RESULT_TABLE_NAME_PREFIX + subPrefix + tableExpression; + tableExpression = tableExpression.substring( 1, tableExpression.length() - 1 ); } - return DML_RESULT_TABLE_NAME_PREFIX + subPrefix + tableExpression; + return Identifier.toIdentifier( DML_RESULT_TABLE_NAME_PREFIX + subPrefix + tableExpression ).render( dialect ); } - private String unquote(String tableExpression) { - return tableExpression.substring( 1, tableExpression.length() - 1 ); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java index 39c1aa4840..dfd764bf11 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java @@ -12,6 +12,7 @@ import java.util.Map; import java.util.function.BiConsumer; import org.hibernate.boot.model.naming.Identifier; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.mapping.EntityMappingType; @@ -324,19 +325,19 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda @Override protected String getCteTableName(String tableExpression) { + final Dialect dialect = getSessionFactory().getJdbcServices().getDialect(); if ( Identifier.isQuoted( tableExpression ) ) { tableExpression = tableExpression.substring( 1, tableExpression.length() - 1 ); - return UPDATE_RESULT_TABLE_NAME_PREFIX + tableExpression; } - return UPDATE_RESULT_TABLE_NAME_PREFIX + tableExpression; + return Identifier.toIdentifier( UPDATE_RESULT_TABLE_NAME_PREFIX + tableExpression ).render( dialect ); } protected String getInsertCteTableName(String tableExpression) { + final Dialect dialect = getSessionFactory().getJdbcServices().getDialect(); if ( Identifier.isQuoted( tableExpression ) ) { tableExpression = tableExpression.substring( 1, tableExpression.length() - 1 ); - return INSERT_RESULT_TABLE_NAME_PREFIX + tableExpression; } - return INSERT_RESULT_TABLE_NAME_PREFIX + tableExpression; + return Identifier.toIdentifier( INSERT_RESULT_TABLE_NAME_PREFIX + tableExpression ).render( dialect ); } private Expression asExpression(SelectClause selectClause) { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/JoinedInheritanceDeletionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/JoinedInheritanceDeletionTest.java new file mode 100644 index 0000000000..3faf1cf745 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/JoinedInheritanceDeletionTest.java @@ -0,0 +1,114 @@ +package org.hibernate.orm.test.inheritance; + +import org.hibernate.testing.TestForIssue; +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.BeforeEach; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; + +@DomainModel( + annotatedClasses = { + JoinedInheritanceDeletionTest.Person.class, + JoinedInheritanceDeletionTest.Employee.class, + JoinedInheritanceDeletionTest.Customer.class + } +) +@SessionFactory +@TestForIssue(jiraKey = "HHH-15115") +public class JoinedInheritanceDeletionTest { + + @BeforeEach + public void setUp(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Person person = new Person( 1, "Bob" ); + Employee employee = new Employee( 2, "Chris", "Software Engineer" ); + Customer customer = new Customer( 3, "Miriam", "" ); + + session.save( person ); + session.save( employee ); + session.save( customer ); + } + ); + } + + @Test + public void testDelete(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.createQuery( "delete from Person" ).executeUpdate(); + } + ); + } + + @Entity(name = "Person") + @Inheritance(strategy = InheritanceType.JOINED) + public static class Person { + + @Id + private Integer id; + + private String name; + + public Person() { + } + + public Person(Integer id, String name) { + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + + } + + @Entity(name = "Customer") + public static class Customer extends Person { + + private String comments; + + public Customer() { + } + + public Customer(Integer id, String name, String comments) { + super( id, name ); + this.comments = comments; + } + + public String getComments() { + return comments; + } + + } + + @Entity(name = "Employee") + public static class Employee extends Person { + + private String title; + + public Employee() { + } + + public Employee(Integer id, String name, String title) { + super( id, name ); + this.title = title; + } + + public String getTitle() { + return title; + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/JoinedInheritanceWithDefaultSchemaDeletionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/JoinedInheritanceWithDefaultSchemaDeletionTest.java new file mode 100644 index 0000000000..8b5fa32b0f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/JoinedInheritanceWithDefaultSchemaDeletionTest.java @@ -0,0 +1,124 @@ +package org.hibernate.orm.test.inheritance; + +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.dialect.PostgreSQLDialect; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.RequiresDialect; +import org.hibernate.testing.orm.junit.ServiceRegistry; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.hibernate.testing.orm.junit.Setting; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; + +@RequiresDialect(PostgreSQLDialect.class) +@DomainModel( + annotatedClasses = { + JoinedInheritanceWithDefaultSchemaDeletionTest.Person.class, + JoinedInheritanceWithDefaultSchemaDeletionTest.Employee.class, + JoinedInheritanceWithDefaultSchemaDeletionTest.Customer.class + } +) +@SessionFactory +@ServiceRegistry( + settings = @Setting( name = AvailableSettings.DEFAULT_SCHEMA,value = "public") +) +@TestForIssue(jiraKey = "HHH-15115") +public class JoinedInheritanceWithDefaultSchemaDeletionTest { + + @BeforeEach + public void setUp(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + Person person = new Person( 1, "Bob" ); + Employee employee = new Employee( 2, "Chris", "Software Engineer" ); + Customer customer = new Customer( 3, "Miriam", "" ); + + session.save( person ); + session.save( employee ); + session.save( customer ); + } + ); + } + + @Test + public void testDelete(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.createQuery( "delete from Person" ).executeUpdate(); + } + ); + } + + @Entity(name = "Person") + @Inheritance(strategy = InheritanceType.JOINED) + public static class Person { + + @Id + private Integer id; + + private String name; + + public Person() { + } + + public Person(Integer id, String name) { + this.id = id; + this.name = name; + } + + public Integer getId() { + return id; + } + + public String getName() { + return name; + } + + } + + @Entity(name = "Customer") + public static class Customer extends Person { + + private String comments; + + public Customer() { + } + + public Customer(Integer id, String name, String comments) { + super( id, name ); + this.comments = comments; + } + + public String getComments() { + return comments; + } + + } + + @Entity(name = "Employee") + public static class Employee extends Person { + + private String title; + + public Employee() { + } + + public Employee(Integer id, String name, String title) { + super( id, name ); + this.title = title; + } + + public String getTitle() { + return title; + } + } + +}