All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hibernate.metamodel.relational.ForeignKey Maven / Gradle / Ivy

There is a newer version: 7.0.0.Alpha1
Show newest version
/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * Copyright (c) 2010 by Red Hat Inc and/or its affiliates or by
 * third-party contributors as indicated by either @author tags or express
 * copyright attribution statements applied by the authors.  All
 * third-party contributions are distributed under license by Red Hat Inc.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.hibernate.metamodel.relational;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;

import org.jboss.logging.Logger;

/**
 * Models the notion of a foreign key.
 * 

* Note that this need not mean a physical foreign key; we just mean a relationship between 2 table * specifications. * * @author Gavin King * @author Steve Ebersole */ public class ForeignKey extends AbstractConstraint implements Constraint, Exportable { private static final Logger LOG = Logger.getLogger( ForeignKey.class ); private static final String ON_DELETE = " on delete "; private static final String ON_UPDATE = " on update "; private final TableSpecification targetTable; private List targetColumns; private ReferentialAction deleteRule = ReferentialAction.NO_ACTION; private ReferentialAction updateRule = ReferentialAction.NO_ACTION; protected ForeignKey(TableSpecification sourceTable, TableSpecification targetTable, String name) { super( sourceTable, name ); this.targetTable = targetTable; } protected ForeignKey(TableSpecification sourceTable, TableSpecification targetTable) { this( sourceTable, targetTable, null ); } public TableSpecification getSourceTable() { return getTable(); } public TableSpecification getTargetTable() { return targetTable; } public Iterable getSourceColumns() { return getColumns(); } public Iterable getTargetColumns() { return targetColumns == null ? getTargetTable().getPrimaryKey().getColumns() : targetColumns; } @Override public void addColumn(Column column) { addColumnMapping( column, null ); } public void addColumnMapping(Column sourceColumn, Column targetColumn) { if ( targetColumn == null ) { if ( targetColumns != null ) { LOG.debugf( "Attempt to map column [%s] to no target column after explicit target column(s) named for FK [name=%s]", sourceColumn.toLoggableString(), getName() ); } } else { checkTargetTable( targetColumn ); if ( targetColumns == null ) { if (!internalColumnAccess().isEmpty()) { LOG.debugf( "Value mapping mismatch as part of FK [table=%s, name=%s] while adding source column [%s]", getTable().toLoggableString(), getName(), sourceColumn.toLoggableString() ); } targetColumns = new ArrayList(); } targetColumns.add( targetColumn ); } internalAddColumn( sourceColumn ); } private void checkTargetTable(Column targetColumn) { if ( targetColumn.getTable() != getTargetTable() ) { throw new AssertionFailure( String.format( "Unable to add column to constraint; tables [%s, %s] did not match", targetColumn.getTable().toLoggableString(), getTargetTable().toLoggableString() ) ); } } @Override public String getExportIdentifier() { return getSourceTable().getLoggableValueQualifier() + ".FK-" + getName(); } public ReferentialAction getDeleteRule() { return deleteRule; } public void setDeleteRule(ReferentialAction deleteRule) { this.deleteRule = deleteRule; } public ReferentialAction getUpdateRule() { return updateRule; } public void setUpdateRule(ReferentialAction updateRule) { this.updateRule = updateRule; } @Override public String[] sqlDropStrings(Dialect dialect) { return new String[] { "alter table " + getTable().getQualifiedName( dialect ) + dialect.getDropForeignKeyString() + getName() }; } public String sqlConstraintStringInAlterTable(Dialect dialect) { String[] columnNames = new String[ getColumnSpan() ]; String[] targetColumnNames = new String[ getColumnSpan() ]; int i=0; Iterator itTargetColumn = getTargetColumns().iterator(); for ( Column column : getColumns() ) { if ( ! itTargetColumn.hasNext() ) { throw new MappingException( "More constraint columns that foreign key target columns." ); } columnNames[i] = column.getColumnName().encloseInQuotesIfQuoted( dialect ); targetColumnNames[i] = ( itTargetColumn.next() ).getColumnName().encloseInQuotesIfQuoted( dialect ); i++; } if ( itTargetColumn.hasNext() ) { throw new MappingException( "More foreign key target columns than constraint columns." ); } StringBuilder sb = new StringBuilder( dialect.getAddForeignKeyConstraintString( getName(), columnNames, targetTable.getQualifiedName( dialect ), targetColumnNames, this.targetColumns == null ) ); // TODO: If a dialect does not support cascade-delete, can it support other actions? (HHH-6428) // For now, assume not. if ( dialect.supportsCascadeDelete() ) { if ( deleteRule != ReferentialAction.NO_ACTION ) { sb.append( ON_DELETE ).append( deleteRule.getActionString() ); } if ( updateRule != ReferentialAction.NO_ACTION ) { sb.append( ON_UPDATE ).append( updateRule.getActionString() ); } } return sb.toString(); } public static enum ReferentialAction { NO_ACTION( "no action" ), CASCADE( "cascade" ), SET_NULL( "set null" ), SET_DEFAULT( "set default" ), RESTRICT( "restrict" ); private final String actionString; private ReferentialAction(String actionString) { this.actionString = actionString; } public String getActionString() { return actionString; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy