下面列出了怎么用org.hibernate.mapping.ForeignKey的API类实例代码及写法,或者点击链接到github查看源代码。
public boolean matches(ForeignKey fk) {
if ( refTable.equalsIgnoreCase( fk.getReferencedTable().getName() ) ) {
if ( fk.getColumnSpan() == references.size() ) {
List fkRefs;
if ( fk.isReferenceToPrimaryKey() ) {
fkRefs = fk.getReferencedTable().getPrimaryKey().getColumns();
}
else {
fkRefs = fk.getReferencedColumns();
}
for ( int i = 0; i < fk.getColumnSpan(); i++ ) {
Column column = fk.getColumn( i );
Column ref = ( Column ) fkRefs.get( i );
if ( !hasReference( column, ref ) ) {
return false;
}
}
return true;
}
}
return false;
}
@Override
public String[] getSqlDropStrings(ForeignKey foreignKey, Metadata metadata) {
if ( !dialect.hasAlterTable() ) {
return NO_COMMANDS;
}
if ( !foreignKey.isCreationEnabled() ) {
return NO_COMMANDS;
}
if ( !foreignKey.isPhysicalConstraint() ) {
return NO_COMMANDS;
}
final JdbcEnvironment jdbcEnvironment = metadata.getDatabase().getJdbcEnvironment();
final String sourceTableName = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
foreignKey.getTable().getQualifiedTableName(),
dialect
);
return new String[] {
getSqlDropStrings( sourceTableName, foreignKey, dialect )
};
}
public void testForeignKeyCreation() {
PersistentClass classMapping = getCfg().getClassMapping("org.hibernate.test.propertyref.basic.Account");
Iterator foreignKeyIterator = classMapping.getTable().getForeignKeyIterator();
boolean found = false;
while ( foreignKeyIterator.hasNext() ) {
ForeignKey element = (ForeignKey) foreignKeyIterator.next();
if(element.getReferencedEntityName().equals(Person.class.getName() ) ) {
if(!element.isReferenceToPrimaryKey() ) {
List referencedColumns = element.getReferencedColumns();
Column column = (Column) referencedColumns.get(0);
if(column.getName().equals("person_userid") ) {
found = true; // extend test to include the columns
}
}
}
}
assertTrue("Property ref foreign key not found",found);
}
@Override
public String[] getSqlDropStrings(ForeignKey foreignKey, Metadata metadata) {
if (spannerDatabaseInfo == null) {
throw new IllegalStateException(
"Cannot determine which foreign keys to drop because spannerDatabaseInfo was null.");
}
if (foreignKeyExists(foreignKey)) {
return super.getSqlDropStrings(foreignKey, metadata);
} else {
return new String[0];
}
}
public ForeignKeyMetadata getForeignKeyMetadata(ForeignKey fk) {
for ( ForeignKeyMetadata existingFk : foreignKeys.values() ) {
if ( existingFk.matches( fk ) ) {
return existingFk;
}
}
return null;
}
private String getSqlDropStrings(String tableName, ForeignKey foreignKey, Dialect dialect) {
final StringBuilder buf = new StringBuilder( dialect.getAlterTableString( tableName ) );
buf.append( dialect.getDropForeignKeyString() );
if ( dialect.supportsIfExistsBeforeConstraintName() ) {
buf.append( "if exists " );
}
buf.append( dialect.quote( foreignKey.getName() ) );
if ( dialect.supportsIfExistsAfterConstraintName() ) {
buf.append( " if exists" );
}
return buf.toString();
}
protected void applyForeignKeys(
Table table,
TableInformation tableInformation,
Dialect dialect,
Metadata metadata,
Formatter formatter,
ExecutionOptions options,
GenerationTarget... targets) {
if ( dialect.hasAlterTable() ) {
final Exporter<ForeignKey> exporter = dialect.getForeignKeyExporter();
@SuppressWarnings("unchecked")
final Iterator<ForeignKey> fkItr = table.getForeignKeyIterator();
while ( fkItr.hasNext() ) {
final ForeignKey foreignKey = fkItr.next();
if ( foreignKey.isPhysicalConstraint() && foreignKey.isCreationEnabled() ) {
boolean existingForeignKeyFound = false;
if ( tableInformation != null ) {
existingForeignKeyFound = checkForExistingForeignKey(
foreignKey,
tableInformation
);
}
if ( !existingForeignKeyFound ) {
// todo : shouldn't we just drop+recreate if FK exists?
// this follows the existing code from legacy SchemaUpdate which just skipped
// in old SchemaUpdate code, this was the trigger to "create"
applySqlStrings(
false,
exporter.getSqlCreateStrings( foreignKey, metadata ),
formatter,
options,
targets
);
}
}
}
}
}
/**
* Check if the ForeignKey already exists. First check based on definition and if that is not matched check if a key
* with the exact same name exists. Keys with the same name are presumed to be functional equal.
*
* @param foreignKey - ForeignKey, new key to be created
* @param tableInformation - TableInformation, information of existing keys
* @return boolean, true if key already exists
*/
private boolean checkForExistingForeignKey(ForeignKey foreignKey, TableInformation tableInformation) {
if ( foreignKey.getName() == null || tableInformation == null ) {
return false;
}
final String referencingColumn = foreignKey.getColumn( 0 ).getName();
final String referencedTable = foreignKey.getReferencedTable().getName();
/*
* Find existing keys based on referencing column and referencedTable. "referencedColumnName" is not checked
* because that always is the primary key of the "referencedTable".
*/
Predicate<ColumnReferenceMapping> mappingPredicate = m -> {
String existingReferencingColumn = m.getReferencingColumnMetadata().getColumnIdentifier().getText();
String existingReferencedTable = m.getReferencedColumnMetadata().getContainingTableInformation().getName().getTableName().getCanonicalName();
return referencingColumn.equals( existingReferencingColumn ) && referencedTable.equals( existingReferencedTable );
};
Stream<ForeignKeyInformation> keyStream = StreamSupport.stream( tableInformation.getForeignKeys().spliterator(), false );
Stream<ColumnReferenceMapping> mappingStream = keyStream.flatMap( k -> StreamSupport.stream( k.getColumnReferenceMappings().spliterator(), false ) );
boolean found = mappingStream.anyMatch( mappingPredicate );
if ( found ) {
return true;
}
// And at the end just compare the name of the key. If a key with the same name exists we assume the function is
// also the same...
return tableInformation.getForeignKey( Identifier.toIdentifier( foreignKey.getName() ) ) != null;
}
private void applyConstraintDropping(
Namespace namespace,
Metadata metadata,
Formatter formatter,
ExecutionOptions options,
GenerationTarget... targets) {
final Dialect dialect = metadata.getDatabase().getJdbcEnvironment().getDialect();
if ( !dialect.dropConstraints() ) {
return;
}
for ( Table table : namespace.getTables() ) {
if ( !table.isPhysicalTable() ) {
continue;
}
if ( !schemaFilter.includeTable( table ) ) {
continue;
}
final Iterator fks = table.getForeignKeyIterator();
while ( fks.hasNext() ) {
final ForeignKey foreignKey = (ForeignKey) fks.next();
applySqlStrings(
dialect.getForeignKeyExporter().getSqlDropStrings( foreignKey, metadata ),
formatter,
options,
targets
);
}
}
}
private void secondPassCompileForeignKeys(MetadataBuildingContext buildingContext) {
int uniqueInteger = 0;
Set<ForeignKey> done = new HashSet<>();
for ( Table table : collectTableMappings() ) {
table.setUniqueInteger( uniqueInteger++ );
secondPassCompileForeignKeys( table, done, buildingContext );
}
}
protected void secondPassCompileForeignKeys(Table table, Set done) throws MappingException {
table.createForeignKeys();
Iterator iter = table.getForeignKeyIterator();
while ( iter.hasNext() ) {
ForeignKey fk = (ForeignKey) iter.next();
if ( !done.contains( fk ) ) {
done.add( fk );
final String referencedEntityName = fk.getReferencedEntityName();
if ( referencedEntityName == null ) {
throw new MappingException(
"An association from the table " +
fk.getTable().getName() +
" does not specify the referenced entity"
);
}
if ( log.isDebugEnabled() ) {
log.debug( "resolving reference to class: " + referencedEntityName );
}
PersistentClass referencedClass = (PersistentClass) classes.get( referencedEntityName );
if ( referencedClass == null ) {
throw new MappingException(
"An association from the table " +
fk.getTable().getName() +
" refers to an unmapped class: " +
referencedEntityName
);
}
if ( referencedClass.isJoinedSubclass() ) {
secondPassCompileForeignKeys( referencedClass.getSuperclass().getTable(), done );
}
fk.setReferencedTable( referencedClass.getTable() );
fk.alignColumns();
}
}
}
@Override
public Exporter<ForeignKey> getForeignKeyExporter() {
return this.spannerForeignKeyExporter;
}
private boolean foreignKeyExists(ForeignKey foreignKey) {
String table = foreignKey.getTable().getName();
return spannerDatabaseInfo.getAllTables().contains(table)
&& spannerDatabaseInfo.getImportedForeignKeys(table).contains(foreignKey.getName());
}
@Override
public String[] getSqlCreateStrings(ForeignKey foreignKey, Metadata metadata) {
if ( !dialect.hasAlterTable() ) {
return NO_COMMANDS;
}
if ( !foreignKey.isCreationEnabled() ) {
return NO_COMMANDS;
}
if ( !foreignKey.isPhysicalConstraint() ) {
return NO_COMMANDS;
}
final int numberOfColumns = foreignKey.getColumnSpan();
final String[] columnNames = new String[numberOfColumns];
final String[] targetColumnNames = new String[numberOfColumns];
final Iterator targetItr;
if ( foreignKey.isReferenceToPrimaryKey() ) {
if ( numberOfColumns != foreignKey.getReferencedTable().getPrimaryKey().getColumnSpan() ) {
throw new AssertionFailure(
String.format(
Locale.ENGLISH,
COLUMN_MISMATCH_MSG,
numberOfColumns,
foreignKey.getReferencedTable().getPrimaryKey().getColumnSpan(),
foreignKey.getName(),
foreignKey.getTable().getName(),
foreignKey.getReferencedTable().getName()
)
);
}
targetItr = foreignKey.getReferencedTable().getPrimaryKey().getColumnIterator();
}
else {
if ( numberOfColumns != foreignKey.getReferencedColumns().size() ) {
throw new AssertionFailure(
String.format(
Locale.ENGLISH,
COLUMN_MISMATCH_MSG,
numberOfColumns,
foreignKey.getReferencedColumns().size(),
foreignKey.getName(),
foreignKey.getTable().getName(),
foreignKey.getReferencedTable().getName()
)
);
}
targetItr = foreignKey.getReferencedColumns().iterator();
}
int i = 0;
final Iterator itr = foreignKey.getColumnIterator();
while ( itr.hasNext() ) {
columnNames[i] = ( (Column) itr.next() ).getQuotedName( dialect );
targetColumnNames[i] = ( (Column) targetItr.next() ).getQuotedName( dialect );
i++;
}
final JdbcEnvironment jdbcEnvironment = metadata.getDatabase().getJdbcEnvironment();
final String sourceTableName = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
foreignKey.getTable().getQualifiedTableName(),
dialect
);
final String targetTableName = jdbcEnvironment.getQualifiedObjectNameFormatter().format(
foreignKey.getReferencedTable().getQualifiedTableName(),
dialect
);
final StringBuilder buffer = new StringBuilder( dialect.getAlterTableString( sourceTableName ) )
.append(
foreignKey.getKeyDefinition() != null ?
dialect.getAddForeignKeyConstraintString(
foreignKey.getName(),
foreignKey.getKeyDefinition()
) :
dialect.getAddForeignKeyConstraintString(
foreignKey.getName(),
columnNames,
targetTableName,
targetColumnNames,
foreignKey.isReferenceToPrimaryKey()
)
);
if ( dialect.supportsCascadeDelete() ) {
if ( foreignKey.isCascadeDeleteEnabled() ) {
buffer.append( " on delete cascade" );
}
}
return new String[] { buffer.toString() };
}
public Exporter<ForeignKey> getForeignKeyExporter() {
return foreignKeyExporter;
}
protected void secondPassCompileForeignKeys(
final Table table,
Set<ForeignKey> done,
final MetadataBuildingContext buildingContext) throws MappingException {
table.createForeignKeys();
Iterator itr = table.getForeignKeyIterator();
while ( itr.hasNext() ) {
final ForeignKey fk = (ForeignKey) itr.next();
if ( !done.contains( fk ) ) {
done.add( fk );
final String referencedEntityName = fk.getReferencedEntityName();
if ( referencedEntityName == null ) {
throw new MappingException(
"An association from the table " +
fk.getTable().getName() +
" does not specify the referenced entity"
);
}
log.debugf( "Resolving reference to class: %s", referencedEntityName );
final PersistentClass referencedClass = getEntityBinding( referencedEntityName );
if ( referencedClass == null ) {
throw new MappingException(
"An association from the table " +
fk.getTable().getName() +
" refers to an unmapped class: " +
referencedEntityName
);
}
if ( referencedClass.isJoinedSubclass() ) {
secondPassCompileForeignKeys( referencedClass.getSuperclass().getTable(), done, buildingContext );
}
fk.setReferencedTable( referencedClass.getTable() );
Identifier nameIdentifier;
ImplicitForeignKeyNameSource foreignKeyNameSource = new ImplicitForeignKeyNameSource() {
final List<Identifier> columnNames = extractColumnNames( fk.getColumns() );
List<Identifier> referencedColumnNames = null;
@Override
public Identifier getTableName() {
return table.getNameIdentifier();
}
@Override
public List<Identifier> getColumnNames() {
return columnNames;
}
@Override
public Identifier getReferencedTableName() {
return fk.getReferencedTable().getNameIdentifier();
}
@Override
public List<Identifier> getReferencedColumnNames() {
if ( referencedColumnNames == null ) {
referencedColumnNames = extractColumnNames( fk.getReferencedColumns() );
}
return referencedColumnNames;
}
@Override
public Identifier getUserProvidedIdentifier() {
return fk.getName() != null ? Identifier.toIdentifier( fk.getName() ) : null;
}
@Override
public MetadataBuildingContext getBuildingContext() {
return buildingContext;
}
};
nameIdentifier = getMetadataBuildingOptions().getImplicitNamingStrategy().determineForeignKeyName(foreignKeyNameSource);
fk.setName( nameIdentifier.render( getDatabase().getJdbcEnvironment().getDialect() ) );
fk.alignColumns();
}
}
}
@Override
public Exporter<ForeignKey> getForeignKeyExporter() {
return getInstance().getForeignKeyExporter();
}