HHH-16985 use ImplicitNamingStrategy in a much more disciplined way

for generating constraint names
This commit is contained in:
Gavin King 2024-03-11 11:22:33 +01:00
parent 9c12ea8b11
commit da9d2c2bf7
31 changed files with 455 additions and 293 deletions

View File

@ -0,0 +1,81 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.boot.internal;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitForeignKeyNameSource;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.Table;
import java.util.List;
import static java.util.Collections.emptyList;
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
public class ForeignKeyNameSource implements ImplicitForeignKeyNameSource {
final List<Identifier> columnNames;
private final ForeignKey foreignKey;
private final Table table;
private final MetadataBuildingContext buildingContext;
List<Identifier> referencedColumnNames;
public ForeignKeyNameSource(ForeignKey foreignKey, Table table, MetadataBuildingContext buildingContext) {
this.foreignKey = foreignKey;
this.table = table;
this.buildingContext = buildingContext;
columnNames = extractColumnNames(foreignKey.getColumns());
referencedColumnNames = null;
}
@Override
public Identifier getTableName() {
return table.getNameIdentifier();
}
@Override
public List<Identifier> getColumnNames() {
return columnNames;
}
@Override
public Identifier getReferencedTableName() {
return foreignKey.getReferencedTable().getNameIdentifier();
}
@Override
public List<Identifier> getReferencedColumnNames() {
if ( referencedColumnNames == null ) {
referencedColumnNames = extractColumnNames( foreignKey.getReferencedColumns() );
}
return referencedColumnNames;
}
@Override
public Identifier getUserProvidedIdentifier() {
return foreignKey.getName() != null ? Identifier.toIdentifier(foreignKey.getName()) : null;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return buildingContext;
}
private List<Identifier> extractColumnNames(List<Column> columns) {
if ( columns == null || columns.isEmpty() ) {
return emptyList();
}
final List<Identifier> columnNames = arrayList( columns.size() );
for ( Column column : columns ) {
columnNames.add( column.getNameIdentifier( buildingContext ) );
}
return columnNames;
}
}

View File

