diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java index f8391e1455..2a4dadc46b 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -1618,15 +1618,19 @@ public class Configuration implements Serializable { ( (SimpleValue) prop.getValue() ).setAlternateUniqueKey( true ); } } - + //TODO: Somehow add the newly created foreign keys to the internal collection + LOG.debug( "Creating tables' unique integer identifiers" ); LOG.debug( "Processing foreign key constraints" ); itr = getTableMappings(); + int uniqueInteger = 0; Set done = new HashSet(); while ( itr.hasNext() ) { - secondPassCompileForeignKeys( (Table) itr.next(), done ); + Table table = (Table) itr.next(); + table.setUniqueInteger( uniqueInteger++ ); + secondPassCompileForeignKeys( table, done ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java index cff2564774..c30ca994c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java @@ -57,11 +57,10 @@ public class Table implements RelationalModel, Serializable { private Map indexes = new LinkedHashMap(); private Map foreignKeys = new LinkedHashMap(); private Map uniqueKeys = new LinkedHashMap(); - private final int uniqueInteger; + private int uniqueInteger; private boolean quoted; private boolean schemaQuoted; private boolean catalogQuoted; - private static int tableCounter = 0; private List checkConstraints = new ArrayList(); private String rowId; private String subselect; @@ -99,9 +98,7 @@ public class Table implements RelationalModel, Serializable { } } - public Table() { - uniqueInteger = tableCounter++; - } + public Table() { } public Table(String name) { this(); @@ -736,6 +733,12 @@ public class Table implements RelationalModel, Serializable { } } + // This must be done outside of Table, rather than statically, to ensure + // deterministic alias names. See HHH-2448. + public void setUniqueInteger( int uniqueInteger ) { + this.uniqueInteger = uniqueInteger; + } + public int getUniqueInteger() { return uniqueInteger; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/mapping/AliasTest.java b/hibernate-core/src/test/java/org/hibernate/test/mapping/AliasTest.java new file mode 100644 index 0000000000..66ffeee483 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/mapping/AliasTest.java @@ -0,0 +1,68 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * JBoss, Home of Professional Open Source + * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.hibernate.test.mapping; + +import static org.junit.Assert.assertTrue; + +import java.util.Iterator; + +import org.hibernate.mapping.Table; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +/** + * Column aliases utilize {@link Table#getUniqueInteger()} for naming. The + * unique integer used to be statically generated by the Table class, meaning + * it was dependent on mapping order. HHH-2448 made the alias names + * deterministic by having Configuration determine the unique integers on its + * second pass over the Tables tree map. AliasTest and + * {@link MappingReorderedAliasTest} ensure that the unique integers are the + * same, regardless of mapping ordering. + * + * @author Brett Meyer + */ +@TestForIssue( jiraKey = "HHH-2448" ) +public class AliasTest extends BaseCoreFunctionalTestCase { + + @Test + public void testAliasOrdering() { + Iterator tables = configuration().getTableMappings(); + Table table1 = null; + Table table2 = null; + while ( tables.hasNext() ) { + Table table = tables.next(); + if ( table.getName().equals( "Table1" ) ) { + table1 = table; + } + else if ( table.getName().equals( "Table2" ) ) { + table2 = table; + } + } + + assertTrue( table1.getUniqueInteger() < table2.getUniqueInteger() ); + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Table1.class, Table2.class }; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/mapping/MappingReorderedAliasTest.java b/hibernate-core/src/test/java/org/hibernate/test/mapping/MappingReorderedAliasTest.java new file mode 100644 index 0000000000..6b3dbffb19 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/mapping/MappingReorderedAliasTest.java @@ -0,0 +1,32 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * JBoss, Home of Professional Open Source + * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.hibernate.test.mapping; + +/** + * @author Brett Meyer + */ +public class MappingReorderedAliasTest extends AliasTest { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Table2.class, Table1.class }; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/mapping/Table1.java b/hibernate-core/src/test/java/org/hibernate/test/mapping/Table1.java new file mode 100644 index 0000000000..928bf85d8d --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/mapping/Table1.java @@ -0,0 +1,46 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * JBoss, Home of Professional Open Source + * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.hibernate.test.mapping; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author Brett Meyer + */ +@Entity +@Table( name = "Table1" ) +public class Table1 { + + @Id + @GeneratedValue + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/mapping/Table2.java b/hibernate-core/src/test/java/org/hibernate/test/mapping/Table2.java new file mode 100644 index 0000000000..1db3959cc5 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/mapping/Table2.java @@ -0,0 +1,46 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * JBoss, Home of Professional Open Source + * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.hibernate.test.mapping; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author Brett Meyer + */ +@Entity +@Table( name = "Table2" ) +public class Table2 { + + @Id + @GeneratedValue + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } +}