This is an automated email from the ASF dual-hosted git repository. struberg pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/openjpa.git
commit c13f0b0e136b0c2730c769948937975a92055940 Author: Robert Mayer <[email protected]> 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 | 41 +++++++++++++++++----- .../org/apache/openjpa/jdbc/sql/DBDictionary.java | 10 ++++++ .../apache/openjpa/jdbc/sql/OracleDictionary.java | 1 + .../openjpa/jdbc/sql/SQLServerDictionary.java | 2 ++ 4 files changed, 46 insertions(+), 8 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 0554235..9843ab3 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; } /** @@ -812,17 +829,25 @@ public class MappingDefaultsImpl @Override 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. */ @@ -868,9 +893,9 @@ public class MappingDefaultsImpl @Override 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 26e13fc..16a2216 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 @@ -345,6 +345,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 b58b55e..0b30cb3 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 @@ -251,6 +251,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 8d397b6..c50ccb1 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 @@ -80,6 +80,8 @@ public class SQLServerDictionary extends AbstractSQLServerDictionary { timeWithZoneTypeName = "TIME"; timestampWithZoneTypeName = "DATETIMEOFFSET"; + + indexPhysicalForeignKeys = true; // MS-SQLServer does not automatically create an index for a foreign key so we will } @Override