@ -53,7 +53,6 @@ import org.hibernate.boot.model.internal.SecondaryTableFromAnnotationSecondPass;
import org.hibernate.boot.model.internal.SecondaryTableSecondPass;
import org.hibernate.boot.model.internal.SetBasicValueTypeSecondPass;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitForeignKeyNameSource;
import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.ExportableProducer;
@ -111,9 +110,6 @@ import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity;
import jakarta.persistence.MapsId;
import static java.util.Collections.emptyList;
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
/**
* The implementation of the {@linkplain InFlightMetadataCollector in-flight
* metadata collector contract}.
@ -1935,26 +1931,16 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
protected void secondPassCompileForeignKeys(Table table, Set<ForeignKey> done, MetadataBuildingContext buildingContext)
throws MappingException {
table.createForeignKeys();
table.createForeignKeys( buildingContext );
final Dialect dialect = getDatabase().getJdbcEnvironment().getDialect();
for ( ForeignKey foreignKey : table.getForeignKeys().values() ) {
if ( !done.contains( foreignKey ) ) {
done.add( foreignKey );
final String referencedEntityName = foreignKey.getReferencedEntityName();
if ( referencedEntityName == null ) {
throw new MappingException( "An association from the table '" + foreignKey.getTable().getName() +
"' does not specify the referenced entity" );
}
final PersistentClass referencedClass = foreignKey.resolveReferencedClass(this);
log.debugf( "Resolving reference to class: %s", referencedEntityName );
final PersistentClass referencedClass = getEntityBinding( referencedEntityName );
if ( referencedClass == null ) {
throw new MappingException( "An association from the table '" + foreignKey.getTable().getName() +
"' refers to an unmapped class '" + referencedEntityName + "'" );
}
if ( referencedClass.isJoinedSubclass() ) {
secondPassCompileForeignKeys( referencedClass.getSuperclass().getTable(), done, buildingContext );
secondPassCompileForeignKeys( referencedClass.getSuperclass().getTable(), done, buildingContext);
}
// the ForeignKeys created in the first pass did not have their referenced table initialized
@ -1971,19 +1957,6 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
}
}
private List<Identifier> extractColumnNames(List<Column> columns) {
if ( columns == null || columns.isEmpty() ) {
return emptyList();
}
final List<Identifier> columnNames = arrayList( columns.size() );
for ( Column column : columns ) {
columnNames.add( getDatabase().toIdentifier( column.getQuotedName() ) );
}
return columnNames;
}
private void processPropertyReferences() {
if ( delayedPropertyReferenceHandlers == null ) {
return;
@ -2173,53 +2146,4 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
log.debugf( "Ignoring exception thrown when trying to build IdentifierGenerator as part of Metadata building", e );
}
}
private class ForeignKeyNameSource implements ImplicitForeignKeyNameSource {
final List<Identifier> columnNames;
private final ForeignKey foreignKey;
private final Table table;
private final MetadataBuildingContext buildingContext;
List<Identifier> referencedColumnNames;
public ForeignKeyNameSource(ForeignKey foreignKey, Table table, MetadataBuildingContext buildingContext) {
this.foreignKey = foreignKey;
this.table = table;
this.buildingContext = buildingContext;
columnNames = extractColumnNames(foreignKey.getColumns());
referencedColumnNames = null;
}
@Override
public Identifier getTableName() {
return table.getNameIdentifier();
}
@Override
public List<Identifier> getColumnNames() {
return columnNames;
}
@Override
public Identifier getReferencedTableName() {
return foreignKey.getReferencedTable().getNameIdentifier();
}
@Override
public List<Identifier> getReferencedColumnNames() {
if ( referencedColumnNames == null ) {
referencedColumnNames = extractColumnNames( foreignKey.getReferencedColumns() );
}
return referencedColumnNames;
}
@Override
public Identifier getUserProvidedIdentifier() {
return foreignKey.getName() != null ? Identifier.toIdentifier( foreignKey.getName() ) : null;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return buildingContext;
}
}
}

View File

@ -301,7 +301,9 @@ public class AnnotatedColumn {
mappingColumn.setArrayLength( arrayLength );
mappingColumn.setNullable( nullable );
mappingColumn.setSqlType( sqlType );
mappingColumn.setUnique( unique );
if ( unique ) {
getParent().getTable().createUniqueKey( mappingColumn, getBuildingContext() );
}
for ( CheckConstraint constraint : checkConstraints ) {
mappingColumn.addCheckConstraint( constraint );
}

View File

@ -213,7 +213,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
AnnotatedJoinColumns parent,
MetadataBuildingContext context) {
final String defaultColumnName = context.getMetadataCollector()
.getLogicalColumnName( identifier.getTable(), identifier.getColumns().get(0).getQuotedName() );
.getLogicalColumnName( identifier.getTable(), identifier.getColumns().get(0).getQuotedName() );
return primaryKeyJoinColumn != null || joinColumn != null
? buildExplicitInheritanceJoinColumn( primaryKeyJoinColumn, joinColumn, parent, context, defaultColumnName )
: buildImplicitInheritanceJoinColumn( parent, context, defaultColumnName );

View File

@ -610,7 +610,8 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
)
);
}
return database.toIdentifier( ( (Column) selectable ).getQuotedName() );
final Column column = (Column) selectable;
return column.getNameIdentifier( getBuildingContext() );
}
@Override

View File

@ -350,7 +350,7 @@ public class BinderHelper {
else {
ownerEntity.addProperty( result );
}
embeddedComponent.createUniqueKey(); //make it unique
embeddedComponent.createUniqueKey( context ); //make it unique
return result;
}

View File

@ -8,10 +8,7 @@ package org.hibernate.boot.model.internal;
import jakarta.persistence.UniqueConstraint;
import org.hibernate.AnnotationException;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitIndexNameSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.ImplicitUniqueKeyNameSource;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.spi.MetadataBuildingContext;
@ -28,9 +25,7 @@ import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
import static java.util.Collections.emptyList;
import static org.hibernate.internal.util.StringHelper.isEmpty;
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
/**
* Responsible for interpreting {@link jakarta.persistence.Index} and
@ -233,57 +228,4 @@ class IndexBinder {
}
}
}
private class IndexOrUniqueKeyNameSource implements ImplicitIndexNameSource, ImplicitUniqueKeyNameSource {
private final MetadataBuildingContext buildingContext;
private final Table table;
private final String[] columnNames;
private final String originalKeyName;
public IndexOrUniqueKeyNameSource(MetadataBuildingContext buildingContext, Table table, String[] columnNames, String originalKeyName) {
this.buildingContext = buildingContext;
this.table = table;
this.columnNames = columnNames;
this.originalKeyName = originalKeyName;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return buildingContext;
}
@Override
public Identifier getTableName() {
return table.getNameIdentifier();
}
private List<Identifier> columnNameIdentifiers;
@Override
public List<Identifier> getColumnNames() {
// be lazy about building these
if ( columnNameIdentifiers == null ) {
columnNameIdentifiers = toIdentifiers( columnNames );
}
return columnNameIdentifiers;
}
@Override
public Identifier getUserProvidedIdentifier() {
return originalKeyName != null ? Identifier.toIdentifier( originalKeyName ) : null;
}
}
private List<Identifier> toIdentifiers(String[] names) {
if ( names == null ) {
return emptyList();
}
final List<Identifier> columnNames = arrayList( names.length );
for ( String name : names ) {
columnNames.add( getDatabase().toIdentifier( name ) );
}
return columnNames;
}
}

View File

@ -0,0 +1,72 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.boot.model.internal;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitIndexNameSource;
import org.hibernate.boot.model.naming.ImplicitUniqueKeyNameSource;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.mapping.Table;
import java.util.List;
import static java.util.Collections.emptyList;
import static org.hibernate.boot.model.naming.Identifier.toIdentifier;
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
class IndexOrUniqueKeyNameSource implements ImplicitIndexNameSource, ImplicitUniqueKeyNameSource {
private final MetadataBuildingContext buildingContext;
private final Table table;
private final String[] columnNames;
private final String originalKeyName;
public IndexOrUniqueKeyNameSource(
MetadataBuildingContext buildingContext, Table table, String[] columnNames, String originalKeyName) {
this.buildingContext = buildingContext;
this.table = table;
this.columnNames = columnNames;
this.originalKeyName = originalKeyName;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return buildingContext;
}
@Override
public Identifier getTableName() {
return table.getNameIdentifier();
}
private List<Identifier> columnNameIdentifiers;
@Override
public List<Identifier> getColumnNames() {
// be lazy about building these
if ( columnNameIdentifiers == null ) {
columnNameIdentifiers = toIdentifiers( columnNames );
}
return columnNameIdentifiers;
}
@Override
public Identifier getUserProvidedIdentifier() {
return originalKeyName != null ? toIdentifier( originalKeyName ) : null;
}
private List<Identifier> toIdentifiers(String[] names) {
if ( names == null ) {
return emptyList();
}
final List<Identifier> columnNames = arrayList( names.length );
for ( String name : names ) {
columnNames.add( buildingContext.getMetadataCollector().getDatabase().toIdentifier( name ) );
}
return columnNames;
}
}

View File

@ -568,7 +568,7 @@ public class TableBinder {
}
value.createForeignKey( referencedEntity, joinColumns );
if ( unique ) {
value.createUniqueKey();
value.createUniqueKey( buildingContext );
}
}

View File

@ -11,7 +11,10 @@ import java.io.Serializable;
import org.hibernate.HibernateException;
import org.hibernate.boot.model.source.spi.AttributePath;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.util.StringHelper;
import static org.hibernate.boot.model.naming.ImplicitJoinColumnNameSource.Nature.ELEMENT_COLLECTION;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.unqualify;
/**
* Implementation of the {@link ImplicitNamingStrategy} contract, generally
@ -47,12 +50,12 @@ public class ImplicitNamingStrategyJpaCompliantImpl implements ImplicitNamingStr
protected String transformEntityName(EntityNaming entityNaming) {
// prefer the JPA entity name, if specified...
if ( StringHelper.isNotEmpty( entityNaming.getJpaEntityName() ) ) {
if ( isNotEmpty( entityNaming.getJpaEntityName() ) ) {
return entityNaming.getJpaEntityName();
}
else {
// otherwise, use the Hibernate entity name
return StringHelper.unqualify( entityNaming.getEntityName() );
return unqualify( entityNaming.getEntityName() );
}
}
@ -67,7 +70,6 @@ public class ImplicitNamingStrategyJpaCompliantImpl implements ImplicitNamingStr
final String name = source.getOwningPhysicalTableName()
+ '_'
+ source.getNonOwningPhysicalTableName();
return toIdentifier( name, source.getBuildingContext() );
}
@ -80,12 +82,9 @@ public class ImplicitNamingStrategyJpaCompliantImpl implements ImplicitNamingStr
// aka:
// if owning entity has a JPA entity name: {OWNER JPA ENTITY NAME}_{COLLECTION ATTRIBUTE NAME}
// otherwise: {OWNER ENTITY NAME}_{COLLECTION ATTRIBUTE NAME}
final String entityName = transformEntityName( source.getOwningEntityNaming() );
final String name = entityName
final String name = transformEntityName( source.getOwningEntityNaming() )
+ '_'
+ transformAttributePath( source.getOwningAttributePath() );
return toIdentifier( name, source.getBuildingContext() );
}
@ -141,16 +140,15 @@ public class ImplicitNamingStrategyJpaCompliantImpl implements ImplicitNamingStr
final String name;
if ( source.getNature() == ImplicitJoinColumnNameSource.Nature.ELEMENT_COLLECTION
String referencedColumnName = source.getReferencedColumnName().getText();
if ( source.getNature() == ELEMENT_COLLECTION
|| source.getAttributePath() == null ) {
name = transformEntityName( source.getEntityNaming() )
+ '_'
+ source.getReferencedColumnName().getText();
+ '_' + referencedColumnName;
}
else {
name = transformAttributePath( source.getAttributePath() )
+ '_'
+ source.getReferencedColumnName().getText();
+ '_' + referencedColumnName;
}
return toIdentifier( name, source.getBuildingContext() );
@ -165,17 +163,21 @@ public class ImplicitNamingStrategyJpaCompliantImpl implements ImplicitNamingStr
@Override
public Identifier determineAnyDiscriminatorColumnName(ImplicitAnyDiscriminatorColumnNameSource source) {
final MetadataBuildingContext buildingContext = source.getBuildingContext();
return toIdentifier(
transformAttributePath( source.getAttributePath() ) + "_" + source.getBuildingContext().getMappingDefaults().getImplicitDiscriminatorColumnName(),
source.getBuildingContext()
transformAttributePath( source.getAttributePath() )
+ "_" + buildingContext.getMappingDefaults().getImplicitDiscriminatorColumnName(),
buildingContext
);
}
@Override
public Identifier determineAnyKeyColumnName(ImplicitAnyKeyColumnNameSource source) {
final MetadataBuildingContext buildingContext = source.getBuildingContext();
return toIdentifier(
transformAttributePath( source.getAttributePath() ) + "_" + source.getBuildingContext().getMappingDefaults().getImplicitIdColumnName(),
source.getBuildingContext()
transformAttributePath( source.getAttributePath() )
+ "_" + buildingContext.getMappingDefaults().getImplicitIdColumnName(),
buildingContext
);
}
@ -198,41 +200,35 @@ public class ImplicitNamingStrategyJpaCompliantImpl implements ImplicitNamingStr
@Override
public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {
Identifier userProvidedIdentifier = source.getUserProvidedIdentifier();
final Identifier userProvidedIdentifier = source.getUserProvidedIdentifier();
final MetadataBuildingContext buildingContext = source.getBuildingContext();
return userProvidedIdentifier != null ? userProvidedIdentifier : toIdentifier(
NamingHelper.withCharset( source.getBuildingContext().getBuildingOptions().getSchemaCharset() ).generateHashedFkName(
"FK",
source.getTableName(),
source.getReferencedTableName(),
source.getColumnNames()
),
source.getBuildingContext()
NamingHelper.withCharset( buildingContext.getBuildingOptions().getSchemaCharset() )
.generateHashedFkName( "FK", source.getTableName(),
source.getReferencedTableName(), source.getColumnNames() ),
buildingContext
);
}
@Override
public Identifier determineUniqueKeyName(ImplicitUniqueKeyNameSource source) {
Identifier userProvidedIdentifier = source.getUserProvidedIdentifier();
final Identifier userProvidedIdentifier = source.getUserProvidedIdentifier();
final MetadataBuildingContext buildingContext = source.getBuildingContext();
return userProvidedIdentifier != null ? userProvidedIdentifier : toIdentifier(
NamingHelper.withCharset( source.getBuildingContext().getBuildingOptions().getSchemaCharset() ).generateHashedConstraintName(
"UK",
source.getTableName(),
source.getColumnNames()
),
source.getBuildingContext()
NamingHelper.withCharset( buildingContext.getBuildingOptions().getSchemaCharset() )
.generateHashedConstraintName( "UK", source.getTableName(), source.getColumnNames() ),
buildingContext
);
}
@Override
public Identifier determineIndexName(ImplicitIndexNameSource source) {
Identifier userProvidedIdentifier = source.getUserProvidedIdentifier();
final Identifier userProvidedIdentifier = source.getUserProvidedIdentifier();
final MetadataBuildingContext buildingContext = source.getBuildingContext();
return userProvidedIdentifier != null ? userProvidedIdentifier : toIdentifier(
NamingHelper.withCharset( source.getBuildingContext().getBuildingOptions().getSchemaCharset() ).generateHashedConstraintName(
"IDX",
source.getTableName(),
source.getColumnNames()
),
source.getBuildingContext()
NamingHelper.withCharset( buildingContext.getBuildingOptions().getSchemaCharset() )
.generateHashedConstraintName( "IDX", source.getTableName(), source.getColumnNames() ),
buildingContext
);
}

View File

@ -16,6 +16,8 @@ import java.util.List;
import org.hibernate.HibernateException;
import static java.util.Comparator.comparing;
/**
* @author Steve Ebersole
*/
@ -48,19 +50,13 @@ public class NamingHelper {
Identifier tableName,
Identifier referencedTableName,
List<Identifier> columnNames) {
final Identifier[] columnNamesArray;
if ( columnNames == null || columnNames.isEmpty() ) {
columnNamesArray = new Identifier[0];
}
else {
columnNamesArray = columnNames.toArray( new Identifier[ columnNames.size() ] );
}
return generateHashedFkName(
prefix,
tableName,
referencedTableName,
columnNamesArray
columnNames == null || columnNames.isEmpty()
? new Identifier[0]
: columnNames.toArray( new Identifier[0] )
);
}
@ -118,15 +114,7 @@ public class NamingHelper {
// Clone the list, as sometimes a set of order-dependent Column
// bindings are given.
Identifier[] alphabeticalColumns = columnNames.clone();
Arrays.sort(
alphabeticalColumns,
new Comparator<Identifier>() {
@Override
public int compare(Identifier o1, Identifier o2) {
return o1.getCanonicalName().compareTo( o2.getCanonicalName() );
}
}
);
Arrays.sort( alphabeticalColumns, comparing(Identifier::getCanonicalName) );
for ( Identifier columnName : alphabeticalColumns ) {
sb.append( "column`" ).append( columnName ).append( "`" );
}

View File

@ -160,9 +160,12 @@ import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
import static org.hibernate.boot.model.naming.Identifier.toIdentifier;
import static org.hibernate.boot.model.source.internal.hbm.Helper.reflectedPropertyClass;
import static org.hibernate.cfg.AvailableSettings.USE_ENTITY_WHERE_CLAUSE_FOR_COLLECTIONS;
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
import static org.hibernate.internal.util.StringHelper.getNonEmptyOrConjunctionIfBothNonEmpty;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty;
import static org.hibernate.mapping.SimpleValue.DEFAULT_ID_GEN_STRATEGY;
@ -406,7 +409,7 @@ public class ModelBinder {
);
// NOTE : entitySource#isLazy already accounts for MappingDefaults#areEntitiesImplicitlyLazy
if ( StringHelper.isNotEmpty( entitySource.getProxy() ) ) {
if ( isNotEmpty( entitySource.getProxy() ) ) {
final String qualifiedProxyName = sourceDocument.qualifyClassName( entitySource.getProxy() );
entityDescriptor.setProxyInterfaceName( qualifiedProxyName );
entityDescriptor.setLazy( true );
@ -439,7 +442,7 @@ public class ModelBinder {
entityDescriptor.setBatchSize( entitySource.getBatchSize() );
entityDescriptor.setSelectBeforeUpdate( entitySource.isSelectBeforeUpdate() );
if ( StringHelper.isNotEmpty( entitySource.getCustomPersisterClassName() ) ) {
if ( isNotEmpty( entitySource.getCustomPersisterClassName() ) ) {
try {
entityDescriptor.setEntityPersisterClass(
sourceDocument.getBootstrapContext()
@ -623,8 +626,8 @@ public class ModelBinder {
int count = 0;
@Override
public Identifier determineImplicitName(LocalMetadataBuildingContext context) {
final Column column = primaryTable.getPrimaryKey().getColumn( count++ );
return database.toIdentifier( column.getQuotedName() );
return primaryTable.getPrimaryKey().getColumn( count++ )
.getNameIdentifier( metadataBuildingContext );
}
}
);
@ -799,7 +802,7 @@ public class ModelBinder {
identifierValue.getTable().setIdentifierValue( identifierValue );
if ( StringHelper.isNotEmpty( unsavedValue ) ) {
if ( isNotEmpty( unsavedValue ) ) {
identifierValue.setNullValue( unsavedValue );
}
else if ( DEFAULT_ID_GEN_STRATEGY.equals( identifierValue.getIdentifierGeneratorStrategy() ) ) {
@ -1696,7 +1699,7 @@ public class ModelBinder {
inLineViewSource.getSelectStatement(),
false
);
logicalTableName = Identifier.toIdentifier( inLineViewSource.getLogicalName() );
logicalTableName = toIdentifier( inLineViewSource.getLogicalName() );
}
secondaryTableJoin.setTable( secondaryTable );
@ -1738,8 +1741,8 @@ public class ModelBinder {
int count = 0;
@Override
public Identifier determineImplicitName(LocalMetadataBuildingContext context) {
final Column correspondingColumn = entityTableXref.getPrimaryTable().getPrimaryKey().getColumn( count++ );
return database.toIdentifier( correspondingColumn.getQuotedName() );
return entityTableXref.getPrimaryTable().getPrimaryKey().getColumn( count++ )
.getNameIdentifier( metadataBuildingContext );
}
}
);
@ -2062,7 +2065,7 @@ public class ModelBinder {
oneToOneBinding.setUnwrapProxy( oneToOneSource.getFetchCharacteristics().isUnwrapProxies() );
if ( StringHelper.isNotEmpty( oneToOneSource.getReferencedEntityAttributeName() ) ) {
if ( isNotEmpty( oneToOneSource.getReferencedEntityAttributeName() ) ) {
oneToOneBinding.setReferencedPropertyName( oneToOneSource.getReferencedEntityAttributeName() );
oneToOneBinding.setReferenceToPrimaryKey( false );
}
@ -2077,7 +2080,7 @@ public class ModelBinder {
DEPRECATION_LOGGER.logDeprecationOfEmbedXmlSupport();
}
if ( StringHelper.isNotEmpty( oneToOneSource.getExplicitForeignKeyName() ) ) {
if ( isNotEmpty( oneToOneSource.getExplicitForeignKeyName() ) ) {
oneToOneBinding.setForeignKeyName( oneToOneSource.getExplicitForeignKeyName() );
}
@ -2096,7 +2099,7 @@ public class ModelBinder {
referencedEntityName = manyToOneSource.getReferencedEntityName();
}
else {
Class<?> reflectedPropertyClass = Helper.reflectedPropertyClass( sourceDocument, containingClassName, attributeName );
Class<?> reflectedPropertyClass = reflectedPropertyClass( sourceDocument, containingClassName, attributeName );
if ( reflectedPropertyClass != null ) {
referencedEntityName = reflectedPropertyClass.getName();
}
@ -2137,7 +2140,7 @@ public class ModelBinder {
prop
);
if ( StringHelper.isNotEmpty( manyToOneSource.getCascadeStyleName() ) ) {
if ( isNotEmpty( manyToOneSource.getCascadeStyleName() ) ) {
// todo : would be better to delay this the end of binding (second pass, etc)
// in order to properly allow for a singular unique column for a many-to-one to
// also trigger a "logical one-to-one". As-is, this can occasionally lead to
@ -2174,7 +2177,7 @@ public class ModelBinder {
// NOTE : no type information to bind
manyToOneBinding.setReferencedEntityName( referencedEntityName );
if ( StringHelper.isNotEmpty( manyToOneSource.getReferencedEntityAttributeName() ) ) {
if ( isNotEmpty( manyToOneSource.getReferencedEntityAttributeName() ) ) {
manyToOneBinding.setReferencedPropertyName( manyToOneSource.getReferencedEntityAttributeName() );
manyToOneBinding.setReferenceToPrimaryKey( false );
}
@ -2196,7 +2199,7 @@ public class ModelBinder {
manyToOneBinding.setIgnoreNotFound( manyToOneSource.isIgnoreNotFound() );
if ( StringHelper.isNotEmpty( manyToOneSource.getExplicitForeignKeyName() ) ) {
if ( isNotEmpty( manyToOneSource.getExplicitForeignKeyName() ) ) {
manyToOneBinding.setForeignKeyName( manyToOneSource.getExplicitForeignKeyName() );
}
@ -2465,7 +2468,7 @@ public class ModelBinder {
property.setName( propertySource.getName() );
property.setPropertyAccessorName(
StringHelper.isNotEmpty( propertySource.getPropertyAccessorName() )
isNotEmpty( propertySource.getPropertyAccessorName() )
? propertySource.getPropertyAccessorName()
: mappingDocument.getMappingDefaults().getImplicitPropertyAccessorName()
);
@ -2474,7 +2477,7 @@ public class ModelBinder {
final CascadeStyleSource cascadeStyleSource = (CascadeStyleSource) propertySource;
property.setCascade(
StringHelper.isNotEmpty( cascadeStyleSource.getCascadeStyleName() )
isNotEmpty( cascadeStyleSource.getCascadeStyleName() )
? cascadeStyleSource.getCascadeStyleName()
: mappingDocument.getMappingDefaults().getImplicitCascadeStyleName()
);
@ -2613,7 +2616,7 @@ public class ModelBinder {
}
else {
log.debugf( "Binding component [%s]", role );
if ( StringHelper.isNotEmpty( explicitComponentClassName ) ) {
if ( isNotEmpty( explicitComponentClassName ) ) {
try {
final Class<Object> componentClass = sourceDocument.getBootstrapContext()
.getClassLoaderAccess()
@ -2643,12 +2646,8 @@ public class ModelBinder {
else if ( componentBinding.getOwner().hasPojoRepresentation() ) {
log.tracef( "Attempting to determine component class by reflection %s", role );
final Class<?> reflectedComponentClass;
if ( StringHelper.isNotEmpty( containingClassName ) && StringHelper.isNotEmpty( propertyName ) ) {
reflectedComponentClass = Helper.reflectedPropertyClass(
sourceDocument,
containingClassName,
propertyName
);
if ( isNotEmpty( containingClassName ) && isNotEmpty( propertyName ) ) {
reflectedComponentClass = reflectedPropertyClass( sourceDocument, containingClassName, propertyName );
}
else {
reflectedComponentClass = null;
@ -2671,11 +2670,7 @@ public class ModelBinder {
}
// todo : anything else to pass along?
bindAllCompositeAttributes(
sourceDocument,
embeddableSource,
componentBinding
);
bindAllCompositeAttributes( sourceDocument, embeddableSource, componentBinding );
if ( embeddableSource.getParentReferenceAttributeName() != null ) {
componentBinding.setParentProperty( embeddableSource.getParentReferenceAttributeName() );
@ -2689,7 +2684,7 @@ public class ModelBinder {
}
}
// todo : we may need to delay this
componentBinding.getOwner().getTable().createUniqueKey( cols );
componentBinding.getOwner().getTable().createUniqueKey( cols, metadataBuildingContext );
}
}
@ -2847,7 +2842,7 @@ public class ModelBinder {
if ( isTable ) {
final TableSource tableSource = (TableSource) tableSpecSource;
if ( StringHelper.isNotEmpty( tableSource.getExplicitTableName() ) ) {
if ( isNotEmpty( tableSource.getExplicitTableName() ) ) {
logicalTableName = database.toIdentifier( tableSource.getExplicitTableName() );
}
else {
@ -2939,7 +2934,7 @@ public class ModelBinder {
if ( isTable ) {
final TableSource tableSource = (TableSource) tableSpecSource;
table.setRowId( tableSource.getRowId() );
if ( StringHelper.isNotEmpty( tableSource.getCheckConstraint() ) ) {
if ( isNotEmpty( tableSource.getCheckConstraint() ) ) {
table.addCheckConstraint( tableSource.getCheckConstraint() );
}
}
@ -2952,7 +2947,7 @@ public class ModelBinder {
}
private Identifier determineCatalogName(TableSpecificationSource tableSpecSource) {
if ( StringHelper.isNotEmpty( tableSpecSource.getExplicitCatalogName() ) ) {
if ( isNotEmpty( tableSpecSource.getExplicitCatalogName() ) ) {
return database.toIdentifier( tableSpecSource.getExplicitCatalogName() );
}
else {
@ -2961,7 +2956,7 @@ public class ModelBinder {
}
private Identifier determineSchemaName(TableSpecificationSource tableSpecSource) {
if ( StringHelper.isNotEmpty( tableSpecSource.getExplicitSchemaName() ) ) {
if ( isNotEmpty( tableSpecSource.getExplicitSchemaName() ) ) {
return database.toIdentifier( tableSpecSource.getExplicitSchemaName() );
}
else {
@ -3183,8 +3178,8 @@ public class ModelBinder {
final TableSource tableSource = (TableSource) tableSpecSource;
Identifier logicalName;
if ( StringHelper.isNotEmpty( tableSource.getExplicitTableName() ) ) {
logicalName = Identifier.toIdentifier(
if ( isNotEmpty( tableSource.getExplicitTableName() ) ) {
logicalName = toIdentifier(
tableSource.getExplicitTableName(),
mappingDocument.getMappingDefaults().shouldImplicitlyQuoteIdentifiers()
);
@ -3486,7 +3481,7 @@ public class ModelBinder {
elementBinding.setForeignKeyName( elementSource.getExplicitForeignKeyName() );
elementBinding.setReferencedEntityName( elementSource.getReferencedEntityName() );
if ( StringHelper.isNotEmpty( elementSource.getReferencedEntityAttributeName() ) ) {
if ( isNotEmpty( elementSource.getReferencedEntityAttributeName() ) ) {
elementBinding.setReferencedPropertyName( elementSource.getReferencedEntityAttributeName() );
elementBinding.setReferenceToPrimaryKey( false );
}
@ -4180,37 +4175,37 @@ public class ModelBinder {
if ( selectable instanceof Column ) {
final Column column = (Column) selectable;
uk.addColumn( column );
columnNames.add(
mappingDocument.getMetadataCollector().getDatabase().toIdentifier( column.getQuotedName() )
);
columnNames.add( column.getNameIdentifier( mappingDocument ) );
}
}
uk.addColumns( attributeBinding.getValue() );
}
final Identifier ukName = mappingDocument.getBuildingOptions().getImplicitNamingStrategy().determineUniqueKeyName(
new ImplicitUniqueKeyNameSource() {
@Override
public Identifier getTableName() {
return entityBinding.getTable().getNameIdentifier();
}
final Identifier ukName = mappingDocument.getBuildingOptions().getImplicitNamingStrategy()
.determineUniqueKeyName(
new ImplicitUniqueKeyNameSource() {
@Override
public Identifier getTableName() {
return entityBinding.getTable().getNameIdentifier();
}
@Override
public List<Identifier> getColumnNames() {
return columnNames;
}
@Override
public List<Identifier> getColumnNames() {
return columnNames;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return mappingDocument;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return mappingDocument;
}
@Override
public Identifier getUserProvidedIdentifier() {
return uk.getName() != null ? Identifier.toIdentifier( uk.getName() ) : null;
}
}
);
@Override
public Identifier getUserProvidedIdentifier() {
final String name = uk.getName();
return name == null ? null : toIdentifier( name );
}
}
);
uk.setName( ukName.render( mappingDocument.getMetadataCollector().getDatabase().getDialect() ) );
entityBinding.getTable().addUniqueKey( uk );

View File

@ -155,6 +155,9 @@ public class RelationalObjectBinder {
column.setNullable( interpretNullability( columnSource.isNullable(), areColumnsNullableByDefault ) );
column.setUnique( columnSource.isUnique() );
if ( columnSource.isUnique() && table != null ) {
table.createUniqueKey( column, simpleValue.getBuildingContext() );
}
String checkCondition = columnSource.getCheckCondition();
if ( checkCondition != null ) {

View File

@ -139,7 +139,7 @@ public class ExportableColumn extends Column {
}
@Override
public void createUniqueKey() {
public void createUniqueKey(MetadataBuildingContext context) {
}
@Override

View File

@ -29,6 +29,7 @@ public class AggregateColumn extends Column {
setName( column.getQuotedName() );
setNullable( column.isNullable() );
setUnique( column.isUnique() );
setUniqueKeyName( column.getUniqueKeyName() );
setSqlType( column.getSqlType() );
setSqlTypeCode( column.getSqlTypeCode() );
uniqueInteger = column.uniqueInteger; //usually useless

View File

@ -499,7 +499,7 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
}
@Override
public void createUniqueKey() {
public void createUniqueKey(MetadataBuildingContext context) {
}
public boolean isSimpleValue() {

View File

@ -13,17 +13,19 @@ import java.util.Locale;
import java.util.Objects;
import org.hibernate.AssertionFailure;
import org.hibernate.Internal;
import org.hibernate.MappingException;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.TruthValue;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.loader.internal.AliasConstantsHelper;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.query.sqm.internal.TypecheckUtil;
import org.hibernate.sql.Template;
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
import org.hibernate.type.BasicType;
@ -61,6 +63,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
private String name;
private boolean nullable = true;
private boolean unique;
private String uniqueKeyName;
private String sqlTypeName;
private Integer sqlTypeCode;
private Boolean sqlTypeLob;
@ -126,6 +129,12 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
}
}
@Internal
public Identifier getNameIdentifier(MetadataBuildingContext buildingContext) {
return buildingContext.getMetadataCollector().getDatabase()
.toIdentifier( getQuotedName() );
}
public boolean isExplicit() {
return explicit;
}
@ -566,6 +575,14 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
this.unique = unique;
}
public String getUniqueKeyName() {
return uniqueKeyName;
}
public void setUniqueKeyName(String keyName) {
uniqueKeyName = keyName;
}
public boolean isQuoted() {
return quoted;
}
@ -778,6 +795,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
copy.quoted = quoted;
copy.nullable = nullable;
copy.unique = unique;
copy.uniqueKeyName = uniqueKeyName;
copy.sqlTypeName = sqlTypeName;
copy.sqlTypeCode = sqlTypeCode;
copy.uniqueInteger = uniqueInteger; //usually useless
@ -792,5 +810,4 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn
copy.columnSize = columnSize;
return copy;
}
}

View File

@ -47,7 +47,10 @@ public abstract class Constraint implements Exportable, Serializable {
* They're cached, keyed by name, in multiple locations.
*
* @return String The generated name
*
* @deprecated This method does not respect the {@link org.hibernate.boot.model.naming.ImplicitNamingStrategy}
*/
@Deprecated(since = "6.5", forRemoval = true)
public static String generateName(String prefix, Table table, Column... columns) {
// Use a concatenation that guarantees uniqueness, even if identical names
// exist between all table and column identifiers.
@ -69,7 +72,10 @@ public abstract class Constraint implements Exportable, Serializable {
* Helper method for {@link #generateName(String, Table, Column...)}.
*
* @return String The generated name
*
* @deprecated This method does not respect the {@link org.hibernate.boot.model.naming.ImplicitNamingStrategy}
*/
@Deprecated(since = "6.5", forRemoval = true)
public static String generateName(String prefix, Table table, List<Column> columns) {
// N.B. legacy APIs are involved: can't trust that the columns List is actually
// containing Column instances - the generic type isn't consistently enforced.
@ -89,7 +95,10 @@ public abstract class Constraint implements Exportable, Serializable {
*
* @param name The name to be hashed.
* @return String The hashed name.
*
* @deprecated Only used from deprecated methods
*/
@Deprecated(since = "6.5", forRemoval = true)
public static String hashedName(String name) {
try {
final MessageDigest md = MessageDigest.getInstance( "MD5" );
@ -147,6 +156,10 @@ public abstract class Constraint implements Exportable, Serializable {
this.table = table;
}
/**
* @deprecated No longer used
*/
@Deprecated(forRemoval = true)
public boolean isGenerated(Dialect dialect) {
return true;
}
@ -172,6 +185,8 @@ public abstract class Constraint implements Exportable, Serializable {
/**
* @return String The prefix to use in generated constraint names. Examples:
* "UK_", "FK_", and "PK_".
* @deprecated No longer used, should be removed
*/
@Deprecated(since="6.5", forRemoval = true)
public abstract String generatedConstraintNamePrefix();
}

View File

@ -12,8 +12,10 @@ import java.util.Iterator;
import java.util.List;
import org.hibernate.Internal;
import org.hibernate.boot.internal.ForeignKeyNameSource;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.internal.util.collections.JoinedList;
/**
@ -59,15 +61,20 @@ public class DenormalizedTable extends Table {
}
@Override
public void createForeignKeys() {
includedTable.createForeignKeys();
public void createForeignKeys(MetadataBuildingContext context) {
includedTable.createForeignKeys( context );
for ( ForeignKey foreignKey : includedTable.getForeignKeys().values() ) {
final PersistentClass referencedClass =
foreignKey.resolveReferencedClass( context.getMetadataCollector() );
// the ForeignKeys created in the first pass did not have their referenced table initialized
if ( foreignKey.getReferencedTable() == null ) {
foreignKey.setReferencedTable( referencedClass.getTable() );
}
createForeignKey(
Constraint.generateName(
foreignKey.generatedConstraintNamePrefix(),
this,
foreignKey.getColumns()
),
context.getBuildingOptions()
.getImplicitNamingStrategy()
.determineForeignKeyName( new ForeignKeyNameSource( foreignKey, this, context ) )
.render( context.getMetadataCollector().getDatabase().getDialect() ),
foreignKey.getColumns(),
foreignKey.getReferencedEntityName(),
foreignKey.getKeyDefinition(),
@ -105,7 +112,7 @@ public class DenormalizedTable extends Table {
return includedTable.getPrimaryKey();
}
@Override @Deprecated
@Override @Deprecated(forRemoval = true)
public Iterator<UniqueKey> getUniqueKeyIterator() {
if ( !includedTable.isPhysicalTable() ) {
for ( UniqueKey uniqueKey : includedTable.getUniqueKeys().values() ) {

View File

@ -10,8 +10,10 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Internal;
import org.hibernate.MappingException;
import org.hibernate.annotations.OnDeleteAction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.dialect.Dialect;
@ -232,7 +234,25 @@ public class ForeignKey extends Constraint {
}
@Deprecated(forRemoval = true)
public String generatedConstraintNamePrefix() {
return "FK_";
}
@Internal
public PersistentClass resolveReferencedClass(Metadata metadata) {
final String referencedEntityName = getReferencedEntityName();
if ( referencedEntityName == null ) {
throw new MappingException( "An association from the table '" + getTable().getName() +
"' does not specify the referenced entity" );
}
final PersistentClass referencedClass = metadata.getEntityBinding( referencedEntityName );
if ( referencedClass == null ) {
throw new MappingException( "An association from the table '" + getTable().getName() +
"' refers to an unmapped class '" + referencedEntityName + "'" );
}
return referencedClass;
}
}

View File

@ -60,9 +60,9 @@ public class ManyToOne extends ToOne {
}
@Override
public void createUniqueKey() {
public void createUniqueKey(MetadataBuildingContext context) {
if ( !hasFormula() ) {
getTable().createUniqueKey( getConstraintColumns() );
getTable().createUniqueKey( getConstraintColumns(), context );
}
}

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.mapping;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
@ -91,7 +90,7 @@ public class OneToMany implements Value {
}
@Override
public void createUniqueKey() {
public void createUniqueKey(MetadataBuildingContext context) {
}
@Override

View File

@ -94,9 +94,9 @@ public class OneToOne extends ToOne {
}
@Override
public void createUniqueKey() {
public void createUniqueKey(MetadataBuildingContext context) {
if ( !hasFormula() && getColumnSpan()>0 ) {
getTable().createUniqueKey( getConstraintColumns() );
getTable().createUniqueKey( getConstraintColumns(), context );
}
}

View File

@ -100,7 +100,8 @@ public class PrimaryKey extends Constraint {
}
return buf.append(')').toString();
}
@Deprecated(forRemoval = true)
public String generatedConstraintNamePrefix() {
return "PK_";
}

View File

@ -368,11 +368,11 @@ public abstract class SimpleValue implements KeyValue {
}
@Override
public void createUniqueKey() {
public void createUniqueKey(MetadataBuildingContext context) {
if ( hasFormula() ) {
throw new MappingException( "unique key constraint involves formulas" );
}
getTable().createUniqueKey( getConstraintColumns() );
getTable().createUniqueKey( getConstraintColumns(), context );
}
/**

View File

@ -23,12 +23,14 @@ import org.hibernate.MappingException;
import org.hibernate.Remove;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitUniqueKeyNameSource;
import org.hibernate.boot.model.relational.ContributableDatabaseObject;
import org.hibernate.boot.model.relational.InitCommand;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.QualifiedTableName;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.tool.schema.extract.spi.TableInformation;
@ -36,9 +38,11 @@ import org.hibernate.tool.schema.internal.StandardTableMigrator;
import org.jboss.logging.Logger;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import static java.util.stream.Collectors.toList;
import static org.hibernate.boot.model.naming.Identifier.toIdentifier;
/**
* A mapping model object representing a relational database {@linkplain jakarta.persistence.Table table}.
@ -151,7 +155,7 @@ public class Table implements Serializable, ContributableDatabaseObject {
}
public void setName(String name) {
this.name = Identifier.toIdentifier( name );
this.name = toIdentifier( name );
}
public String getName() {
@ -193,7 +197,7 @@ public class Table implements Serializable, ContributableDatabaseObject {
}
public void setSchema(String schema) {
this.schema = Identifier.toIdentifier( schema );
this.schema = toIdentifier( schema );
}
public String getSchema() {
@ -213,7 +217,7 @@ public class Table implements Serializable, ContributableDatabaseObject {
}
public void setCatalog(String catalog) {
this.catalog = Identifier.toIdentifier( catalog );
this.catalog = toIdentifier( catalog );
}
public String getCatalog() {
@ -321,7 +325,10 @@ public class Table implements Serializable, ContributableDatabaseObject {
return unmodifiableMap( indexes );
}
@Deprecated(since = "6.0")
/**
* @deprecated No longer used, should be removed
*/
@Deprecated(since = "6.0", forRemoval = true)
public Iterator<ForeignKey> getForeignKeyIterator() {
return getForeignKeys().values().iterator();
}
@ -330,7 +337,10 @@ public class Table implements Serializable, ContributableDatabaseObject {
return unmodifiableMap( foreignKeys );
}
@Deprecated(since = "6.0")
/**
* @deprecated No longer used, should be removed
*/
@Deprecated(since = "6.0", forRemoval = true)
public Iterator<UniqueKey> getUniqueKeyIterator() {
return getUniqueKeys().values().iterator();
}
@ -508,10 +518,84 @@ public class Table implements Serializable, ContributableDatabaseObject {
return uniqueKey;
}
/**
* Mark the given column unique.
*/
public void createUniqueKey(Column column, MetadataBuildingContext context) {
final String keyName = context.getBuildingOptions().getImplicitNamingStrategy()
.determineUniqueKeyName( new ImplicitUniqueKeyNameSource() {
@Override
public Identifier getTableName() {
return name;
}
@Override
public List<Identifier> getColumnNames() {
return singletonList( column.getNameIdentifier( context ) );
}
@Override
public Identifier getUserProvidedIdentifier() {
return null;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return context;
}
} )
.render( context.getMetadataCollector().getDatabase().getDialect() );
column.setUniqueKeyName( keyName );
column.setUnique( true );
}
/**
* If there is one given column, mark it unique, otherwise
* create a {@link UniqueKey} comprising the given columns.
*/
public void createUniqueKey(List<Column> keyColumns, MetadataBuildingContext context) {
if ( keyColumns.size() == 1 ) {
createUniqueKey( keyColumns.get(0), context );
}
else {
final String keyName = context.getBuildingOptions().getImplicitNamingStrategy()
.determineUniqueKeyName( new ImplicitUniqueKeyNameSource() {
@Override
public Identifier getTableName() {
return name;
}
@Override
public List<Identifier> getColumnNames() {
return keyColumns.stream()
.map( column -> column.getNameIdentifier( context ) )
.collect(toList());
}
@Override
public Identifier getUserProvidedIdentifier() {
return null;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return context;
}
} )
.render( context.getMetadataCollector().getDatabase().getDialect() );
final UniqueKey uniqueKey = getOrCreateUniqueKey( keyName );
for ( Column keyColumn : keyColumns ) {
uniqueKey.addColumn( keyColumn );
}
}
}
/**
* If there is one given column, mark it unique, otherwise
* create a {@link UniqueKey} comprising the given columns.
* @deprecated Use {@link #createUniqueKey(List, MetadataBuildingContext)}
*/
@Deprecated(since = "6.5", forRemoval = true)
public void createUniqueKey(List<Column> keyColumns) {
if ( keyColumns.size() == 1 ) {
keyColumns.get(0).setUnique( true );
@ -540,7 +624,7 @@ public class Table implements Serializable, ContributableDatabaseObject {
return uniqueKey;
}
public void createForeignKeys() {
public void createForeignKeys(MetadataBuildingContext context) {
}
public ForeignKey createForeignKey(String keyName, List<Column> keyColumns, String referencedEntityName, String keyDefinition) {
@ -699,12 +783,18 @@ public class Table implements Serializable, ContributableDatabaseObject {
this.comment = comment;
}
@Deprecated(since = "6.0")
/**
* @deprecated No longer used, should be removed
*/
@Deprecated(since = "6.0", forRemoval = true)
public Iterator<String> getCheckConstraintsIterator() {
return getCheckConstraints().iterator();
}
@Deprecated(since = "6.2")
/**
* @deprecated No longer used, should be removed
*/
@Deprecated(since = "6.2", forRemoval = true)
public List<String> getCheckConstraints() {
return checkConstraints.stream().map( CheckConstraint::getConstraint ).collect( toList() );
}

View File

@ -47,6 +47,7 @@ public class UniqueKey extends Constraint {
return columnOrderMap;
}
@Deprecated(forRemoval = true)
public String generatedConstraintNamePrefix() {
return "UK_";
}

View File

@ -7,7 +7,6 @@
package org.hibernate.mapping;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@ -142,7 +141,7 @@ public interface Value extends Serializable {
// called when this is the foreign key of a
// @OneToOne with a FK, or a @OneToMany with
// a join table
void createUniqueKey();
void createUniqueKey(MetadataBuildingContext context);
boolean isSimpleValue();

View File

@ -9,7 +9,6 @@ package org.hibernate.tool.schema.internal;
import java.util.Locale;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.Sequence;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
@ -33,6 +32,8 @@ import org.hibernate.type.descriptor.JdbcTypeNameMapper;
import org.jboss.logging.Logger;
import static org.hibernate.boot.model.naming.Identifier.toIdentifier;
/**
* Base implementation of {@link SchemaValidator}.
*
@ -139,7 +140,9 @@ public abstract class AbstractSchemaValidator implements SchemaValidator {
}
for ( Column column : table.getColumns() ) {
final ColumnInformation existingColumn = tableInformation.getColumn( Identifier.toIdentifier( column.getQuotedName() ) );
final ColumnInformation existingColumn =
//QUESTION: should this use metadata.getDatabase().toIdentifier( column.getQuotedName() )
tableInformation.getColumn( toIdentifier( column.getQuotedName() ) );
if ( existingColumn == null ) {
throw new SchemaManagementException(
String.format(

View File

@ -114,7 +114,12 @@ class ColumnDefinitions {
Dialect dialect,
SqlStringGenerationContext context) {
if ( column.isUnique() && !table.isPrimaryKey( column ) ) {
final String keyName = Constraint.generateName( "UK_", table, column);
String uniqueKeyName = column.getUniqueKeyName();
final String keyName = uniqueKeyName == null
// fallback in case the ImplicitNamingStrategy name was not assigned
// (we don't have access to the ImplicitNamingStrategy here)
? Constraint.generateName( "UK_", table, column )
: uniqueKeyName;
final UniqueKey uniqueKey = table.getOrCreateUniqueKey( keyName );
uniqueKey.addColumn( column );
definition.append( dialect.getUniqueDelegate().getColumnDefinitionUniquenessFragment( column, context ) );

View File

@ -144,7 +144,7 @@ public class UniqueConstraintDropTest {
if ( getDialect().supportsIfExistsBeforeConstraintName() ) {
regex += " if exists";
}
regex += " uk_.*";
regex += " uk.*";
if ( getDialect().supportsIfExistsAfterConstraintName() ) {
regex += " if exists";
}