light refactoring
This commit is contained in:
parent
3ba90c004c
commit
13f4c8c285
|
@ -1931,45 +1931,8 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
|
|
||||||
Identifier nameIdentifier;
|
Identifier nameIdentifier;
|
||||||
|
|
||||||
ImplicitForeignKeyNameSource foreignKeyNameSource = new ImplicitForeignKeyNameSource() {
|
nameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy()
|
||||||
final List<Identifier> columnNames = extractColumnNames( foreignKey.getColumns() );
|
.determineForeignKeyName( new ForeignKeyNameSource( foreignKey, table, buildingContext ) );
|
||||||
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);
|
|
||||||
|
|
||||||
foreignKey.setName( nameIdentifier.render( getDatabase().getJdbcEnvironment().getDialect() ) );
|
foreignKey.setName( nameIdentifier.render( getDatabase().getJdbcEnvironment().getDialect() ) );
|
||||||
|
|
||||||
|
@ -2063,93 +2026,53 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
//column equals and hashcode is based on column name
|
//column equals and hashcode is based on column name
|
||||||
}
|
}
|
||||||
catch ( MappingException e ) {
|
catch ( MappingException e ) {
|
||||||
// If at least 1 columnName does exist, 'columns' will contain a mix of Columns and nulls. In order
|
// If at least 1 columnName does exist, 'columns' will contain a mix of Columns and nulls.
|
||||||
// to exhaustively report all of the unbound columns at once, w/o an NPE in
|
// 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.
|
// Constraint#generateName's array sorting, simply create a fake Column.
|
||||||
columns[index] = new Column( logicalColumnName );
|
columns[index] = new Column( logicalColumnName );
|
||||||
unboundNoLogical.add( columns[index] );
|
unboundNoLogical.add( columns[index] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final String originalKeyName = keyName;
|
createIndexOrUniqueKey( table, keyName, nameExplicit, columnNames, orderings, unique, buildingContext, columns, unbound );
|
||||||
|
|
||||||
if ( unique ) {
|
if ( unbound.size() > 0 || unboundNoLogical.size() > 0 ) {
|
||||||
final Identifier keyNameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy().determineUniqueKeyName(
|
throwUnableToCreateConstraint( table, columnNames, unique, unbound, unboundNoLogical );
|
||||||
new ImplicitUniqueKeyNameSource() {
|
}
|
||||||
@Override
|
|
||||||
public MetadataBuildingContext getBuildingContext() {
|
|
||||||
return buildingContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void createIndexOrUniqueKey(
|
||||||
public Identifier getTableName() {
|
Table table,
|
||||||
return table.getNameIdentifier();
|
String originalKeyName,
|
||||||
}
|
boolean nameExplicit,
|
||||||
|
String[] columnNames,
|
||||||
private List<Identifier> columnNameIdentifiers;
|
String[] orderings,
|
||||||
|
boolean unique,
|
||||||
@Override
|
MetadataBuildingContext buildingContext,
|
||||||
public List<Identifier> getColumnNames() {
|
Column[] columns,
|
||||||
// be lazy about building these
|
Set<Column> unbound) {
|
||||||
if ( columnNameIdentifiers == null ) {
|
if (unique) {
|
||||||
columnNameIdentifiers = toIdentifiers( columnNames );
|
createUniqueKey( table, originalKeyName, nameExplicit, columnNames, orderings, buildingContext, columns, unbound );
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final Identifier keyNameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy().determineIndexName(
|
createIndex( table, originalKeyName, columnNames, orderings, buildingContext, columns, unbound );
|
||||||
new ImplicitIndexNameSource() {
|
}
|
||||||
@Override
|
|
||||||
public MetadataBuildingContext getBuildingContext() {
|
|
||||||
return buildingContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void createIndex(
|
||||||
public Identifier getTableName() {
|
Table table,
|
||||||
return table.getNameIdentifier();
|
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;
|
final Index index = table.getOrCreateIndex( keyName );
|
||||||
|
for (int i = 0; i < columns.length; i++ ) {
|
||||||
@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 );
|
|
||||||
for ( int i = 0; i < columns.length; i++ ) {
|
|
||||||
Column column = columns[i];
|
Column column = columns[i];
|
||||||
String order = orderings != null ? orderings[i] : null;
|
String order = orderings != null ? orderings[i] : null;
|
||||||
if ( table.containsColumn( column ) ) {
|
if ( table.containsColumn( column ) ) {
|
||||||
|
@ -2159,29 +2082,58 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( unbound.size() > 0 || unboundNoLogical.size() > 0 ) {
|
private void createUniqueKey(
|
||||||
StringBuilder sb = new StringBuilder( "Unable to create " );
|
Table table,
|
||||||
if ( unique ) {
|
String originalKeyName,
|
||||||
sb.append( "unique key constraint (" );
|
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) {
|
||||||
|
message.append( "unique key constraint (" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sb.append( "index (" );
|
message.append( "index (" );
|
||||||
}
|
}
|
||||||
for ( String columnName : columnNames ) {
|
for ( String columnName : columnNames) {
|
||||||
sb.append( columnName ).append( ", " );
|
message.append( columnName ).append( ", " );
|
||||||
}
|
}
|
||||||
sb.setLength( sb.length() - 2 );
|
message.setLength( message.length() - 2 );
|
||||||
sb.append( ") on table '" ).append( table.getName() ).append( "' since the column " );
|
message.append( ") on table '" ).append( table.getName() ).append( "' since the column " );
|
||||||
for ( Column column : unbound ) {
|
for ( Column column : unbound) {
|
||||||
sb.append("'").append( column.getName() ).append( "', " );
|
message.append("'").append( column.getName() ).append( "', " );
|
||||||
}
|
}
|
||||||
for ( Column column : unboundNoLogical ) {
|
for ( Column column : unboundNoLogical) {
|
||||||
sb.append("'").append( column.getName() ).append( "', " );
|
message.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.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) {
|
private void processJPAIndexHolders(MetadataBuildingContext buildingContext) {
|
||||||
|
@ -2379,4 +2331,93 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
||||||
}
|
}
|
||||||
return identifier.render( dialect );
|
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,
|
SimpleValue value,
|
||||||
boolean unique) {
|
boolean unique) {
|
||||||
if ( hasMappedBy() ) {
|
if ( hasMappedBy() ) {
|
||||||
final Property property = targetEntity.getRecursiveProperty( mappedBy );
|
bindUnownedManyToManyInverseForeignKey( targetEntity, joinColumns, value );
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
else {
|
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(
|
createSyntheticPropertyReference(
|
||||||
joinColumns,
|
joinColumns,
|
||||||
targetEntity,
|
targetEntity,
|
||||||
|
@ -2677,6 +2671,27 @@ public abstract class CollectionBinder {
|
||||||
buildingContext
|
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) {
|
private static List<Selectable> mappedByColumns(PersistentClass referencedEntity, Property property) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.hibernate.internal.util.StringHelper;
|
||||||
*/
|
*/
|
||||||
public class UniqueKey extends Constraint {
|
public class UniqueKey extends Constraint {
|
||||||
private final Map<Column, String> columnOrderMap = new HashMap<>();
|
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")
|
@Override @Deprecated(since="6.2")
|
||||||
public String sqlConstraintString(
|
public String sqlConstraintString(
|
||||||
|
|
Loading…
Reference in New Issue