HHH-8224 unique key, foreign key, and index naming strategies
This commit is contained in:
parent
afc7bdfebe
commit
ba59bbf119
|
@ -24,9 +24,12 @@
|
|||
package org.hibernate.cfg;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.internal.HashedNameUtil;
|
||||
|
||||
/**
|
||||
* The default <tt>NamingStrategy</tt>
|
||||
|
@ -93,6 +96,22 @@ public class DefaultNamingStrategy implements NamingStrategy, Serializable {
|
|||
if (header == null) throw new AssertionFailure("NammingStrategy not properly filled");
|
||||
return columnName( header ); //+ "_" + referencedColumnName not used for backward compatibility
|
||||
}
|
||||
|
||||
public String foreignKeyName(String sourceTableName, List<String> sourceColumnNames,
|
||||
String targetTableName, List<String> targetColumnNames) {
|
||||
List<String> combinedColumnNames = new ArrayList<String>();
|
||||
combinedColumnNames.addAll( sourceColumnNames );
|
||||
combinedColumnNames.addAll( targetColumnNames );
|
||||
return HashedNameUtil.generateName( "FK_", sourceTableName + "_" + targetTableName, combinedColumnNames );
|
||||
}
|
||||
|
||||
public String uniqueKeyName(String tableName, List<String> columnNames) {
|
||||
return HashedNameUtil.generateName( "UK_", tableName, columnNames );
|
||||
}
|
||||
|
||||
public String indexName(String tableName, List<String> columnNames) {
|
||||
return HashedNameUtil.generateName( "IDX_", tableName, columnNames );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column name or the unqualified property name
|
||||
|
|
|
@ -23,9 +23,12 @@
|
|||
*/
|
||||
package org.hibernate.cfg;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.internal.HashedNameUtil;
|
||||
|
||||
/**
|
||||
* Naming strategy implementing the EJB3 standards
|
||||
|
@ -76,6 +79,22 @@ public class EJB3NamingStrategy implements NamingStrategy, Serializable {
|
|||
if ( header == null ) throw new AssertionFailure( "NamingStrategy not properly filled" );
|
||||
return columnName( header + "_" + referencedColumnName );
|
||||
}
|
||||
|
||||
public String foreignKeyName(String sourceTableName, List<String> sourceColumnNames,
|
||||
String targetTableName, List<String> targetColumnNames) {
|
||||
List<String> combinedColumnNames = new ArrayList<String>();
|
||||
combinedColumnNames.addAll( sourceColumnNames );
|
||||
combinedColumnNames.addAll( targetColumnNames );
|
||||
return HashedNameUtil.generateName( "FK_", sourceTableName + "_" + targetTableName, combinedColumnNames );
|
||||
}
|
||||
|
||||
public String uniqueKeyName(String tableName, List<String> columnNames) {
|
||||
return HashedNameUtil.generateName( "UK_", tableName, columnNames );
|
||||
}
|
||||
|
||||
public String indexName(String tableName, List<String> columnNames) {
|
||||
return HashedNameUtil.generateName( "IDX_", tableName, columnNames );
|
||||
}
|
||||
|
||||
public String logicalColumnName(String columnName, String propertyName) {
|
||||
return StringHelper.isNotEmpty( columnName ) ? columnName : StringHelper.unqualify( propertyName );
|
||||
|
|
|
@ -24,9 +24,12 @@
|
|||
package org.hibernate.cfg;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.internal.HashedNameUtil;
|
||||
|
||||
/**
|
||||
* An improved naming strategy that prefers embedded
|
||||
|
@ -106,6 +109,22 @@ public class ImprovedNamingStrategy implements NamingStrategy, Serializable {
|
|||
if (header == null) throw new AssertionFailure("NamingStrategy not properly filled");
|
||||
return columnName( header ); //+ "_" + referencedColumnName not used for backward compatibility
|
||||
}
|
||||
|
||||
public String foreignKeyName(String sourceTableName, List<String> sourceColumnNames,
|
||||
String targetTableName, List<String> targetColumnNames) {
|
||||
List<String> combinedColumnNames = new ArrayList<String>();
|
||||
combinedColumnNames.addAll( sourceColumnNames );
|
||||
combinedColumnNames.addAll( targetColumnNames );
|
||||
return HashedNameUtil.generateName( "FK_", sourceTableName + "_" + targetTableName, combinedColumnNames );
|
||||
}
|
||||
|
||||
public String uniqueKeyName(String tableName, List<String> columnNames) {
|
||||
return HashedNameUtil.generateName( "UK_", tableName, columnNames );
|
||||
}
|
||||
|
||||
public String indexName(String tableName, List<String> columnNames) {
|
||||
return HashedNameUtil.generateName( "IDX_", tableName, columnNames );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the column name or the unqualified property name
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.cfg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* A set of rules for determining the physical column
|
||||
|
@ -37,6 +39,7 @@ package org.hibernate.cfg;
|
|||
* @see ImprovedNamingStrategy
|
||||
* @author Gavin King
|
||||
* @author Emmanuel Bernard
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public interface NamingStrategy {
|
||||
/**
|
||||
|
@ -93,6 +96,33 @@ public interface NamingStrategy {
|
|||
public String foreignKeyColumnName(
|
||||
String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName
|
||||
);
|
||||
/**
|
||||
* Return a constraint name for foreign keys that are not explicitly named in the mappings/annotations.
|
||||
*
|
||||
* @param tableName The foreign key's source table
|
||||
* @param columnNames The source columns within the foreign key
|
||||
* @param tableName The foreign key's target table
|
||||
* @param columnNames The target columns within the foreign key
|
||||
* @return The generated foreign key constraint name
|
||||
*/
|
||||
public String foreignKeyName(String sourceTableName, List<String> sourceColumnNames,
|
||||
String targetTableName, List<String> targetColumnNames);
|
||||
/**
|
||||
* Return a constraint name for unique keys that are not explicitly named in the mappings/annotations.
|
||||
*
|
||||
* @param tableName The unique key's table
|
||||
* @param columnNames The columns within the unique key
|
||||
* @return The generated unique key constraint name
|
||||
*/
|
||||
public String uniqueKeyName(String tableName, List<String> columnNames);
|
||||
/**
|
||||
* Return a constraint name for indexes that are not explicitly named in the mappings/annotations.
|
||||
*
|
||||
* @param tableName The index's table
|
||||
* @param columnNames The columns within the index
|
||||
* @return The generated index constraint name
|
||||
*/
|
||||
public String indexName(String tableName, List<String> columnNames);
|
||||
/**
|
||||
* Return the logical column name used to refer to a column in the metadata
|
||||
* (like index, unique constraints etc)
|
||||
|
|
|
@ -207,4 +207,10 @@ public final class CollectionHelper {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> List<T> singleEntryList(T entry) {
|
||||
final List<T> list = new ArrayList<T>();
|
||||
list.add( entry );
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,11 +112,9 @@ import org.hibernate.metamodel.spi.domain.SingularAttribute;
|
|||
import org.hibernate.metamodel.spi.relational.Column;
|
||||
import org.hibernate.metamodel.spi.relational.ForeignKey;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.Index;
|
||||
import org.hibernate.metamodel.spi.relational.PrimaryKey;
|
||||
import org.hibernate.metamodel.spi.relational.Table;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
import org.hibernate.metamodel.spi.relational.UniqueKey;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.AggregatedCompositeIdentifierSource;
|
||||
import org.hibernate.metamodel.spi.source.AttributeSource;
|
||||
|
@ -222,7 +220,7 @@ public class Binder implements HelperContext {
|
|||
this.tableHelper = new TableHelper( this );
|
||||
this.foreignKeyHelper = new ForeignKeyHelper( this );
|
||||
this.relationalValueBindingHelper = new RelationalValueBindingHelper( this );
|
||||
this.naturalIdUniqueKeyHelper = new NaturalIdUniqueKeyHelper();
|
||||
this.naturalIdUniqueKeyHelper = new NaturalIdUniqueKeyHelper( this );
|
||||
this.standardAssociationRelationalBindingResolver =
|
||||
new StandardAssociationRelationalBindingResolverImpl( this );
|
||||
this.mappedByAssociationRelationalBindingResolver =
|
||||
|
@ -1127,49 +1125,28 @@ public class Binder implements HelperContext {
|
|||
final EntitySource entitySource = bindingContextContext.getEntitySource();
|
||||
for ( final ConstraintSource constraintSource : entitySource.getConstraints() ) {
|
||||
if ( UniqueConstraintSource.class.isInstance( constraintSource ) ) {
|
||||
UniqueConstraintSource uniqueConstraintSource = (UniqueConstraintSource) constraintSource;
|
||||
final UniqueConstraintSource uniqueConstraintSource = (UniqueConstraintSource) constraintSource;
|
||||
|
||||
UniqueKey uk = new UniqueKey();
|
||||
final TableSpecification table = findConstraintTable( entityBinding, constraintSource.getTableName() );
|
||||
|
||||
TableSpecification table = findConstraintTable( entityBinding, constraintSource.getTableName() );
|
||||
|
||||
final List<String> columnNames = uniqueConstraintSource.columnNames();
|
||||
final String constraintName = StringHelper.isEmpty( constraintSource.name() )
|
||||
? HashedNameUtil.generateName( "UK_", table, columnNames.toArray( new String[columnNames.size()] ) )
|
||||
: constraintSource.name();
|
||||
for ( final String columnName : columnNames ) {
|
||||
uk.addColumn(
|
||||
tableHelper.locateOrCreateColumn(
|
||||
table,
|
||||
columnName,
|
||||
new ColumnNamingStrategyHelper( null, false )
|
||||
|
||||
)
|
||||
);
|
||||
final List<Column> columns = new ArrayList<Column>();
|
||||
for ( final String columnName : uniqueConstraintSource.columnNames() ) {
|
||||
columns.add( tableHelper.locateOrCreateColumn( table, columnName,
|
||||
new ColumnNamingStrategyHelper( null, false ) ) );
|
||||
}
|
||||
uk.setTable( table );
|
||||
uk.setName( constraintName );
|
||||
table.addUniqueKey( uk );
|
||||
tableHelper.createUniqueKey( table, columns, constraintSource.name() );
|
||||
}
|
||||
else if ( IndexConstraintSource.class.isInstance( constraintSource ) ) {
|
||||
IndexConstraintSource indexConstraintSource = (IndexConstraintSource) constraintSource;
|
||||
final IndexConstraintSource indexConstraintSource = (IndexConstraintSource) constraintSource;
|
||||
|
||||
TableSpecification table = findConstraintTable( entityBinding, constraintSource.getTableName() );
|
||||
final TableSpecification table = findConstraintTable( entityBinding, constraintSource.getTableName() );
|
||||
|
||||
final List<String> columnNames = indexConstraintSource.columnNames();
|
||||
final List<String> orderings = indexConstraintSource.orderings();
|
||||
final String constraintName = StringHelper.isEmpty( constraintSource.name() )
|
||||
? HashedNameUtil.generateName( "IDX_", table, columnNames.toArray( new String[columnNames.size()] ) )
|
||||
: constraintSource.name();
|
||||
final Index index = table.getOrCreateIndex( constraintName );
|
||||
for ( int i = 0; i < columnNames.size(); i++ ) {
|
||||
Column column = tableHelper.locateOrCreateColumn(
|
||||
table,
|
||||
columnNames.get( i ),
|
||||
new DefaultColumnNamingStrategyHelper( null )
|
||||
);
|
||||
index.addColumn( column, orderings.get( i ) );
|
||||
final List<Column> columns = new ArrayList<Column>();
|
||||
for ( final String columnName : indexConstraintSource.columnNames() ) {
|
||||
columns.add( tableHelper.locateOrCreateColumn( table, columnName,
|
||||
new ColumnNamingStrategyHelper( null, false ) ) );
|
||||
}
|
||||
tableHelper.createIndex( table, columns, constraintSource.name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2477,15 +2454,13 @@ public class Binder implements HelperContext {
|
|||
foreignKey = null;
|
||||
}
|
||||
if ( elementSource.isUnique() ) {
|
||||
UniqueKey uk = new UniqueKey();
|
||||
final List<Column> columns = new ArrayList<Column>();
|
||||
for ( RelationalValueBinding relationalValueBinding : relationalValueBindings ) {
|
||||
if ( ! relationalValueBinding.isDerived() ) {
|
||||
uk.addColumn( (Column) relationalValueBinding.getValue() );
|
||||
columns.add( (Column) relationalValueBinding.getValue() );
|
||||
}
|
||||
}
|
||||
uk.setTable( collectionTable );
|
||||
HashedNameUtil.setName("UK_", uk);
|
||||
collectionTable.addUniqueKey( uk );
|
||||
tableHelper.createUniqueKey( collectionTable, columns, null );
|
||||
}
|
||||
elementBinding.setJoinRelationalValueBindings( relationalValueBindings, foreignKey );
|
||||
typeHelper.bindManyToManyAttributeType(
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* 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, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY 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
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.metamodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.cfg.NamingStrategy;
|
||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||
import org.hibernate.metamodel.spi.relational.Column;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
|
||||
/**
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public abstract class ConstraintNamingStrategyHelper implements ObjectNameNormalizer.NamingStrategyHelper {
|
||||
|
||||
protected final TableSpecification table;
|
||||
|
||||
protected final List<Column> columns;
|
||||
|
||||
public ConstraintNamingStrategyHelper(TableSpecification table, List<Column> columns) {
|
||||
this.table = table;
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String determineImplicitName(NamingStrategy strategy) {
|
||||
return doDetermineImplicitName( strategy, table.getLogicalName().getText(), getColumnNames( columns ) );
|
||||
}
|
||||
|
||||
protected abstract String doDetermineImplicitName(NamingStrategy strategy, String tableName, List<String> columnNames);
|
||||
|
||||
@Override
|
||||
public String handleExplicitName(NamingStrategy strategy, String name) {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static class UniqueKeyNamingStrategyHelper extends ConstraintNamingStrategyHelper {
|
||||
public UniqueKeyNamingStrategyHelper(TableSpecification table, List<Column> columns) {
|
||||
super( table, columns );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doDetermineImplicitName(NamingStrategy strategy, String tableName, List<String> columnNames) {
|
||||
return strategy.uniqueKeyName( tableName, columnNames );
|
||||
}
|
||||
}
|
||||
|
||||
public static class ForeignKeyNamingStrategyHelper extends ConstraintNamingStrategyHelper {
|
||||
// named using a combo of source/target table/columns
|
||||
private final String targetTableName;
|
||||
private final List<String> targetColumnNames;
|
||||
|
||||
public ForeignKeyNamingStrategyHelper(TableSpecification sourceTable, List<Column> sourceColumns,
|
||||
TableSpecification targetTable, List<Column> targetColumns) {
|
||||
super( sourceTable, sourceColumns );
|
||||
targetTableName = targetTable.getLogicalName().getText();
|
||||
targetColumnNames = getColumnNames( targetColumns );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doDetermineImplicitName(NamingStrategy strategy, String tableName, List<String> columnNames) {
|
||||
// combine source and target (if available) to ensure uniqueness
|
||||
return strategy.foreignKeyName( tableName, columnNames, targetTableName, targetColumnNames );
|
||||
}
|
||||
}
|
||||
|
||||
public static class IndexNamingStrategyHelper extends ConstraintNamingStrategyHelper {
|
||||
public IndexNamingStrategyHelper(TableSpecification table, List<Column> columns) {
|
||||
super( table, columns );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doDetermineImplicitName(NamingStrategy strategy, String tableName, List<String> columnNames) {
|
||||
return strategy.indexName( tableName, columnNames );
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> getColumnNames(List<Column> columns) {
|
||||
final List<String> columnNames = new ArrayList<String>();
|
||||
for ( final Column column : columns ) {
|
||||
columnNames.add( column.getColumnName().getText() );
|
||||
}
|
||||
return columnNames;
|
||||
}
|
||||
}
|
|
@ -27,9 +27,9 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.annotations.common.util.StringHelper;
|
||||
import org.hibernate.cfg.NotYetImplementedException;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.metamodel.internal.ConstraintNamingStrategyHelper.ForeignKeyNamingStrategyHelper;
|
||||
import org.hibernate.metamodel.spi.binding.AttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.EntityBinding;
|
||||
import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
|
||||
|
@ -42,7 +42,6 @@ import org.hibernate.metamodel.spi.relational.TableSpecification;
|
|||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource;
|
||||
import org.hibernate.metamodel.spi.source.LocalBindingContext;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
|
@ -160,35 +159,11 @@ public class ForeignKeyHelper {
|
|||
final List<Column> sourceColumns,
|
||||
final TableSpecification targetTable,
|
||||
final List<Column> targetColumns) {
|
||||
final String foreignKeyName;
|
||||
if ( StringHelper.isEmpty( explicitForeignKeyName ) ) {
|
||||
foreignKeyName = ForeignKey.generateName( sourceTable, targetTable, sourceColumns, targetColumns );
|
||||
}
|
||||
else {
|
||||
foreignKeyName = helperContext.relationalIdentifierHelper().quotedIdentifier( explicitForeignKeyName );
|
||||
}
|
||||
final String foreignKeyName = helperContext.relationalIdentifierHelper().normalizeDatabaseIdentifier(
|
||||
explicitForeignKeyName, new ForeignKeyNamingStrategyHelper(
|
||||
sourceTable, sourceColumns, targetTable, targetColumns ) );
|
||||
|
||||
ForeignKey foreignKey = locateAndBindForeignKeyByName( foreignKeyName, sourceTable, sourceColumns, targetTable, targetColumns );
|
||||
if ( foreignKey == null ) {
|
||||
foreignKey = locateForeignKeyByColumnMapping( sourceTable, sourceColumns, targetTable, targetColumns );
|
||||
if ( foreignKey != null ) {
|
||||
if ( foreignKey.getName() == null ) {
|
||||
// the foreign key name has not be initialized; set it to foreignKeyName
|
||||
foreignKey.setName( foreignKeyName );
|
||||
}
|
||||
else {
|
||||
// the foreign key name has already been initialized so cannot rename it
|
||||
// TODO: should this just be INFO?
|
||||
log.warn(
|
||||
String.format(
|
||||
"A foreign key mapped as %s will not be created because foreign key %s already exists with the same column mapping.",
|
||||
foreignKeyName,
|
||||
foreignKey.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( foreignKey == null ) {
|
||||
// no foreign key found; create one
|
||||
foreignKey = sourceTable.createForeignKey( targetTable, foreignKeyName );
|
||||
|
@ -197,27 +172,6 @@ public class ForeignKeyHelper {
|
|||
return foreignKey;
|
||||
}
|
||||
|
||||
private static ForeignKey locateForeignKeyByColumnMapping(
|
||||
final TableSpecification sourceTable,
|
||||
final List<Column> sourceColumns,
|
||||
final TableSpecification targetTable,
|
||||
final List<Column> targetColumns) {
|
||||
// check for an existing foreign key with the same source/target columns
|
||||
ForeignKey foreignKey = null;
|
||||
Iterable<ForeignKey> possibleForeignKeys = sourceTable.locateForeignKey( targetTable );
|
||||
if ( possibleForeignKeys != null ) {
|
||||
for ( ForeignKey possibleFK : possibleForeignKeys ) {
|
||||
if ( possibleFK.getSourceColumns().equals( sourceColumns ) &&
|
||||
possibleFK.getTargetColumns().equals( targetColumns ) ) {
|
||||
// this is the foreign key
|
||||
foreignKey = possibleFK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return foreignKey;
|
||||
}
|
||||
|
||||
private void bindForeignKeyColumns(
|
||||
final ForeignKey foreignKey,
|
||||
final TableSpecification sourceTable,
|
||||
|
|
|
@ -27,8 +27,6 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.metamodel.spi.relational.AbstractConstraint;
|
||||
import org.hibernate.metamodel.spi.relational.Column;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
|
||||
/**
|
||||
|
@ -47,11 +45,11 @@ public class HashedNameUtil {
|
|||
* @param columnNames
|
||||
* @return String The generated name
|
||||
*/
|
||||
public static String generateName(String prefix, TableSpecification table, String... columnNames ) {
|
||||
public static String generateName(String prefix, String tableName, String... columnNames ) {
|
||||
// Use a concatenation that guarantees uniqueness, even if identical names
|
||||
// exist between all table and column identifiers.
|
||||
|
||||
StringBuilder sb = new StringBuilder( "table`" + table.getLogicalName().getText() + "`" );
|
||||
StringBuilder sb = new StringBuilder( "table`" + tableName + "`" );
|
||||
|
||||
// Ensure a consistent ordering of columns, regardless of the order
|
||||
// they were bound.
|
||||
|
@ -73,20 +71,12 @@ public class HashedNameUtil {
|
|||
* @param columns
|
||||
* @return String The generated name
|
||||
*/
|
||||
public static String generateName(String prefix, TableSpecification table, List<Column> columns) {
|
||||
String[] columnNames = new String[columns.size()];
|
||||
for ( int i = 0; i < columns.size(); i++ ) {
|
||||
columnNames[i] = columns.get( i ).getColumnName().getText();
|
||||
public static String generateName(String prefix, String tableName, List<String> columnNames) {
|
||||
String[] columnNamesArray = new String[columnNames.size()];
|
||||
for ( int i = 0; i < columnNames.size(); i++ ) {
|
||||
columnNamesArray[i] = columnNames.get( i );
|
||||
}
|
||||
return generateName( prefix, table, columnNames );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for {@link #generateName(String, TableSpecification, String...)}.
|
||||
* Generates and sets a name for an existing constraint.
|
||||
*/
|
||||
public static void setName(String prefix, AbstractConstraint constraint) {
|
||||
constraint.setName( generateName( prefix, constraint.getTable(), constraint.getColumns() ) );
|
||||
return generateName( prefix, tableName, columnNamesArray );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,9 +31,15 @@ import org.hibernate.metamodel.spi.relational.UniqueKey;
|
|||
* @author Brett Meyer
|
||||
*/
|
||||
public class NaturalIdUniqueKeyHelper {
|
||||
|
||||
private final HelperContext helperContext;
|
||||
|
||||
private Map<TableSpecification, UniqueKey> naturalIdUniqueKeys
|
||||
= new HashMap<TableSpecification, UniqueKey>();
|
||||
|
||||
public NaturalIdUniqueKeyHelper(HelperContext helperContext) {
|
||||
this.helperContext = helperContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Natural ID columns must reside in one single UniqueKey within the Table.
|
||||
|
@ -50,6 +56,7 @@ public class NaturalIdUniqueKeyHelper {
|
|||
uniqueKey = naturalIdUniqueKeys.get( table );
|
||||
}
|
||||
else {
|
||||
// TODO: For now, leave this out of the naming strategy. It has nothing to do with the columns.
|
||||
String keyName = "UK_" + HashedNameUtil.hashedName( table.getLogicalName().getText() + "_NaturalID" );
|
||||
uniqueKey = new UniqueKey();
|
||||
uniqueKey.setTable( table );
|
||||
|
|
|
@ -23,13 +23,17 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.internal;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.TruthValue;
|
||||
import org.hibernate.cfg.ObjectNameNormalizer;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.internal.ConstraintNamingStrategyHelper.IndexNamingStrategyHelper;
|
||||
import org.hibernate.metamodel.internal.ConstraintNamingStrategyHelper.UniqueKeyNamingStrategyHelper;
|
||||
import org.hibernate.metamodel.spi.relational.Column;
|
||||
import org.hibernate.metamodel.spi.relational.Identifier;
|
||||
import org.hibernate.metamodel.spi.relational.Index;
|
||||
import org.hibernate.metamodel.spi.relational.Schema;
|
||||
import org.hibernate.metamodel.spi.relational.Table;
|
||||
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||
|
@ -41,6 +45,7 @@ import org.hibernate.metamodel.spi.source.MappingDefaults;
|
|||
import org.hibernate.metamodel.spi.source.SizeSource;
|
||||
import org.hibernate.metamodel.spi.source.TableSource;
|
||||
import org.hibernate.metamodel.spi.source.TableSpecificationSource;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
|
@ -173,14 +178,42 @@ public class TableHelper {
|
|||
column.setComment( columnSource.getComment() );
|
||||
|
||||
if (columnSource.isUnique()) {
|
||||
UniqueKey uk = new UniqueKey();
|
||||
uk.addColumn( column );
|
||||
uk.setTable( table );
|
||||
HashedNameUtil.setName("UK_", uk);
|
||||
table.addUniqueKey( uk );
|
||||
createUniqueKey( table, CollectionHelper.singleEntryList( column ), null );
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
public void createUniqueKey(
|
||||
final TableSpecification table,
|
||||
final List<Column> columns,
|
||||
final String name) {
|
||||
final UniqueKey uk = new UniqueKey();
|
||||
for ( final Column column : columns ) {
|
||||
uk.addColumn( column );
|
||||
}
|
||||
uk.setTable( table );
|
||||
|
||||
final String normalizedName = normalizeDatabaseIdentifier( name, new UniqueKeyNamingStrategyHelper( table, columns ) );
|
||||
|
||||
uk.setName( normalizedName );
|
||||
table.addUniqueKey( uk );
|
||||
}
|
||||
|
||||
public void createIndex(
|
||||
final TableSpecification table,
|
||||
final List<Column> columns,
|
||||
final String name) {
|
||||
final Index idx = new Index();
|
||||
for ( final Column column : columns ) {
|
||||
idx.addColumn( column );
|
||||
}
|
||||
idx.setTable( table );
|
||||
|
||||
final String normalizedName = normalizeDatabaseIdentifier( name, new IndexNamingStrategyHelper( table, columns ) );
|
||||
|
||||
idx.setName( normalizedName );
|
||||
table.addIndex( idx );
|
||||
}
|
||||
|
||||
private void resolveColumnNullable(
|
||||
final TableSpecification table,
|
||||
|
|
|
@ -25,10 +25,6 @@ package org.hibernate.metamodel.internal.source.annotations.global;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
|
@ -40,12 +36,11 @@ import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotName
|
|||
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.spi.MetadataImplementor;
|
||||
import org.hibernate.metamodel.spi.binding.SecondaryTable;
|
||||
import org.hibernate.metamodel.spi.relational.Column;
|
||||
import org.hibernate.metamodel.spi.relational.Index;
|
||||
import org.hibernate.metamodel.spi.relational.ObjectName;
|
||||
import org.hibernate.metamodel.spi.relational.Schema;
|
||||
import org.hibernate.metamodel.spi.relational.Table;
|
||||
import org.hibernate.metamodel.spi.relational.Value;
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Binds table related information. This binder is called after the entities are bound.
|
||||
|
@ -101,13 +96,6 @@ public class TableProcessor {
|
|||
final AnnotationInstance tableAnnotation,
|
||||
final boolean isSecondaryTable,
|
||||
final MetadataImplementor metadata) {
|
||||
for ( AnnotationInstance indexAnnotation : JandexHelper.getValue(
|
||||
tableAnnotation,
|
||||
"indexes",
|
||||
AnnotationInstance[].class
|
||||
) ) {
|
||||
bindIndexAnnotation( table, tableAnnotation, indexAnnotation );
|
||||
}
|
||||
String comment = JandexHelper.getValue( tableAnnotation, "comment", String.class );
|
||||
if ( StringHelper.isNotEmpty( comment ) ) {
|
||||
table.addComment( comment.trim() );
|
||||
|
@ -164,35 +152,4 @@ public class TableProcessor {
|
|||
|
||||
|
||||
}
|
||||
|
||||
private static void bindIndexAnnotation(Table table, AnnotationInstance tableAnnotation, AnnotationInstance indexAnnotation) {
|
||||
String indexName = JandexHelper.getValue( indexAnnotation, "name", String.class );
|
||||
String[] columnNames = JandexHelper.getValue( indexAnnotation, "columnNames", String[].class );
|
||||
if ( columnNames == null ) {
|
||||
LOG.noColumnsSpecifiedForIndex( indexName, table.toLoggableString() );
|
||||
return;
|
||||
}
|
||||
Index index = table.getOrCreateIndex( indexName );
|
||||
for ( String columnName : columnNames ) {
|
||||
Column column = findColumn( table, columnName );
|
||||
if ( column == null ) {
|
||||
throw new AnnotationException( "@Index references a unknown column: " + columnName );
|
||||
}
|
||||
index.addColumn( column );
|
||||
}
|
||||
}
|
||||
|
||||
private static Column findColumn(Table table, String columnName) {
|
||||
Column column = null;
|
||||
for ( Value value : table.values() ) {
|
||||
if ( Column.class.isInstance( value ) && Column.class.cast( value )
|
||||
.getColumnName()
|
||||
.getText()
|
||||
.equals( columnName ) ) {
|
||||
column = (Column) value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return column;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,16 +24,13 @@
|
|||
package org.hibernate.metamodel.spi.relational;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.metamodel.internal.HashedNameUtil;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
|
@ -260,51 +257,6 @@ public class ForeignKey extends AbstractConstraint {
|
|||
return columnMappingList;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a constraint is not explicitly named, this is called to generate
|
||||
* a unique hash using the source/target table and column names.
|
||||
* Static so the name can be generated prior to creating the Constraint.
|
||||
* They're cached, keyed by name, in multiple locations.
|
||||
*
|
||||
* @param sourceTable
|
||||
* @param targetTable
|
||||
* @param sourceColumns
|
||||
* @param targetColumns
|
||||
* @return String The generated name
|
||||
*/
|
||||
public static String generateName(TableSpecification sourceTable, TableSpecification targetTable,
|
||||
List<Column> sourceColumns, List<Column> targetColumns) {
|
||||
// Use a concatenation that guarantees uniqueness, even if identical names
|
||||
// exist between all table and column identifiers.
|
||||
|
||||
StringBuilder sb = new StringBuilder( "table`" + sourceTable.getLogicalName().getText() + "`" );
|
||||
sb.append( "table`" + targetTable.getLogicalName().getText() + "`" );
|
||||
appendColumns( sourceColumns, sb );
|
||||
appendColumns( targetColumns, sb );
|
||||
|
||||
return "FK_" + HashedNameUtil.hashedName( sb.toString() );
|
||||
}
|
||||
|
||||
private static void appendColumns(List<Column> columns, StringBuilder sb) {
|
||||
// Ensure a consistent ordering of columns, regardless of the order
|
||||
// they were bound.
|
||||
// Clone the list, as sometimes a set of order-dependent Column
|
||||
// bindings are given.
|
||||
Column[] alphabeticalColumns = columns.toArray( new Column[columns.size()] );
|
||||
Arrays.sort( alphabeticalColumns, ColumnComparator.INSTANCE );
|
||||
for ( Column column : alphabeticalColumns ) {
|
||||
sb.append( "column`" + column.getColumnName().getText() + "`" );
|
||||
}
|
||||
}
|
||||
|
||||
private static class ColumnComparator implements Comparator<Column> {
|
||||
public static ColumnComparator INSTANCE = new ColumnComparator();
|
||||
|
||||
public int compare(Column col1, Column col2) {
|
||||
return col1.getColumnName().toString().compareTo( col2.getColumnName().toString() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExportIdentifier() {
|
||||
return getSourceTable().getLoggableValueQualifier() + ".FK-" + getName();
|
||||
|
|
|
@ -69,7 +69,7 @@ public class InLineView extends AbstractTableSpecification {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Index getOrCreateIndex(String name) {
|
||||
public void addIndex(Index index) {
|
||||
throw new UnsupportedOperationException( "Cannot create index on inline view" );
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,10 @@ import org.hibernate.dialect.Dialect;
|
|||
*/
|
||||
public class Index extends AbstractConstraint {
|
||||
|
||||
public Index() {
|
||||
this( null, null );
|
||||
}
|
||||
|
||||
protected Index(Table table, String name) {
|
||||
super( table, name );
|
||||
}
|
||||
|
|
|
@ -147,16 +147,8 @@ public class Table extends AbstractTableSpecification implements Exportable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Index getOrCreateIndex(String name) {
|
||||
Index result = null;
|
||||
if ( name != null ) {
|
||||
result = locateConstraint( indexes, name );
|
||||
}
|
||||
if ( result == null ) {
|
||||
result = new Index( this, name );
|
||||
indexes.add( result );
|
||||
}
|
||||
return result;
|
||||
public void addIndex(Index idx) {
|
||||
indexes.add( idx );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -136,7 +136,7 @@ public interface TableSpecification extends ValueContainer, Loggable {
|
|||
|
||||
public Iterable<Index> getIndexes();
|
||||
|
||||
public Index getOrCreateIndex(String name);
|
||||
public void addIndex(Index idx);
|
||||
|
||||
public Iterable<UniqueKey> getUniqueKeys();
|
||||
|
||||
|
|
Loading…
Reference in New Issue