HHH-15115 Fix PostgreSQL SqmMultiTableMutationStrategy
This commit is contained in:
parent
6169a60ecd
commit
cd78676608
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.boot.model.naming.Identifier;
|
import org.hibernate.boot.model.naming.Identifier;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||||
|
@ -182,18 +183,20 @@ public class CteDeleteHandler extends AbstractCteMutationHandler implements Dele
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getCteTableName(String tableExpression) {
|
protected String getCteTableName(String tableExpression) {
|
||||||
|
final Dialect dialect = getSessionFactory().getJdbcServices().getDialect();
|
||||||
if ( Identifier.isQuoted( tableExpression ) ) {
|
if ( Identifier.isQuoted( tableExpression ) ) {
|
||||||
tableExpression = tableExpression.substring( 1, tableExpression.length() - 1 );
|
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) {
|
protected String getCteTableName(PluralAttributeMapping pluralAttribute) {
|
||||||
|
final Dialect dialect = getSessionFactory().getJdbcServices().getDialect();
|
||||||
final String hibernateEntityName = pluralAttribute.findContainingEntityMapping().getEntityName();
|
final String hibernateEntityName = pluralAttribute.findContainingEntityMapping().getEntityName();
|
||||||
final String jpaEntityName = getSessionFactory().getJpaMetamodel().entity( hibernateEntityName ).getName();
|
final String jpaEntityName = getSessionFactory().getJpaMetamodel().entity( hibernateEntityName ).getName();
|
||||||
return DELETE_RESULT_TABLE_NAME_PREFIX + jpaEntityName + "_" + pluralAttribute.getRootPathName().substring(
|
return Identifier.toIdentifier(
|
||||||
hibernateEntityName.length() + 1
|
DELETE_RESULT_TABLE_NAME_PREFIX + jpaEntityName + "_" +
|
||||||
);
|
pluralAttribute.getRootPathName().substring( hibernateEntityName.length() + 1 )
|
||||||
|
).render( dialect );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.util.Map;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import org.hibernate.boot.model.naming.Identifier;
|
import org.hibernate.boot.model.naming.Identifier;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.dialect.temptable.TemporaryTable;
|
import org.hibernate.dialect.temptable.TemporaryTable;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
@ -1151,14 +1152,11 @@ public class CteInsertHandler implements InsertHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getCteTableName(String tableExpression, String subPrefix) {
|
protected String getCteTableName(String tableExpression, String subPrefix) {
|
||||||
|
final Dialect dialect = sessionFactory.getJdbcServices().getDialect();
|
||||||
if ( Identifier.isQuoted( tableExpression ) ) {
|
if ( Identifier.isQuoted( tableExpression ) ) {
|
||||||
tableExpression = unquote( tableExpression );
|
tableExpression = tableExpression.substring( 1, tableExpression.length() - 1 );
|
||||||
return DML_RESULT_TABLE_NAME_PREFIX + subPrefix + tableExpression;
|
|
||||||
}
|
}
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import org.hibernate.boot.model.naming.Identifier;
|
import org.hibernate.boot.model.naming.Identifier;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
@ -324,19 +325,19 @@ public class CteUpdateHandler extends AbstractCteMutationHandler implements Upda
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getCteTableName(String tableExpression) {
|
protected String getCteTableName(String tableExpression) {
|
||||||
|
final Dialect dialect = getSessionFactory().getJdbcServices().getDialect();
|
||||||
if ( Identifier.isQuoted( tableExpression ) ) {
|
if ( Identifier.isQuoted( tableExpression ) ) {
|
||||||
tableExpression = tableExpression.substring( 1, tableExpression.length() - 1 );
|
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) {
|
protected String getInsertCteTableName(String tableExpression) {
|
||||||
|
final Dialect dialect = getSessionFactory().getJdbcServices().getDialect();
|
||||||
if ( Identifier.isQuoted( tableExpression ) ) {
|
if ( Identifier.isQuoted( tableExpression ) ) {
|
||||||
tableExpression = tableExpression.substring( 1, tableExpression.length() - 1 );
|
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) {
|
private Expression asExpression(SelectClause selectClause) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue