HHH-18470: fix duplicate generated FK names for TABLE_PER_CLASS inheritance
This commit is contained in:
parent
ee00217733
commit
f5e1d1cd73
|
@ -8,7 +8,6 @@ package org.hibernate.mapping;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Internal;
|
||||
|
@ -70,10 +69,12 @@ public class DenormalizedTable extends Table {
|
|||
if ( foreignKey.getReferencedTable() == null ) {
|
||||
foreignKey.setReferencedTable( referencedClass.getTable() );
|
||||
}
|
||||
|
||||
final ForeignKey denormalizedForeignKey = createDenormalizedForeignKey( foreignKey );
|
||||
createForeignKey(
|
||||
context.getBuildingOptions()
|
||||
.getImplicitNamingStrategy()
|
||||
.determineForeignKeyName( new ForeignKeyNameSource( foreignKey, this, context ) )
|
||||
.determineForeignKeyName( new ForeignKeyNameSource( denormalizedForeignKey, this, context ) )
|
||||
.render( context.getMetadataCollector().getDatabase().getDialect() ),
|
||||
foreignKey.getColumns(),
|
||||
foreignKey.getReferencedEntityName(),
|
||||
|
@ -83,6 +84,18 @@ public class DenormalizedTable extends Table {
|
|||
}
|
||||
}
|
||||
|
||||
private ForeignKey createDenormalizedForeignKey(ForeignKey includedTableFk) {
|
||||
final ForeignKey denormalizedForeignKey = new ForeignKey(this);
|
||||
denormalizedForeignKey.setReferencedEntityName( includedTableFk.getReferencedEntityName() );
|
||||
denormalizedForeignKey.setKeyDefinition( includedTableFk.getKeyDefinition() );
|
||||
denormalizedForeignKey.setReferencedTable( includedTableFk.getReferencedTable() );
|
||||
denormalizedForeignKey.addReferencedColumns( includedTableFk.getReferencedColumns() );
|
||||
for ( Column keyColumn : includedTableFk.getColumns() ) {
|
||||
denormalizedForeignKey.addColumn( keyColumn );
|
||||
}
|
||||
return denormalizedForeignKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Column getColumn(Column column) {
|
||||
Column superColumn = super.getColumn( column );
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package org.hibernate.orm.test.inheritance;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.JiraKey;
|
||||
import org.hibernate.testing.orm.junit.Jpa;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Paria Hosseiny
|
||||
*/
|
||||
@JiraKey("HHH-18470")
|
||||
@Jpa(
|
||||
annotatedClasses = {
|
||||
DenormalizedTableForeignKeyGeneratorTest.Employee.class,
|
||||
DenormalizedTableForeignKeyGeneratorTest.Manager.class,
|
||||
DenormalizedTableForeignKeyGeneratorTest.Address.class,
|
||||
DenormalizedTableForeignKeyGeneratorTest.Territory.class
|
||||
}
|
||||
)
|
||||
|
||||
@RequiresDialect(H2Dialect.class)
|
||||
public class DenormalizedTableForeignKeyGeneratorTest {
|
||||
|
||||
@Test
|
||||
public void shouldCreateForeignKeyForSubclasses(EntityManagerFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
entityManager -> {
|
||||
String managerQuery = "select CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS " +
|
||||
"WHERE TABLE_NAME='MANAGER' " +
|
||||
"AND CONSTRAINT_TYPE='FOREIGN KEY'";
|
||||
List<String> managerForeignKeyNames = entityManager.createNativeQuery(managerQuery).getResultList();
|
||||
|
||||
String employeeQuery = "select CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS " +
|
||||
"WHERE TABLE_NAME='EMPLOYEE' " +
|
||||
"AND CONSTRAINT_TYPE='FOREIGN KEY'";
|
||||
String employeeForeignKeyName = entityManager.createNativeQuery(employeeQuery).getSingleResult().toString();
|
||||
|
||||
assertThat(employeeForeignKeyName).isNotNull();
|
||||
assertThat(managerForeignKeyNames).isNotNull().hasSize(2);
|
||||
assertThat(managerForeignKeyNames).doesNotContain(employeeForeignKeyName);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "Employee")
|
||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||
static class Employee implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
private Address address;
|
||||
|
||||
}
|
||||
|
||||
@Entity(name = "Manager")
|
||||
static class Manager extends Employee {
|
||||
|
||||
@OneToOne(fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
|
||||
private Territory territory;
|
||||
}
|
||||
|
||||
@Entity(name = "Address")
|
||||
static class Address {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
@Column(nullable = false, columnDefinition = "TEXT")
|
||||
private String address = "";
|
||||
}
|
||||
|
||||
@Entity(name = "Territory")
|
||||
static class Territory {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
Long id;
|
||||
|
||||
@Column
|
||||
private String location = "";
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue