HHH-7134 - Detection of wrong circularity when two tables with same name in different schemas

Fixes FKSecondPass processing to take catalog and schema in accounts. Corresponding test class is
org.hibernate.test.cfg.WrongCircularityDetectionTest.
This commit is contained in:
Didier Villevalois 2012-03-01 15:44:38 +01:00 committed by Strong Liu
parent 3e2be6a009
commit 8e30a2b86d
2 changed files with 80 additions and 2 deletions

View File

@ -1425,7 +1425,7 @@ public class Configuration implements Serializable {
if ( sp.isInPrimaryKey() ) { if ( sp.isInPrimaryKey() ) {
String referenceEntityName = sp.getReferencedEntityName(); String referenceEntityName = sp.getReferencedEntityName();
PersistentClass classMapping = getClassMapping( referenceEntityName ); PersistentClass classMapping = getClassMapping( referenceEntityName );
String dependentTable = classMapping.getTable().getQuotedName(); String dependentTable = quotedTableName(classMapping.getTable());
if ( !isADependencyOf.containsKey( dependentTable ) ) { if ( !isADependencyOf.containsKey( dependentTable ) ) {
isADependencyOf.put( dependentTable, new HashSet<FkSecondPass>() ); isADependencyOf.put( dependentTable, new HashSet<FkSecondPass>() );
} }
@ -1495,7 +1495,7 @@ public class Configuration implements Serializable {
} }
for ( FkSecondPass sp : dependencies ) { for ( FkSecondPass sp : dependencies ) {
String dependentTable = sp.getValue().getTable().getQuotedName(); String dependentTable = quotedTableName(sp.getValue().getTable());
if ( dependentTable.compareTo( startTable ) == 0 ) { if ( dependentTable.compareTo( startTable ) == 0 ) {
StringBuilder sb = new StringBuilder( StringBuilder sb = new StringBuilder(
"Foreign key circularity dependency involving the following tables: " "Foreign key circularity dependency involving the following tables: "
@ -1509,6 +1509,10 @@ public class Configuration implements Serializable {
} }
} }
private String quotedTableName(Table table) {
return Table.qualify( table.getCatalog(), table.getQuotedSchema(), table.getQuotedName() );
}
private void processEndOfQueue(List<FkSecondPass> endOfQueueFkSecondPasses) { private void processEndOfQueue(List<FkSecondPass> endOfQueueFkSecondPasses) {
/* /*
* If a second pass raises a recoverableException, queue it for next round * If a second pass raises a recoverableException, queue it for next round

View File

@ -0,0 +1,74 @@
package org.hibernate.test.cfg;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
/**
* This test illustrates the problem when two related (in terms of joins)
* classes have the same table name in different schemas.
*
* @author Didier Villevalois
*/
@TestForIssue(jiraKey = "HHH-7134")
public class WrongCircularityDetectionTest extends BaseUnitTestCase {
@Test
public void testNoCircularityDetection() {
Configuration cfg = new Configuration();
cfg.addAnnotatedClass(Entity1.class);
cfg.addAnnotatedClass(Entity2.class);
cfg.buildMappings();
org.hibernate.mapping.Table entity1Table = cfg.getClassMapping(
Entity1.class.getName()).getTable();
org.hibernate.mapping.Table entity2Table = cfg.getClassMapping(
Entity2.class.getName()).getTable();
assertTrue(entity1Table.getName().equals(entity2Table.getName()));
assertFalse(entity1Table.getSchema().equals(entity2Table.getSchema()));
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(schema = "schema1", name = "entity")
public static class Entity1 {
private String id;
@Id
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
@Entity
@Table(schema = "schema2", name = "entity")
public static class Entity2 extends Entity1 {
private String value;
@Basic
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}