This is an automated email from the ASF dual-hosted git repository. struberg pushed a commit to branch 2.4.x in repository https://gitbox.apache.org/repos/asf/openjpa.git
The following commit(s) were added to refs/heads/2.4.x by this push: new 712542b This fixes OPENJPA-2795 in that generation of indizes for @ManyToOne relations that are also foreign keys can optionally be turned on if so desired. Default behaviour of OpenJPA is unchanged. 712542b is described below commit 712542bf53f81b31fb61bc87a1f978654dddd60d Author: Robert Mayer <robert.ma...@rise-world.com> AuthorDate: Mon Jul 6 15:52:27 2020 +0200 This fixes OPENJPA-2795 in that generation of indizes for @ManyToOne relations that are also foreign keys can optionally be turned on if so desired. Default behaviour of OpenJPA is unchanged. This commit contains two new features: 1) A new DB-specific flag DBDictionary#indexPhysicalForeignKeys so that indices for foreign keys will be generated for database systems that don't automatically create an index for foreign keys. 2) A new boolean property MappingDefaults.IndexPhysicalForeignKeys that will turn the feature from 1) on or off. By default MappingDefaults.IndexPhysicalForeignKeys is false so that the feature from 1) is disabled. Note: DBDictionary#indexPhysicalForeignKeys works similar to the pre-existing flag DBDictionary#indexLogicalForeignKeys. Note: this commit enables FK indices for Oracle and MS SQLServer. Other database systems may benefit, too, and should also be changed. --- .../openjpa/jdbc/meta/MappingDefaultsImpl.java | 43 +++++++++++++++++----- .../org/apache/openjpa/jdbc/sql/DBDictionary.java | 10 +++++ .../apache/openjpa/jdbc/sql/OracleDictionary.java | 1 + .../openjpa/jdbc/sql/SQLServerDictionary.java | 2 + 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java index e9350d3..8f31b52 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.java @@ -61,7 +61,8 @@ public class MappingDefaultsImpl private int _joinFKAction = ForeignKey.ACTION_NONE; private int _fkAction = ForeignKey.ACTION_NONE; private boolean _defer = false; - private boolean _indexFK = true; + private boolean _indexLogicalFK = true; + private boolean _indexPhysicalFK = false; private boolean _indexDisc = true; private boolean _indexVers = false; private boolean _orderLists = true; @@ -248,14 +249,30 @@ public class MappingDefaultsImpl * Whether to index logical foreign keys by default. Defaults to true. */ public boolean getIndexLogicalForeignKeys() { - return _indexFK; + return _indexLogicalFK; } /** * Whether to index logical foreign keys by default. Defaults to true. */ public void setIndexLogicalForeignKeys(boolean indexFK) { - _indexFK = indexFK; + _indexLogicalFK = indexFK; + } + + /** + * Whether to use DbDictionary specific index on real foreign keys by default. + * Defaults to false i.e. old compatibility behaviour (i.e. no foreign key indices for FKs) + */ + public boolean getIndexPhysicalForeignKeys() { + return _indexPhysicalFK; + } + + /** + * Whether to use DbDictionary specific index on real foreign keys by default. + * Defaults to false i.e. old compatibility behaviour (i.e. no foreign key indices for FKs) + */ + public void setIndexPhysicalForeignKeys(boolean indexPhysFKCompat) { + _indexPhysicalFK = indexPhysFKCompat; } /** @@ -747,7 +764,7 @@ public class MappingDefaultsImpl Table foreign, boolean inverse) { return getForeignKey(vm, DBIdentifier.newForeignKey(name), local, foreign, inverse); } - + public ForeignKey getForeignKey(ValueMapping vm, DBIdentifier name, Table local, Table foreign, boolean inverse) { if (_fkAction == ForeignKey.ACTION_NONE) @@ -759,17 +776,25 @@ public class MappingDefaultsImpl } public Index getJoinIndex(FieldMapping fm, Table table, Column[] cols) { - if (!_indexFK || fm.getJoinForeignKey() == null - || !fm.getJoinForeignKey().isLogical()) + if (!needsFkIndex(fm.getJoinForeignKey())) { return null; - if (areAllPrimaryKeyColumns(cols)) + } + if (areAllPrimaryKeyColumns(cols)) { return null; + } Index idx = new Index(); idx.setIdentifier(getIndexName(DBIdentifier.NULL, table, cols)); return idx; } + private boolean needsFkIndex(ForeignKey fk) { + if (fk == null) + return false; + boolean fkIsLogical = fk.isLogical(); + return (_indexLogicalFK && fkIsLogical) || (_indexPhysicalFK && !fkIsLogical && dict.indexPhysicalForeignKeys); + } + /** * Return whether all the given columns are primary key columns. */ @@ -811,9 +836,9 @@ public class MappingDefaultsImpl public Index getIndex(ValueMapping vm, DBIdentifier name, Table table, Column[] cols) { - if (!_indexFK || vm.getForeignKey() == null - || !vm.getForeignKey().isLogical()) + if (!needsFkIndex(vm.getForeignKey())) { return null; + } if (areAllPrimaryKeyColumns(cols)) return null; diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java index 72efaf0..102496a 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java @@ -336,6 +336,16 @@ public class DBDictionary */ protected BooleanRepresentation booleanRepresentation = BooleanRepresentationFactory.INT_10; + /** + * Whether an index is generated for a relation that is also a foreign key. + * Some database systems (e.g. MySQL) will automatically create an index for a foreign key, + * others (e.g. Oracle, MS-SQL-Server) do not. + * + * See also {@link org.apache.openjpa.jdbc.meta.MappingDefaultsImpl#_indexPhysicalFK} + * which may disable this feature for backwards compatibility. + */ + public boolean indexPhysicalForeignKeys = false; + public int characterColumnSize = 255; public String arrayTypeName = "ARRAY"; public String bigintTypeName = "BIGINT"; diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java index 867a8f5..f2859b3 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java @@ -245,6 +245,7 @@ public class OracleDictionary oracleBlob_empty_lob_Method = getMethodByReflection("oracle.sql.BLOB", "getEmptyBLOB"); oracleClob_isEmptyLob_Method = getMethodByReflection("oracle.sql.CLOB", "isEmptyLob"); + indexPhysicalForeignKeys = true; // Oracle does not automatically create an index for a foreign key so we will } private Method getMethodByReflection(String className, String methodName, Class<?>... paramTypes) { diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java index 6d4e86d..63ef0e3 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java @@ -63,6 +63,8 @@ public class SQLServerDictionary extends AbstractSQLServerDictionary { supportsNullTableForGetColumns = false; requiresAliasForSubselect = true; stringLengthFunction = "LEN({0})"; + + indexPhysicalForeignKeys = true; // MS-SQLServer does not automatically create an index for a foreign key so we will } public void connectedConfiguration(Connection conn) throws SQLException {