HHH-16985 use ImplicitNamingStrategy in a much more disciplined way
for generating constraint names
This commit is contained in:
parent
9c12ea8b11
commit
da9d2c2bf7
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -350,7 +350,7 @@ public class BinderHelper {
|
|||
else {
|
||||
ownerEntity.addProperty( result );
|
||||
}
|
||||
embeddedComponent.createUniqueKey(); //make it unique
|
||||
embeddedComponent.createUniqueKey( context ); //make it unique
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -568,7 +568,7 @@ public class TableBinder {
|
|||
}
|
||||
value.createForeignKey( referencedEntity, joinColumns );
|
||||
if ( unique ) {
|
||||
value.createUniqueKey();
|
||||
value.createUniqueKey( buildingContext );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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( "`" );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -139,7 +139,7 @@ public class ExportableColumn extends Column {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void createUniqueKey() {
|
||||
public void createUniqueKey(MetadataBuildingContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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() ) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,8 @@ public class PrimaryKey extends Constraint {
|
|||
}
|
||||
return buf.append(')').toString();
|
||||
}
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public String generatedConstraintNamePrefix() {
|
||||
return "PK_";
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ public class UniqueKey extends Constraint {
|
|||
return columnOrderMap;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public String generatedConstraintNamePrefix() {
|
||||
return "UK_";
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 ) );
|
||||
|
|
|
@ -144,7 +144,7 @@ public class UniqueConstraintDropTest {
|
|||
if ( getDialect().supportsIfExistsBeforeConstraintName() ) {
|
||||
regex += " if exists";
|
||||
}
|
||||
regex += " uk_.*";
|
||||
regex += " uk.*";
|
||||
if ( getDialect().supportsIfExistsAfterConstraintName() ) {
|
||||
regex += " if exists";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue