light refactoring
This commit is contained in:
parent
3ba90c004c
commit
13f4c8c285
|
@ -1931,45 +1931,8 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
|||
|
||||
Identifier nameIdentifier;
|
||||
|
||||
ImplicitForeignKeyNameSource foreignKeyNameSource = new ImplicitForeignKeyNameSource() {
|
||||
final List<Identifier> columnNames = extractColumnNames( foreignKey.getColumns() );
|
||||
List<Identifier> 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;
|
||||
}
|
||||
};
|
||||
|
||||
nameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy().determineForeignKeyName(foreignKeyNameSource);
|
||||
nameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy()
|
||||
.determineForeignKeyName( new ForeignKeyNameSource( foreignKey, table, buildingContext ) );
|
||||
|
||||
foreignKey.setName( nameIdentifier.render( getDatabase().getJdbcEnvironment().getDialect() ) );
|
||||
|
||||
|
@ -2063,92 +2026,52 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
|||
//column equals and hashcode is based on column name
|
||||
}
|
||||
catch ( MappingException e ) {
|
||||
// If at least 1 columnName does exist, 'columns' will contain a mix of Columns and nulls. In order
|
||||
// to exhaustively report all of the unbound columns at once, w/o an NPE in
|
||||
// If at least 1 columnName does exist, 'columns' will contain a mix of Columns and nulls.
|
||||
// In order to exhaustively report all the unbound columns at once, w/o an NPE in
|
||||
// Constraint#generateName's array sorting, simply create a fake Column.
|
||||
columns[index] = new Column( logicalColumnName );
|
||||
unboundNoLogical.add( columns[index] );
|
||||
}
|
||||
}
|
||||
|
||||
final String originalKeyName = keyName;
|
||||
createIndexOrUniqueKey( table, keyName, nameExplicit, columnNames, orderings, unique, buildingContext, columns, unbound );
|
||||
|
||||
if ( unbound.size() > 0 || unboundNoLogical.size() > 0 ) {
|
||||
throwUnableToCreateConstraint( table, columnNames, unique, unbound, unboundNoLogical );
|
||||
}
|
||||
}
|
||||
|
||||
private void createIndexOrUniqueKey(
|
||||
Table table,
|
||||
String originalKeyName,
|
||||
boolean nameExplicit,
|
||||
String[] columnNames,
|
||||
String[] orderings,
|
||||
boolean unique,
|
||||
MetadataBuildingContext buildingContext,
|
||||
Column[] columns,
|
||||
Set<Column> unbound) {
|
||||
if (unique) {
|
||||
final Identifier keyNameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy().determineUniqueKeyName(
|
||||
new ImplicitUniqueKeyNameSource() {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
);
|
||||
keyName = keyNameIdentifier.render( getDatabase().getJdbcEnvironment().getDialect() );
|
||||
|
||||
UniqueKey uk = table.getOrCreateUniqueKey( keyName );
|
||||
uk.setNameExplicit( nameExplicit );
|
||||
for ( int i = 0; i < columns.length; i++ ) {
|
||||
Column column = columns[i];
|
||||
String order = orderings != null ? orderings[i] : null;
|
||||
if ( table.containsColumn( column ) ) {
|
||||
uk.addColumn( column, order );
|
||||
unbound.remove( column );
|
||||
}
|
||||
}
|
||||
createUniqueKey( table, originalKeyName, nameExplicit, columnNames, orderings, buildingContext, columns, unbound );
|
||||
}
|
||||
else {
|
||||
final Identifier keyNameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy().determineIndexName(
|
||||
new ImplicitIndexNameSource() {
|
||||
@Override
|
||||
public MetadataBuildingContext getBuildingContext() {
|
||||
return buildingContext;
|
||||
createIndex( table, originalKeyName, columnNames, orderings, buildingContext, columns, unbound );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTableName() {
|
||||
return table.getNameIdentifier();
|
||||
}
|
||||
private void createIndex(
|
||||
Table table,
|
||||
String originalKeyName,
|
||||
String[] columnNames,
|
||||
String[] orderings,
|
||||
MetadataBuildingContext buildingContext,
|
||||
Column[] columns,
|
||||
Set<Column> unbound) {
|
||||
final Identifier keyNameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy()
|
||||
.determineIndexName( new IndexOrUniqueKeyNameSource( buildingContext, table, columnNames, originalKeyName ) );
|
||||
final String keyName = keyNameIdentifier.render( getDatabase().getJdbcEnvironment().getDialect() );
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
);
|
||||
keyName = keyNameIdentifier.render( getDatabase().getJdbcEnvironment().getDialect() );
|
||||
|
||||
Index index = table.getOrCreateIndex( keyName );
|
||||
final Index index = table.getOrCreateIndex( keyName );
|
||||
for (int i = 0; i < columns.length; i++ ) {
|
||||
Column column = columns[i];
|
||||
String order = orderings != null ? orderings[i] : null;
|
||||
|
@ -2159,29 +2082,58 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
|||
}
|
||||
}
|
||||
|
||||
if ( unbound.size() > 0 || unboundNoLogical.size() > 0 ) {
|
||||
StringBuilder sb = new StringBuilder( "Unable to create " );
|
||||
private void createUniqueKey(
|
||||
Table table,
|
||||
String originalKeyName,
|
||||
boolean nameExplicit,
|
||||
String[] columnNames,
|
||||
String[] orderings,
|
||||
MetadataBuildingContext buildingContext,
|
||||
Column[] columns,
|
||||
Set<Column> unbound) {
|
||||
final Identifier keyNameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy()
|
||||
.determineUniqueKeyName( new IndexOrUniqueKeyNameSource( buildingContext, table, columnNames, originalKeyName ) );
|
||||
final String keyName = keyNameIdentifier.render( getDatabase().getJdbcEnvironment().getDialect() );
|
||||
|
||||
final UniqueKey uk = table.getOrCreateUniqueKey( keyName );
|
||||
uk.setNameExplicit(nameExplicit);
|
||||
for (int i = 0; i < columns.length; i++ ) {
|
||||
Column column = columns[i];
|
||||
String order = orderings != null ? orderings[i] : null;
|
||||
if ( table.containsColumn( column ) ) {
|
||||
uk.addColumn( column, order );
|
||||
unbound.remove( column );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void throwUnableToCreateConstraint(
|
||||
Table table,
|
||||
String[] columnNames,
|
||||
boolean unique,
|
||||
Set<Column> unbound,
|
||||
Set<Column> unboundNoLogical) {
|
||||
final StringBuilder message = new StringBuilder( "Unable to create " );
|
||||
if (unique) {
|
||||
sb.append( "unique key constraint (" );
|
||||
message.append( "unique key constraint (" );
|
||||
}
|
||||
else {
|
||||
sb.append( "index (" );
|
||||
message.append( "index (" );
|
||||
}
|
||||
for ( String columnName : columnNames) {
|
||||
sb.append( columnName ).append( ", " );
|
||||
message.append( columnName ).append( ", " );
|
||||
}
|
||||
sb.setLength( sb.length() - 2 );
|
||||
sb.append( ") on table '" ).append( table.getName() ).append( "' since the column " );
|
||||
message.setLength( message.length() - 2 );
|
||||
message.append( ") on table '" ).append( table.getName() ).append( "' since the column " );
|
||||
for ( Column column : unbound) {
|
||||
sb.append("'").append( column.getName() ).append( "', " );
|
||||
message.append("'").append( column.getName() ).append( "', " );
|
||||
}
|
||||
for ( Column column : unboundNoLogical) {
|
||||
sb.append("'").append( column.getName() ).append( "', " );
|
||||
}
|
||||
sb.setLength( sb.length() - 2 );
|
||||
sb.append( " was not found (specify the correct column name, which depends on the naming strategy, and may not be the same as the entity property name)" );
|
||||
throw new AnnotationException( sb.toString() );
|
||||
message.append("'").append( column.getName() ).append( "', " );
|
||||
}
|
||||
message.setLength( message.length() - 2 );
|
||||
message.append( " was not found (specify the correct column name, which depends on the naming strategy, and may not be the same as the entity property name)" );
|
||||
throw new AnnotationException( message.toString() );
|
||||
}
|
||||
|
||||
private void processJPAIndexHolders(MetadataBuildingContext buildingContext) {
|
||||
|
@ -2379,4 +2331,93 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
|||
}
|
||||
return identifier.render( dialect );
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2638,24 +2638,18 @@ public abstract class CollectionBinder {
|
|||
SimpleValue value,
|
||||
boolean unique) {
|
||||
if ( hasMappedBy() ) {
|
||||
final Property property = targetEntity.getRecursiveProperty( mappedBy );
|
||||
final List<Selectable> mappedByColumns = mappedByColumns( targetEntity, property );
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0);
|
||||
for ( Selectable selectable: mappedByColumns ) {
|
||||
firstColumn.linkValueUsingAColumnCopy( (Column) selectable, value );
|
||||
}
|
||||
final String referencedPropertyName = buildingContext.getMetadataCollector()
|
||||
.getPropertyReferencedAssociation( targetEntity.getEntityName(), mappedBy );
|
||||
if ( referencedPropertyName != null ) {
|
||||
//TODO always a many to one?
|
||||
( (ManyToOne) value ).setReferencedPropertyName( referencedPropertyName );
|
||||
buildingContext.getMetadataCollector()
|
||||
.addUniquePropertyReference( targetEntity.getEntityName(), referencedPropertyName );
|
||||
}
|
||||
( (ManyToOne) value ).setReferenceToPrimaryKey( referencedPropertyName == null );
|
||||
value.createForeignKey();
|
||||
bindUnownedManyToManyInverseForeignKey( targetEntity, joinColumns, value );
|
||||
}
|
||||
else {
|
||||
bindOwnedManyToManyForeignKeyMappedBy( targetEntity, joinColumns, value, unique );
|
||||
}
|
||||
}
|
||||
|
||||
private void bindOwnedManyToManyForeignKeyMappedBy(
|
||||
PersistentClass targetEntity,
|
||||
AnnotatedJoinColumns joinColumns,
|
||||
SimpleValue value,
|
||||
boolean unique) { // true when it's actually a logical @OneToMany
|
||||
createSyntheticPropertyReference(
|
||||
joinColumns,
|
||||
targetEntity,
|
||||
|
@ -2677,6 +2671,27 @@ public abstract class CollectionBinder {
|
|||
buildingContext
|
||||
);
|
||||
}
|
||||
|
||||
private void bindUnownedManyToManyInverseForeignKey(
|
||||
PersistentClass targetEntity,
|
||||
AnnotatedJoinColumns joinColumns,
|
||||
SimpleValue value) {
|
||||
final Property property = targetEntity.getRecursiveProperty( mappedBy );
|
||||
final List<Selectable> mappedByColumns = mappedByColumns(targetEntity, property );
|
||||
final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0);
|
||||
for ( Selectable selectable: mappedByColumns ) {
|
||||
firstColumn.linkValueUsingAColumnCopy( (Column) selectable, value);
|
||||
}
|
||||
final String referencedPropertyName = buildingContext.getMetadataCollector()
|
||||
.getPropertyReferencedAssociation( targetEntity.getEntityName(), mappedBy );
|
||||
if ( referencedPropertyName != null ) {
|
||||
//TODO always a many to one?
|
||||
( (ManyToOne) value).setReferencedPropertyName( referencedPropertyName );
|
||||
buildingContext.getMetadataCollector()
|
||||
.addUniquePropertyReference( targetEntity.getEntityName(), referencedPropertyName );
|
||||
}
|
||||
( (ManyToOne) value).setReferenceToPrimaryKey( referencedPropertyName == null );
|
||||
value.createForeignKey();
|
||||
}
|
||||
|
||||
private static List<Selectable> mappedByColumns(PersistentClass referencedEntity, Property property) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.hibernate.internal.util.StringHelper;
|
|||
*/
|
||||
public class UniqueKey extends Constraint {
|
||||
private final Map<Column, String> columnOrderMap = new HashMap<>();
|
||||
private boolean nameExplicit;
|
||||
private boolean nameExplicit; // true when the constraint name was explicitly specified by @UniqueConstraint annotation
|
||||
|
||||
@Override @Deprecated(since="6.2")
|
||||
public String sqlConstraintString(
|
||||
|
|
Loading…
Reference in New Issue