You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by st...@apache.org on 2020/08/31 12:31:46 UTC

[openjpa] branch 2.4.x updated: 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 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 <ro...@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 {