diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/identifier/DBIdentifier.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/identifier/DBIdentifier.java index b2688abf2..9b8b46703 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/identifier/DBIdentifier.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/identifier/DBIdentifier.java @@ -418,7 +418,7 @@ public class DBIdentifier extends IdentifierImpl implements Cloneable, Identifie /** * Converts the provided set of names to an array of identifiers of the * provided type, optionally delimiting the names. - * @param columnNames + * @param names columnNames or other DB identifier names * @param id */ public static DBIdentifier[] toArray(String[] names, DBIdentifierType id, boolean delimit) { @@ -427,7 +427,7 @@ public class DBIdentifier extends IdentifierImpl implements Cloneable, Identifie } DBIdentifier[] sNames = new DBIdentifier[names.length]; for (int i = 0; i < names.length; i++) { - sNames[i] = new DBIdentifier(names[i], id, delimit); + sNames[i] = new DBIdentifier(names[i].trim(), id, delimit); } return sNames; } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/identifier/Normalizer.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/identifier/Normalizer.java index cce440d1e..dfd72b50f 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/identifier/Normalizer.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/identifier/Normalizer.java @@ -253,8 +253,6 @@ public class Normalizer { /** * Removes default delimiters from a string. - * @param name1 - * @param name2 */ public static String removeDelimiters(String name) { return normalizer.removeDelimiters(defaultRule, name); @@ -263,8 +261,6 @@ public class Normalizer { /** * Delimits a string if necessary, optionally forcing it to be * delimited. - * @param name1 - * @param name2 */ public static String delimit(String name, boolean force) { return normalizer.delimit(defaultRule, name, force); @@ -272,8 +268,6 @@ public class Normalizer { /** * Determines whether a name can be split into multiple components. - * @param name1 - * @param name2 */ public static boolean canSplit(String name) { return normalizer.canSplit(defaultRule, name); @@ -282,8 +276,6 @@ public class Normalizer { /** * Determines whether a name can be split into multiple components, taking * into account the specified delimiter. - * @param name1 - * @param name2 */ public static boolean canSplit(String name, String delim) { return normalizer.canSplit(defaultRule, name, delim); diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/identifier/IdentifierUtil.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/identifier/IdentifierUtil.java index dc3b4bacd..c53c2d10b 100644 --- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/identifier/IdentifierUtil.java +++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/identifier/IdentifierUtil.java @@ -50,7 +50,7 @@ public interface IdentifierUtil { /** * Delimit the name if it requires delimiters - * @param the rule to use for delimiting + * @param rule the rule to use for delimiting * @param name the name to delimit * @return the delimited name, if delimiting was necessary. */ @@ -58,7 +58,7 @@ public interface IdentifierUtil { /** * Delimit the name if it requires delimiters - * @param the rule to use for delimiting + * @param rule the rule to use for delimiting * @param name the name to delimit * @return the delimited name, if delimiting was necessary. */ @@ -68,7 +68,7 @@ public interface IdentifierUtil { * Delimit the string with the option to force delimiting. If force is * true, the name will delimited without checking to see if it * requires delimiters. - * @param the rule to use for delimiting + * @param rule the rule to use for delimiting * @param name the name to delimit * @param force add delimiters even if delimiting is not required * @return the delimited name, if delimiting was necessary. @@ -79,7 +79,7 @@ public interface IdentifierUtil { * Delimit the string with the option to force delimiting. If force is * true, the name will delimited without checking to see if it * requires delimiters. - * @param the rule to use for delimiting + * @param rule the rule to use for delimiting * @param name the name to delimit * @param force add delimiters even if delimiting is not required * @return the delimited name, if delimiting was necessary. @@ -89,35 +89,35 @@ public interface IdentifierUtil { /** * Remove delimiters from a delimited name - * @param the rule to use for removing delimiters + * @param rule the rule to use for removing delimiters * @param name the name from which to remove delimiters */ String removeDelimiters(String rule, String name); /** * Remove delimiters from a delimited name - * @param the rule to use for removing delimiters + * @param rule the rule to use for removing delimiters * @param name the name from which to remove delimiters */ String removeDelimiters(IdentifierConfiguration config, String rule, String name); /** * Remove delimiters from a delimited name - * @param the rule to use for removing delimiters + * @param rule the rule to use for removing delimiters * @param name the name from which to remove delimiters */ String removeDelimiters(IdentifierRule rule, String name); /** * Determines whether a name is delimited. - * @param the rule to use for removing delimiters + * @param rule the rule to use for removing delimiters * @param name the name to examine for delimiters */ boolean isDelimited(String rule, String name); /** * Determines whether a name is delimited. - * @param the rule to use for removing delimiters + * @param rule the rule to use for removing delimiters * @param name the name to examine for delimiters */ boolean isDelimited(IdentifierRule rule, String name); @@ -128,7 +128,7 @@ public interface IdentifierUtil { *
  • The SQL-92 Reference definition of a valid unquoted name
  • *
  • The naming rule specified
  • * - * @param the rule to use for removing delimiters + * @param rule the rule to use for removing delimiters * @param name the name to examine for delimiting requirements */ boolean requiresDelimiters(String rule, String name); @@ -139,7 +139,7 @@ public interface IdentifierUtil { *
  • The SQL-92 Reference definition of a valid unquoted name
  • *
  • The naming rule specified
  • * - * @param the rule to use for removing delimiters + * @param rule the rule to use for removing delimiters * @param name the name to examine for delimiting requirements */ boolean requiresDelimiters(IdentifierRule rule, String name); diff --git a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java index d22431b52..cd0c95450 100644 --- a/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java +++ b/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/AnnotationPersistenceMappingParser.java @@ -655,8 +655,10 @@ public class AnnotationPersistenceMappingParser org.apache.openjpa.jdbc.schema.Index createIndex(MetaDataContext ctx, javax.persistence.Index anno) { String columnNames = anno.columnList(); - if (StringUtil.isEmpty(columnNames)) + if (StringUtil.isEmpty(columnNames)) { throw new UserException(_loc.get("index-no-column", ctx)); + } + DBIdentifier[] sColNames = DBIdentifier.toArray(columnNames.split(","), DBIdentifierType.COLUMN, delimit()); org.apache.openjpa.jdbc.schema.Index indx = new org.apache.openjpa.jdbc.schema.Index(); for (int i = 0; i < sColNames.length; i++) { diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EntityWithIndices.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EntityWithIndices.java index cc073d177..1cf9b84b1 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EntityWithIndices.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/EntityWithIndices.java @@ -26,51 +26,75 @@ import javax.persistence.Table; @Entity @Table(name = "INDICES1" - , indexes = {@Index(name = "idx_index1", columnList = "index1") - , @Index(name = "idx_long", columnList = "LONG_NAME", unique = true)}) + , indexes = {@Index(name = "idx_index1", columnList = "INDEX1") + , @Index(name = "idx_long", columnList = "LONG_NAME", unique = true) + , @Index(name = "idx_wo_spaces", columnList = "INDEX1,COL2,COL3") + , @Index(name = "idx_with_spaces", columnList = " LONG_NAME , COL2, COL3 ")}) public class EntityWithIndices { - @Id - @Column(name = "PK") - private Long pk; + @Id + @Column(name = "PK") + private Long pk; - @Column(name = "INDEX1") - private String index1; + @Column(name = "INDEX1") + private String index1; - @Column(name = "LONG_NAME") - private String longName; + @Column(name = "LONG_NAME") + private String longName; - @Column(name = "NAME") - private String name; + @Column(name = "NAME") + private String name; + + @Column(name = "COL2") + private String col2; + + @Column(name = "COL3") + private String col3; - public Long getPk() { - return pk; - } + public Long getPk() { + return pk; + } - public void setPk(Long pk) { - this.pk = pk; - } + public void setPk(Long pk) { + this.pk = pk; + } - public String getIndex1() { - return index1; - } + public String getIndex1() { + return index1; + } - public void setIndex1(String index1) { - this.index1 = index1; - } + public void setIndex1(String index1) { + this.index1 = index1; + } - public String getLongName() { - return longName; - } + public String getLongName() { + return longName; + } - public void setLongName(String longName) { - this.longName = longName; - } + public void setLongName(String longName) { + this.longName = longName; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } + + public String getCol2() { + return col2; + } + + public void setCol2(String col2) { + this.col2 = col2; + } + + public String getCol3() { + return col3; + } + + public void setCol3(String col3) { + this.col3 = col3; + } } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestIndices.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestIndices.java index f105d6471..a4a1d43c4 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestIndices.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/annotations/TestIndices.java @@ -18,8 +18,11 @@ */ package org.apache.openjpa.persistence.jdbc.annotations; +import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.identifier.DBIdentifier; @@ -31,34 +34,53 @@ import org.apache.openjpa.persistence.test.SingleEMFTestCase; import org.junit.Test; public class TestIndices extends SingleEMFTestCase { - @Override - public void setUp() { - setUp(EntityWithIndices.class, CLEAR_TABLES -// ,"openjpa.Log","SQL=trace" - ); - } + @Override + public void setUp() { + setUp(EntityWithIndices.class, CLEAR_TABLES +// ,"openjpa.Log","SQL=trace" + ); + } - @Test - public void testIndicesCreated() { - JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration(); - ClassMapping cls = conf.getMappingRepositoryInstance().getMapping(EntityWithIndices.class, null, true); - Table table = cls.getTable(); - Index idx1 = table.getIndex(DBIdentifier.newIndex("idx_index1")); - assertNotNull("Defined index should exist", idx1); - assertFalse(idx1.isUnique()); + @Test + public void testIndicesCreated() { + JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration(); + ClassMapping cls = conf.getMappingRepositoryInstance().getMapping(EntityWithIndices.class, null, true); + Table table = cls.getTable(); + Index idx1 = table.getIndex(DBIdentifier.newIndex("idx_index1")); + assertNotNull("Defined index should exist", idx1); + assertFalse(idx1.isUnique()); - Index idx2 = table.getIndex(DBIdentifier.newIndex("idx_long")); - assertNotNull("Defined index should exist", idx2); - assertTrue(idx2.isUnique()); + Index idx2 = table.getIndex(DBIdentifier.newIndex("idx_long")); + assertNotNull("Defined index should exist", idx2); + assertTrue(idx2.isUnique()); - Set indexedCols = new HashSet<>(); - for (Index idx : table.getIndexes()) { - for (Column col : idx.getColumns()) { - indexedCols.add(col.getIdentifier().getName()); - } - } - assertTrue(indexedCols.contains("INDEX1")); - assertTrue(indexedCols.contains("LONG_NAME")); - assertFalse(indexedCols.contains("NAME")); - } + Set indexedCols = new HashSet<>(); + for (Index idx : table.getIndexes()) { + for (Column col : idx.getColumns()) { + indexedCols.add(col.getIdentifier().getName()); + } + } + assertTrue(indexedCols.contains("INDEX1")); + assertTrue(indexedCols.contains("LONG_NAME")); + assertFalse(indexedCols.contains("NAME")); + + // test multi column index without spaces + assertIndexColumns(table, "idx_wo_spaces", "INDEX1", "COL2", "COL3"); + + // test multi column index without spaces + assertIndexColumns(table, "idx_with_spaces", "LONG_NAME", "COL2", "COL3"); + } + + private void assertIndexColumns(Table table, String indexName, String... assertedColumnNames) { + Index idx = table.getIndex(DBIdentifier.newIndex(indexName)); + assertNotNull("Defined index should exist", idx); + + final List indexColumnNames = Arrays.stream(idx.getColumns()) + .map(c -> c.getIdentifier().getName()) + .collect(Collectors.toList()); + + for (String assertedColumnName : assertedColumnNames) { + assertTrue("Column " + assertedColumnName + " does not exist in index " + indexName, indexColumnNames.contains(assertedColumnName)); + } + } }