OPENJPA-2814 fix mem leak

This commit is contained in:
gjevardat 2023-06-05 11:02:32 +02:00
parent 1c6a6014a0
commit 6950441288
2 changed files with 176 additions and 197 deletions

View File

@ -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;
}
}

View File

@ -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;