From 695044128842ed08a7e2c74f77df76cc580efeae Mon Sep 17 00:00:00 2001 From: gjevardat Date: Mon, 5 Jun 2023 11:02:32 +0200 Subject: [PATCH] OPENJPA-2814 fix mem leak --- .../openjpa/jdbc/schema/Constraint.java | 96 +++--- .../openjpa/jdbc/schema/ForeignKey.java | 277 ++++++++---------- 2 files changed, 176 insertions(+), 197 deletions(-) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Constraint.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Constraint.java index f7f9fdb28..5968e54d7 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Constraint.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/Constraint.java @@ -14,7 +14,7 @@ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations - * under the License. + * under the License. */ package org.apache.openjpa.jdbc.schema; @@ -27,8 +27,10 @@ import org.apache.openjpa.jdbc.identifier.QualifiedDBIdentifier; * * @author Abe White */ -public abstract class Constraint extends ReferenceCounter { - private static final long serialVersionUID = 1L; +@SuppressWarnings("serial") +public abstract class Constraint + extends ReferenceCounter { + private DBIdentifier _name = DBIdentifier.NULL; private QualifiedDBIdentifier _fullPath = null; private Table _table = null; @@ -50,7 +52,6 @@ public abstract class Constraint extends ReferenceCounter { * @param table the local table of the constraint * @deprecated */ - @Deprecated Constraint(String name, Table table) { this(DBIdentifier.newConstant(name), table); } @@ -83,7 +84,6 @@ public abstract class Constraint extends ReferenceCounter { * Return the column's table name. * @deprecated */ - @Deprecated public String getTableName() { return getTableIdentifier().getName(); } @@ -97,7 +97,6 @@ public abstract class Constraint extends ReferenceCounter { * columns whose table object is not set. * @deprecated */ - @Deprecated public void setTableName(String name) { setTableIdentifier(DBIdentifier.newTable(name)); } @@ -109,12 +108,11 @@ public abstract class Constraint extends ReferenceCounter { _fullPath = null; } - + /** * Return the column table's schema name. * @deprecated */ - @Deprecated public String getSchemaName() { return getSchemaIdentifier().getName(); } @@ -128,7 +126,6 @@ public abstract class Constraint extends ReferenceCounter { * columns whose table object is not set. * @deprecated */ - @Deprecated public void setSchemaName(String schema) { setSchemaIdentifier(DBIdentifier.newSchema(schema)); } @@ -143,7 +140,6 @@ public abstract class Constraint extends ReferenceCounter { * Return the column's name. * @deprecated */ - @Deprecated public String getColumnName() { return getColumnIdentifier().getName(); } @@ -157,7 +153,6 @@ public abstract class Constraint extends ReferenceCounter { * columns whose table object is not set. * @deprecated */ - @Deprecated public void setColumnName(String name) { setColumnIdentifier(DBIdentifier.newColumn(name)); } @@ -172,11 +167,10 @@ public abstract class Constraint extends ReferenceCounter { * Return the name of the constraint. * @deprecated */ - @Deprecated public String getName() { return getIdentifier().getName(); } - + public DBIdentifier getIdentifier() { return _name == null ? DBIdentifier.NULL : _name; } @@ -187,7 +181,6 @@ public abstract class Constraint extends ReferenceCounter { * constraint already belongs to a table. * @deprecated */ - @Deprecated public void setName(String name) { setIdentifier(DBIdentifier.newConstraint(name)); } @@ -203,7 +196,6 @@ public abstract class Constraint extends ReferenceCounter { * Return the full name of the constraint. * @deprecated */ - @Deprecated public String getFullName() { return getFullIdentifier().getName(); } @@ -218,8 +210,8 @@ public abstract class Constraint extends ReferenceCounter { public DBIdentifier getFullIdentifier() { return getQualifiedPath().getIdentifier(); } - - + + /** * Return whether this constraint is a logical constraint only; i.e. * if it does not exist in the database. @@ -240,7 +232,6 @@ public abstract class Constraint extends ReferenceCounter { _deferred = deferred; } - @Override public String toString() { if (!getIdentifier().isNull()) return getIdentifier().getName(); @@ -250,31 +241,48 @@ public abstract class Constraint extends ReferenceCounter { return "<" + name.toLowerCase() + ">"; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((_columnName == null) ? 0 : _columnName.hashCode()); + result = prime * result + ((_name == null) ? 0 : _name.hashCode()); + result = prime * result + ((_schemaName == null) ? 0 : _schemaName.hashCode()); + result = prime * result + ((_tableName == null) ? 0 : _tableName.hashCode()); + return result; + } - Constraint that = (Constraint) o; - - if (_deferred != that._deferred) return false; - if (_name != null ? !_name.equals(that._name) : that._name != null) return false; - if (_fullPath != null ? !_fullPath.equals(that._fullPath) : that._fullPath != null) return false; - if (_table != null ? !_table.equals(that._table) : that._table != null) return false; - if (_tableName != null ? !_tableName.equals(that._tableName) : that._tableName != null) return false; - if (_schemaName != null ? !_schemaName.equals(that._schemaName) : that._schemaName != null) return false; - return _columnName != null ? _columnName.equals(that._columnName) : that._columnName == null; - } - - @Override - public int hashCode() { - int result = _name != null ? _name.hashCode() : 0; - result = 31 * result + (_fullPath != null ? _fullPath.hashCode() : 0); - result = 31 * result + (_table != null ? _table.hashCode() : 0); - result = 31 * result + (_tableName != null ? _tableName.hashCode() : 0); - result = 31 * result + (_schemaName != null ? _schemaName.hashCode() : 0); - result = 31 * result + (_columnName != null ? _columnName.hashCode() : 0); - result = 31 * result + (_deferred ? 1 : 0); - return result; - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Constraint other = (Constraint) obj; + if (_columnName == null) { + if (other._columnName != null) + return false; + } else if (!_columnName.equals(other._columnName)) + return false; + if (_name == null) { + if (other._name != null) + return false; + } else if (!_name.equals(other._name)) + return false; + if (_schemaName == null) { + if (other._schemaName != null) + return false; + } else if (!_schemaName.equals(other._schemaName)) + return false; + if (_tableName == null) { + if (other._tableName != null) + return false; + } else if (!_tableName.equals(other._tableName)) + return false; + return true; + } + + } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java index 70668e1a7..2a339a67b 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/ForeignKey.java @@ -14,7 +14,7 @@ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations - * under the License. + * under the License. */ package org.apache.openjpa.jdbc.schema; @@ -40,8 +40,9 @@ import org.apache.openjpa.util.InvalidStateException; * * @author Abe White */ -public class ForeignKey extends Constraint { - private static final long serialVersionUID = 1L; +@SuppressWarnings("serial") +public class ForeignKey + extends Constraint { /** * Logical foreign key; links columns, but does not perform any action @@ -72,7 +73,7 @@ public class ForeignKey extends Constraint { */ public static final int ACTION_DEFAULT = 5; - private static final Localizer _loc = + private static final Localizer _loc = Localizer.forPackage(ForeignKey.class); private DBIdentifier _pkTableName = DBIdentifier.NULL; @@ -162,7 +163,6 @@ public class ForeignKey extends Constraint { * @param table the local table of the foreign key * @deprecated */ - @Deprecated public ForeignKey(String name, Table table) { super(name, table); } @@ -171,7 +171,6 @@ public class ForeignKey extends Constraint { super(name, table); } - @Override public boolean isLogical() { return _delAction == ACTION_NONE; } @@ -183,23 +182,23 @@ public class ForeignKey extends Constraint { */ public boolean isPrimaryKeyAutoAssigned() { if (_autoAssign != null) - return _autoAssign; + return _autoAssign.booleanValue(); return isPrimaryKeyAutoAssigned(new ArrayList(3)); } /** - * Helper to calculate whether this foreign key depends on auto-assigned + * Helper to calculate whether this foreign key depends on auto-assigned * columns. Recurses appropriately if the primary key columns this key * joins to are themselves members of a foreign key that is dependent on - * auto-assigned columns. Caches calculated auto-assign value as a side + * auto-assigned columns. Caches calculated auto-assign value as a side * effect. * * @param seen track seen foreign keys to prevent infinite recursion in * the case of foreign key cycles */ private boolean isPrimaryKeyAutoAssigned(List seen) { - if (_autoAssign != null) - return _autoAssign; + if (_autoAssign != null) + return _autoAssign.booleanValue(); Column[] cols = getPrimaryKeyColumns(); if (cols.length == 0) { @@ -207,8 +206,8 @@ public class ForeignKey extends Constraint { return false; } - for (Column column : cols) { - if (column.isAutoAssigned()) { + for (int i = 0; i < cols.length; i++) { + if (cols[i].isAutoAssigned()) { _autoAssign = Boolean.TRUE; return true; } @@ -216,12 +215,12 @@ public class ForeignKey extends Constraint { ForeignKey[] fks = _pkTable.getForeignKeys(); seen.add(this); - for (Column col : cols) { - for (ForeignKey fk : fks) { - if (!fk.containsColumn(col)) + for (int i = 0; i < cols.length; i++) { + for (int j = 0; j < fks.length; j++) { + if (!fks[j].containsColumn(cols[i])) continue; - if (!seen.contains(fk) - && fk.isPrimaryKeyAutoAssigned(seen)) { + if (!seen.contains(fks[j]) + && fks[j].isPrimaryKeyAutoAssigned(seen)) { _autoAssign = Boolean.TRUE; return true; } @@ -236,7 +235,6 @@ public class ForeignKey extends Constraint { * The name of the primary key table. * @deprecated */ - @Deprecated public String getPrimaryKeyTableName() { return getPrimaryKeyTableIdentifier().getName(); } @@ -253,7 +251,6 @@ public class ForeignKey extends Constraint { * key table name on foreign keys that have not already been joined. * @deprecated */ - @Deprecated public void setPrimaryKeyTableName(String pkTableName) { setPrimaryKeyTableIdentifier(DBIdentifier.newTable(pkTableName)); } @@ -268,7 +265,6 @@ public class ForeignKey extends Constraint { * The name of the primary key table's schema. * @deprecated */ - @Deprecated public String getPrimaryKeySchemaName() { return getPrimaryKeySchemaIdentifier().getName(); } @@ -286,7 +282,6 @@ public class ForeignKey extends Constraint { * joined. * @deprecated */ - @Deprecated public void setPrimaryKeySchemaName(String pkSchemaName) { setPrimaryKeySchemaIdentifier(DBIdentifier.newSchema(pkSchemaName)); } @@ -301,7 +296,6 @@ public class ForeignKey extends Constraint { * The name of the primary key column. * @deprecated */ - @Deprecated public String getPrimaryKeyColumnName() { return getPrimaryKeyColumnIdentifier().getName(); } @@ -316,7 +310,6 @@ public class ForeignKey extends Constraint { * joined. * @deprecated */ - @Deprecated public void setPrimaryKeyColumnName(String pkColumnName) { setPrimaryKeyColumnIdentifier(DBIdentifier.newColumn(pkColumnName)); } @@ -527,9 +520,8 @@ public class ForeignKey extends Constraint { */ public void setJoins(Column[] cols, Column[] pkCols) { Column[] cur = getColumns(); - for (Column column : cur) { - removeJoin(column); - } + for (int i = 0; i < cur.length; i++) + removeJoin(cur[i]); if (cols != null) for (int i = 0; i < cols.length; i++) @@ -541,9 +533,8 @@ public class ForeignKey extends Constraint { */ public void setConstantJoins(Object[] consts, Column[] pkCols) { Column[] cur = getConstantPrimaryKeyColumns(); - for (Column column : cur) { - removeJoin(column); - } + for (int i = 0; i < cur.length; i++) + removeJoin(cur[i]); if (consts != null) for (int i = 0; i < consts.length; i++) @@ -555,9 +546,8 @@ public class ForeignKey extends Constraint { */ public void setConstantJoins(Column[] cols, Object[] consts) { Column[] cur = getConstantColumns(); - for (Column column : cur) { - removeJoin(column); - } + for (int i = 0; i < cur.length; i++) + removeJoin(cur[i]); if (consts != null) for (int i = 0; i < consts.length; i++) @@ -694,13 +684,11 @@ public class ForeignKey extends Constraint { */ public void refColumns() { Column[] cols = getColumns(); - for (Column column : cols) { - column.ref(); - } + for (int i = 0; i < cols.length; i++) + cols[i].ref(); cols = getConstantColumns(); - for (Column col : cols) { - col.ref(); - } + for (int i = 0; i < cols.length; i++) + cols[i].ref(); } /** @@ -708,13 +696,11 @@ public class ForeignKey extends Constraint { */ public void derefColumns() { Column[] cols = getColumns(); - for (Column column : cols) { - column.deref(); - } + for (int i = 0; i < cols.length; i++) + cols[i].deref(); cols = getConstantColumns(); - for (Column col : cols) { - col.deref(); - } + for (int i = 0; i < cols.length; i++) + cols[i].deref(); } /** @@ -762,26 +748,26 @@ public class ForeignKey extends Constraint { */ public boolean hasNotNullColumns() { Column[] columns = getColumns(); - for (Column column : columns) { - if (column.isNotNull()) { - return true; - } - } + for (int j = 0; j < columns.length; j++) { + if (columns[j].isNotNull()) { + return true; + } + } return false; } - + private static boolean match(Column[] cols, Column[] fkCols) { if (cols.length != fkCols.length) return false; - for (Column fkCol : fkCols) - if (!hasColumn(cols, fkCol)) + for (int i = 0; i < fkCols.length; i++) + if (!hasColumn(cols, fkCols[i])) return false; return true; } private static boolean hasColumn(Column[] cols, Column col) { - for (Column column : cols) - if (column.getQualifiedPath().equals(col.getQualifiedPath())) + for (int i = 0; i < cols.length; i++) + if (cols[i].getQualifiedPath().equals(col.getQualifiedPath())) return true; return false; } @@ -794,12 +780,11 @@ public class ForeignKey extends Constraint { return false; return true; } - + /** * Return the name of the foreignkey constraint as defined in the database. * @deprecated */ - @Deprecated public String loadNameFromDB(DBDictionary dbdict, Connection conn) { return loadIdentifierFromDB(dbdict, conn).getName(); } @@ -810,58 +795,58 @@ public class ForeignKey extends Constraint { DBIdentifier retVal = DBIdentifier.NULL; try{ Schema schema = getTable().getSchema(); - ForeignKey[] fks = dbdict.getImportedKeys(conn.getMetaData(), - DBIdentifier.newCatalog(conn.getCatalog()), schema.getIdentifier(), + ForeignKey[] fks = dbdict.getImportedKeys(conn.getMetaData(), + DBIdentifier.newCatalog(conn.getCatalog()), schema.getIdentifier(), getTable().getIdentifier(), conn, false); - for (ForeignKey fk : fks) { - Table localtable = schema.getTable(fk.getTableIdentifier()); + for ( int i=0; i< fks.length; i++) { + Table localtable = schema.getTable(fks[i].getTableIdentifier()); Table pkTable = schema.getTable( - fk.getPrimaryKeyTableIdentifier()); + fks[i].getPrimaryKeyTableIdentifier()); boolean addFK = false; ForeignKey fkTemp = localtable.getForeignKey( - fk.getIdentifier()); - if (fkTemp == null) { - addFK = true; + fks[i].getIdentifier()); + if( fkTemp == null) { + addFK=true; fkTemp = localtable.addForeignKey( - fk.getIdentifier()); - fkTemp.setDeferred(fk.isDeferred()); - fkTemp.setDeleteAction(fk.getDeleteAction()); + fks[i].getIdentifier()); + fkTemp.setDeferred(fks[i].isDeferred()); + fkTemp.setDeleteAction(fks[i].getDeleteAction()); } - if (fk.getColumns() == null || fk.getColumns().length == 0) { - // Singular column foreign key - if (!fkTemp.containsColumn( - localtable.getColumn(fk.getColumnIdentifier()))) - fkTemp.join(localtable.getColumn(fk.getColumnIdentifier()), - pkTable.getColumn(fk.getPrimaryKeyColumnIdentifier())); - } - else { + if (fks[i].getColumns() == null || fks[i].getColumns().length == 0) { + // Singular column foreign key + if( ! fkTemp.containsColumn( + localtable.getColumn(fks[i].getColumnIdentifier()))) + fkTemp.join(localtable.getColumn(fks[i].getColumnIdentifier()), + pkTable.getColumn(fks[i].getPrimaryKeyColumnIdentifier())); + } else { // Add the multi-column foreign key, joining local and pk columns in // the temporary key - Column[] locCols = fk.getColumns(); - Column[] pkCols = fk.getPrimaryKeyColumns(); + Column[] locCols = fks[i].getColumns(); + Column[] pkCols = fks[i].getPrimaryKeyColumns(); // Column counts must match if (locCols != null && pkCols != null && - locCols.length != pkCols.length) { + locCols.length != pkCols.length) { Log log = dbdict.getLog(); if (log.isTraceEnabled()) { log.trace(_loc.get("fk-column-mismatch")); } } for (int j = 0; j < locCols.length; j++) { - if (!fkTemp.containsColumn( - localtable.getColumn(locCols[j].getIdentifier()))) { - fkTemp.join(localtable.getColumn(locCols[j].getIdentifier()), - pkTable.getColumn(pkCols[j].getIdentifier())); + if( ! fkTemp.containsColumn( + localtable.getColumn(locCols[j].getIdentifier()))) { + fkTemp.join(localtable.getColumn(locCols[j].getIdentifier()), + pkTable.getColumn(pkCols[j].getIdentifier())); } } } - if (equalsForeignKey(fkTemp)) { - if (addFK) + if( equalsForeignKey(fkTemp)) + { + if(addFK) localtable.removeForeignKey(fkTemp); - retVal = fk.getIdentifier(); + retVal = fks[i].getIdentifier(); break; } - if (addFK) + if(addFK) localtable.removeForeignKey(fkTemp); } } catch(Exception ex){ @@ -895,9 +880,9 @@ public class ForeignKey extends Constraint { join(keyCols[0], keyCols[1]); } } - + /* - * Creates the local and primary key columns for a name-based fk. + * Creates the local and primary key columns for a name-based fk. * @return Column[] element 0 is local column * element 1 is the primary key in another table. */ @@ -909,7 +894,7 @@ public class ForeignKey extends Constraint { fkCol.setTableIdentifier(fk.getTableIdentifier()); fkCol.setSchemaIdentifier(fk.getSchemaIdentifier()); } - + Column pkCol = null; if (!DBIdentifier.isEmpty(fk.getPrimaryKeyColumnIdentifier())) { pkCol = new Column(); @@ -920,72 +905,60 @@ public class ForeignKey extends Constraint { return new Column[] { fkCol, pkCol }; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((_pkColumnName == null) ? 0 : _pkColumnName.hashCode()); + result = prime * result + ((_pkSchemaName == null) ? 0 : _pkSchemaName.hashCode()); + result = prime * result + ((_pkTableName == null) ? 0 : _pkTableName.hashCode()); + return result; + } - ForeignKey that = (ForeignKey) o; + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ForeignKey other = (ForeignKey) obj; + if (_pkColumnName == null) { + if (other._pkColumnName != null) + return false; + } else if (!_pkColumnName.equals(other._pkColumnName)) + return false; + if (_pkSchemaName == null) { + if (other._pkSchemaName != null) + return false; + } else if (!_pkSchemaName.equals(other._pkSchemaName)) + return false; + if (_pkTableName == null) { + if (other._pkTableName != null) + return false; + } else if (!_pkTableName.equals(other._pkTableName)) + return false; + return true; + } - if (_seq != that._seq) return false; - if (_delAction != that._delAction) return false; - if (_upAction != that._upAction) return false; - if (_index != that._index) return false; - if (_pkTableName != null ? !_pkTableName.equals(that._pkTableName) : that._pkTableName != null) return false; - if (_pkSchemaName != null ? !_pkSchemaName.equals(that._pkSchemaName) : that._pkSchemaName != null) return false; - if (_pkColumnName != null ? !_pkColumnName.equals(that._pkColumnName) : that._pkColumnName != null) return false; - if (_joins != null ? !_joins.equals(that._joins) : that._joins != null) return false; - if (_joinsPK != null ? !_joinsPK.equals(that._joinsPK) : that._joinsPK != null) return false; - if (_consts != null ? !_consts.equals(that._consts) : that._consts != null) return false; - if (_constsPK != null ? !_constsPK.equals(that._constsPK) : that._constsPK != null) return false; - // Probably incorrect - comparing Object[] arrays with Arrays.equals - if (!Arrays.equals(_locals, that._locals)) return false; - // Probably incorrect - comparing Object[] arrays with Arrays.equals - if (!Arrays.equals(_pks, that._pks)) return false; - // Probably incorrect - comparing Object[] arrays with Arrays.equals - if (!Arrays.equals(_constVals, that._constVals)) return false; - // Probably incorrect - comparing Object[] arrays with Arrays.equals - if (!Arrays.equals(_constCols, that._constCols)) return false; - // Probably incorrect - comparing Object[] arrays with Arrays.equals - if (!Arrays.equals(_constValsPK, that._constValsPK)) return false; - // Probably incorrect - comparing Object[] arrays with Arrays.equals - if (!Arrays.equals(_constColsPK, that._constColsPK)) return false; - if (_pkTable != null ? !_pkTable.equals(that._pkTable) : that._pkTable != null) return false; - return _autoAssign != null ? _autoAssign.equals(that._autoAssign) : that._autoAssign == null; - } - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + (_pkTableName != null ? _pkTableName.hashCode() : 0); - result = 31 * result + (_pkSchemaName != null ? _pkSchemaName.hashCode() : 0); - result = 31 * result + (_pkColumnName != null ? _pkColumnName.hashCode() : 0); - result = 31 * result + _seq; - result = 31 * result + (_joins != null ? _joins.hashCode() : 0); - result = 31 * result + (_joinsPK != null ? _joinsPK.hashCode() : 0); - result = 31 * result + (_consts != null ? _consts.hashCode() : 0); - result = 31 * result + (_constsPK != null ? _constsPK.hashCode() : 0); - result = 31 * result + _delAction; - result = 31 * result + _upAction; - result = 31 * result + _index; - result = 31 * result + Arrays.hashCode(_locals); - result = 31 * result + Arrays.hashCode(_pks); - result = 31 * result + Arrays.hashCode(_constVals); - result = 31 * result + Arrays.hashCode(_constCols); - result = 31 * result + Arrays.hashCode(_constValsPK); - result = 31 * result + Arrays.hashCode(_constColsPK); - result = 31 * result + (_pkTable != null ? _pkTable.hashCode() : 0); - result = 31 * result + (_autoAssign != null ? _autoAssign.hashCode() : 0); - return result; - } - /* - * ForeignKey utility class which determines equality based upon the - * non-column state of the keys. + + + + + + + + + + /* + * ForeignKey utility class which determines equality based upon the + * non-column state of the keys. */ public static class FKMapKey { - + private ForeignKey _fk; public FKMapKey(ForeignKey fk) { @@ -995,12 +968,10 @@ public class ForeignKey extends Constraint { return _fk; } - @Override public int hashCode() { return getFk().getIdentifier() != null ? getFk().getIdentifier().hashCode() : getFk().hashCode(); } - - @Override + public boolean equals(Object fkObj) { if (fkObj == this) { return true;