From 1e655c421e4b09a2311cbd40d5202adbeba10958 Mon Sep 17 00:00:00 2001 From: Enrico Olivelli Date: Wed, 28 Oct 2020 12:20:18 +0100 Subject: [PATCH 1/7] Add OpenJPA foreignkey example --- .../src/main/java/test/entity/Address.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 herddb-thirdparty/openjpa-test/src/main/java/test/entity/Address.java diff --git a/herddb-thirdparty/openjpa-test/src/main/java/test/entity/Address.java b/herddb-thirdparty/openjpa-test/src/main/java/test/entity/Address.java new file mode 100644 index 000000000..3b87ee268 --- /dev/null +++ b/herddb-thirdparty/openjpa-test/src/main/java/test/entity/Address.java @@ -0,0 +1,48 @@ +/* + * Licensed to Diennea S.r.l. under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Diennea S.r.l. licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "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. + * + */ +package test.entity; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Lob; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Entity +@NoArgsConstructor +@AllArgsConstructor +@SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_BOOLEAN_RETURN_NULL"}, + justification = " Unwritten field: test.entity.User.pcPCSuperclass [test.entity.User] " + + " test.entity.User.pcIsDetached() has Boolean return type and returns explicit null") +public class User { + + @Id + @GeneratedValue + private long id; + private String name; + // reserved word for Calcite + private int value; + @Lob + private String description; +} From 052237c743c5ae94e9cf4632bbd26084da154970 Mon Sep 17 00:00:00 2001 From: Enrico Olivelli Date: Wed, 28 Oct 2020 12:20:53 +0100 Subject: [PATCH 2/7] Add OpenJPA foreignkey example --- herddb-thirdparty/openjpa-test/pom.xml | 2 +- .../src/main/java/test/entity/Address.java | 13 ++++--------- .../src/main/java/test/entity/User.java | 8 ++++++++ .../src/main/resources/META-INF/persistence.xml | 6 +++++- .../src/test/java/test/DataSourceTest.java | 5 +++-- .../src/test/java/test/JDBCDriverTest.java | 3 ++- .../src/main/java/herddb/openjpa/DBDictionary.java | 5 ++--- 7 files changed, 25 insertions(+), 17 deletions(-) diff --git a/herddb-thirdparty/openjpa-test/pom.xml b/herddb-thirdparty/openjpa-test/pom.xml index bf6ae15a9..96466f92e 100644 --- a/herddb-thirdparty/openjpa-test/pom.xml +++ b/herddb-thirdparty/openjpa-test/pom.xml @@ -41,7 +41,7 @@ org.apache.openjpa openjpa - 3.1.1 + 3.1.3-SNAPSHOT + + + none + + diff --git a/herddb-thirdparty/openjpa-test/src/main/java/test/entity/User.java b/herddb-thirdparty/openjpa-test/src/main/java/test/entity/User.java index 4dbfc72af..b49b69180 100644 --- a/herddb-thirdparty/openjpa-test/src/main/java/test/entity/User.java +++ b/herddb-thirdparty/openjpa-test/src/main/java/test/entity/User.java @@ -27,7 +27,6 @@ import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.OneToOne; -import javax.persistence.UniqueConstraint; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -39,18 +38,18 @@ @SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD", "NP_BOOLEAN_RETURN_NULL"}, justification = " Unwritten field: test.entity.User.pcPCSuperclass [test.entity.User] " + " test.entity.User.pcIsDetached() has Boolean return type and returns explicit null") -public class User { +public class User { // this is a reserved word for Calcite @Id @GeneratedValue private long id; @Column(unique = true) private String name; - // reserved word for Calcite + // this is a reserved word for Calcite private int value; @Lob private String description; - @OneToOne(cascade = CascadeType.REMOVE) + @OneToOne(cascade = CascadeType.ALL) private Address address; } diff --git a/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml b/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml index 43796c07b..b983a90a2 100644 --- a/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml +++ b/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml @@ -27,7 +27,11 @@ - + + + @@ -36,7 +40,11 @@ test.entity.Address true - + + + diff --git a/herddb-thirdparty/openjpa-test/src/test/java/test/DataSourceTest.java b/herddb-thirdparty/openjpa-test/src/test/java/test/DataSourceTest.java index 3b23e6e03..86e4f2f9d 100644 --- a/herddb-thirdparty/openjpa-test/src/test/java/test/DataSourceTest.java +++ b/herddb-thirdparty/openjpa-test/src/test/java/test/DataSourceTest.java @@ -52,22 +52,46 @@ public void hello() throws Exception { final EntityManagerFactory factory = Persistence.createEntityManagerFactory("hdb_ds", Map.of("openjpa.ConnectionFactory", ds2)); + performAssertions(factory); + + factory.close(); + + ds2.close(); + + } + + static void performAssertions(final EntityManagerFactory factory) { { final EntityManager em = factory.createEntityManager(); final EntityTransaction transaction = em.getTransaction(); transaction.begin(); - em.persist(new User(0, "First", 10, "Something", new Address(1, "Localhost"))); + Address a = new Address(0, "Localhost"); + em.persist(a); + em.persist(new User(0, "First", 10, "Something", a)); transaction.commit(); em.close(); } { final EntityManager em = factory.createEntityManager(); assertEquals(1, em.createQuery("select e from User e").getResultList().size()); + assertEquals(1, em.createQuery("select e from Address e").getResultList().size()); + em.close(); + } + + { + final EntityManager em = factory.createEntityManager(); + final EntityTransaction transaction = em.getTransaction(); + transaction.begin(); + em.createQuery("DELETE from User e").executeUpdate(); + transaction.commit(); + em.close(); + } + + { + final EntityManager em = factory.createEntityManager(); + assertEquals(0, em.createQuery("select e from User e").getResultList().size()); + assertEquals(0, em.createQuery("select e from Address e").getResultList().size()); em.close(); } - factory.close(); - - ds2.close(); - } } diff --git a/herddb-thirdparty/openjpa-test/src/test/java/test/JDBCDriverTest.java b/herddb-thirdparty/openjpa-test/src/test/java/test/JDBCDriverTest.java index 02494cb94..cc615fc81 100644 --- a/herddb-thirdparty/openjpa-test/src/test/java/test/JDBCDriverTest.java +++ b/herddb-thirdparty/openjpa-test/src/test/java/test/JDBCDriverTest.java @@ -43,19 +43,8 @@ public void hello() throws Exception { final EntityManagerFactory factory = Persistence.createEntityManagerFactory("hdb_jdbc"); - { - final EntityManager em = factory.createEntityManager(); - final EntityTransaction transaction = em.getTransaction(); - transaction.begin(); - em.persist(new User(0, "First", 10, "Something", new Address(1, "Localhost"))); - transaction.commit(); - em.close(); - } - { - final EntityManager em = factory.createEntityManager(); - assertEquals(1, em.createQuery("select e from User e").getResultList().size()); - em.close(); - } + DataSourceTest.performAssertions(factory); + factory.close(); // clean up, unregistring the driver will shutdown every datasource From cf58dc6f1b78804f0b15c6405c990375832bbc3e Mon Sep 17 00:00:00 2001 From: Enrico Olivelli Date: Fri, 30 Oct 2020 10:10:50 +0100 Subject: [PATCH 4/7] better fk name generation and fix checkstyle --- .../src/main/java/herddb/sql/JSQLParserPlanner.java | 6 +++++- .../src/test/java/herddb/sql/ForeignKeySQLTest.java | 6 +++--- .../main/java/herddb/jdbc/HerdDBDatabaseMetadata.java | 8 ++++---- .../src/main/java/test/entity/Address.java | 3 +-- .../openjpa-test/src/main/java/test/entity/User.java | 2 +- .../src/test/java/test/DataSourceTest.java | 10 +++++----- .../src/test/java/test/JDBCDriverTest.java | 5 ----- 7 files changed, 19 insertions(+), 21 deletions(-) diff --git a/herddb-core/src/main/java/herddb/sql/JSQLParserPlanner.java b/herddb-core/src/main/java/herddb/sql/JSQLParserPlanner.java index cec6401df..d2dd2749c 100644 --- a/herddb-core/src/main/java/herddb/sql/JSQLParserPlanner.java +++ b/herddb-core/src/main/java/herddb/sql/JSQLParserPlanner.java @@ -320,7 +320,8 @@ public TranslatedQuery translate( query = rewriteExecuteSyntax(query); if (query.startsWith("ALTER TABLE") && query.contains("ADD FOREIGN KEY")) { - query = query.replace("ADD FOREIGN KEY","ADD CONSTRAINT unnamed_fk_"+System.nanoTime()+" FOREIGN KEY"); + // jsqlparser does not support unnamed foreign keys in "ALTER TABLE" + query = query.replace("ADD FOREIGN KEY", "ADD CONSTRAINT generate_unnamed FOREIGN KEY"); } if (query.startsWith("EXPLAIN ")) { query = query.substring("EXPLAIN ".length()); @@ -611,6 +612,9 @@ private Statement buildCreateTableStatement(String defaultTableSpace, CreateTabl private ForeignKeyDef parseForeignKeyIndex(ForeignKeyIndex fk, Table table, String tableName, String tableSpace) throws StatementExecutionException { String indexName = fixMySqlBackTicks(fk.getName().toLowerCase()); + if (indexName.equals("generate_unnamed")) { + indexName = "fk_" + tableName + "_" + System.nanoTime(); + } int onUpdateCascadeAction = parseForeignKeyAction(fk.getOnUpdateReferenceOption()); int onDeleteCascadeAction = parseForeignKeyAction(fk.getOnDeleteReferenceOption()); Table parentTableSchema = getTable(table.tablespace, fk.getTable()); diff --git a/herddb-core/src/test/java/herddb/sql/ForeignKeySQLTest.java b/herddb-core/src/test/java/herddb/sql/ForeignKeySQLTest.java index 7b8b94fb3..fab9ad857 100644 --- a/herddb-core/src/test/java/herddb/sql/ForeignKeySQLTest.java +++ b/herddb-core/src/test/java/herddb/sql/ForeignKeySQLTest.java @@ -479,7 +479,7 @@ public void createTableWithOnUpdateSetNull() throws Exception { } } - + @Test public void alterAddUnnamedForeignKey() throws Exception { String nodeId = "localhost"; @@ -491,11 +491,11 @@ public void alterAddUnnamedForeignKey() throws Exception { execute(manager, "CREATE TABLE tblspace1.parent (k1 string primary key,n1 int,s1 string)", Collections.emptyList()); execute(manager, "CREATE TABLE tblspace1.child (k2 string primary key,n2 int," - + "s2 string)", Collections.emptyList()); + + "s2 string)", Collections.emptyList()); execute(manager, "ALTER TABLE tblspace1.child ADD FOREIGN KEY (s2,n2) REFERENCES parent(k1,n1)", Collections.emptyList()); Table parentTable = manager.getTableSpaceManager("tblspace1").getTableManager("parent").getTable(); Table childTable = manager.getTableSpaceManager("tblspace1").getTableManager("child").getTable(); - assertEquals(1, childTable.foreignKeys.length); + assertEquals(1, childTable.foreignKeys.length); assertEquals(ForeignKeyDef.ACTION_NO_ACTION, childTable.foreignKeys[0].onUpdateAction); assertEquals(ForeignKeyDef.ACTION_NO_ACTION, childTable.foreignKeys[0].onDeleteAction); assertEquals(parentTable.uuid, childTable.foreignKeys[0].parentTableId); diff --git a/herddb-jdbc/src/main/java/herddb/jdbc/HerdDBDatabaseMetadata.java b/herddb-jdbc/src/main/java/herddb/jdbc/HerdDBDatabaseMetadata.java index 4b455a7f8..f763586dc 100644 --- a/herddb-jdbc/src/main/java/herddb/jdbc/HerdDBDatabaseMetadata.java +++ b/herddb-jdbc/src/main/java/herddb/jdbc/HerdDBDatabaseMetadata.java @@ -1758,7 +1758,7 @@ public boolean isWrapperFor(Class iface) throws SQLException { } public static int convertFkActions(String action) { - switch (action+"") { + switch (action + "") { case "importedNoAction": return importedKeyNoAction; case "importedKeyCascade": @@ -1771,11 +1771,11 @@ public static int convertFkActions(String action) { return importedKeyRestrict; default: return importedKeyNoAction; - } + } } - + private static int convertDeferrability(String deferred) { - switch (deferred+"") { + switch (deferred + "") { case "importedKeyNotDeferrable": return importedKeyNotDeferrable; case "importedKeyInitiallyDeferred": diff --git a/herddb-thirdparty/openjpa-test/src/main/java/test/entity/Address.java b/herddb-thirdparty/openjpa-test/src/main/java/test/entity/Address.java index 03cb6f962..389a3e0da 100644 --- a/herddb-thirdparty/openjpa-test/src/main/java/test/entity/Address.java +++ b/herddb-thirdparty/openjpa-test/src/main/java/test/entity/Address.java @@ -23,7 +23,6 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; -import javax.persistence.Lob; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -39,5 +38,5 @@ public class Address { @GeneratedValue private long id; private String city; - + } diff --git a/herddb-thirdparty/openjpa-test/src/main/java/test/entity/User.java b/herddb-thirdparty/openjpa-test/src/main/java/test/entity/User.java index b49b69180..957f5c346 100644 --- a/herddb-thirdparty/openjpa-test/src/main/java/test/entity/User.java +++ b/herddb-thirdparty/openjpa-test/src/main/java/test/entity/User.java @@ -49,7 +49,7 @@ public class User { // this is a reserved word for Calcite private int value; @Lob private String description; - + @OneToOne(cascade = CascadeType.ALL) private Address address; } diff --git a/herddb-thirdparty/openjpa-test/src/test/java/test/DataSourceTest.java b/herddb-thirdparty/openjpa-test/src/test/java/test/DataSourceTest.java index 86e4f2f9d..19bb9f3c1 100644 --- a/herddb-thirdparty/openjpa-test/src/test/java/test/DataSourceTest.java +++ b/herddb-thirdparty/openjpa-test/src/test/java/test/DataSourceTest.java @@ -53,7 +53,7 @@ public void hello() throws Exception { Map.of("openjpa.ConnectionFactory", ds2)); performAssertions(factory); - + factory.close(); ds2.close(); @@ -64,9 +64,9 @@ static void performAssertions(final EntityManagerFactory factory) { { final EntityManager em = factory.createEntityManager(); final EntityTransaction transaction = em.getTransaction(); - transaction.begin(); + transaction.begin(); Address a = new Address(0, "Localhost"); - em.persist(a); + em.persist(a); em.persist(new User(0, "First", 10, "Something", a)); transaction.commit(); em.close(); @@ -77,7 +77,7 @@ static void performAssertions(final EntityManagerFactory factory) { assertEquals(1, em.createQuery("select e from Address e").getResultList().size()); em.close(); } - + { final EntityManager em = factory.createEntityManager(); final EntityTransaction transaction = em.getTransaction(); @@ -86,7 +86,7 @@ static void performAssertions(final EntityManagerFactory factory) { transaction.commit(); em.close(); } - + { final EntityManager em = factory.createEntityManager(); assertEquals(0, em.createQuery("select e from User e").getResultList().size()); diff --git a/herddb-thirdparty/openjpa-test/src/test/java/test/JDBCDriverTest.java b/herddb-thirdparty/openjpa-test/src/test/java/test/JDBCDriverTest.java index cc615fc81..273114f92 100644 --- a/herddb-thirdparty/openjpa-test/src/test/java/test/JDBCDriverTest.java +++ b/herddb-thirdparty/openjpa-test/src/test/java/test/JDBCDriverTest.java @@ -19,17 +19,12 @@ */ package test; -import static org.junit.Assert.assertEquals; import java.sql.Driver; import java.sql.DriverManager; import java.util.Enumeration; -import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import org.junit.Test; -import test.entity.Address; -import test.entity.User; /** * From b63af0d9b207100bc1b88cde58265278921b154c Mon Sep 17 00:00:00 2001 From: Enrico Olivelli Date: Fri, 30 Oct 2020 15:14:47 +0100 Subject: [PATCH 5/7] Disable native foreign keys --- .../src/main/resources/META-INF/persistence.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml b/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml index b983a90a2..13a97460c 100644 --- a/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml +++ b/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml @@ -27,9 +27,9 @@ - - @@ -41,9 +41,9 @@ true - - From 5549ccb614b45ebd2c7398c33828f4471cca1d73 Mon Sep 17 00:00:00 2001 From: Enrico Olivelli Date: Fri, 30 Oct 2020 17:44:24 +0100 Subject: [PATCH 6/7] fix jdbc test --- .../test/java/herddb/jdbc/JdbcForeignKeyMetadataTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/herddb-jdbc/src/test/java/herddb/jdbc/JdbcForeignKeyMetadataTest.java b/herddb-jdbc/src/test/java/herddb/jdbc/JdbcForeignKeyMetadataTest.java index 33f4911a9..1ec186511 100644 --- a/herddb-jdbc/src/test/java/herddb/jdbc/JdbcForeignKeyMetadataTest.java +++ b/herddb-jdbc/src/test/java/herddb/jdbc/JdbcForeignKeyMetadataTest.java @@ -53,7 +53,7 @@ public void test() throws Exception { Statement statement = con.createStatement()) { statement.execute("CREATE TABLE ptable (pkey string primary key, p1 string, p2 string)"); statement.execute("CREATE TABLE ctable (ckey string primary key, c1 string, c2 string," - + " CONSTRAINT `fk1` FOREIGN KEY (`c1`,`c2`) REFERENCES ptable(`p1`,`p2`))"); + + " CONSTRAINT `fk1` FOREIGN KEY (`c1`,`c2`) REFERENCES ptable(`p1`,`p2`) ON DELETE CASCADE)"); DatabaseMetaData metaData = con.getMetaData(); try (ResultSet rs = metaData.getImportedKeys(null, null, "CTABLE");) { verifyForeignKeyResultSet(rs); @@ -101,7 +101,7 @@ private void verifyForeignKeyResultSet(final ResultSet importedKeys) throws SQLE assertEquals("fk1", importedKeys.getString("FK_NAME")); assertEquals(null, importedKeys.getString("PK_NAME")); - assertEquals("importedKeyNotDeferrable", importedKeys.getString("DEFERRABILITY")); + assertEquals(DatabaseMetaData.importedKeyNotDeferrable, importedKeys.getInt("DEFERRABILITY")); if (count == 0) { assertEquals("c1", importedKeys.getString("PKCOLUMN_NAME")); assertEquals("p1", importedKeys.getString("FKCOLUMN_NAME")); @@ -109,8 +109,8 @@ private void verifyForeignKeyResultSet(final ResultSet importedKeys) throws SQLE assertEquals("c2", importedKeys.getString("PKCOLUMN_NAME")); assertEquals("p2", importedKeys.getString("FKCOLUMN_NAME")); } - assertEquals("importedNoAction", importedKeys.getString("UPDATE_RULE")); - assertEquals("importedNoAction", importedKeys.getString("DELETE_RULE")); + assertEquals(DatabaseMetaData.importedKeyNoAction, importedKeys.getInt("UPDATE_RULE")); + assertEquals(DatabaseMetaData.importedKeyCascade, importedKeys.getInt("DELETE_RULE")); count++; } assertEquals(2, count); From ebf634889cdddce9558eca30e5ad17210d1ec74a Mon Sep 17 00:00:00 2001 From: Enrico Olivelli Date: Mon, 2 Nov 2020 16:01:03 +0100 Subject: [PATCH 7/7] Disable useSchemaName and use 'native' SchemaFactory --- herddb-thirdparty/openjpa-test/pom.xml | 2 +- .../src/main/resources/META-INF/persistence.xml | 8 ++++---- herddb-thirdparty/openjpa/pom.xml | 4 ++-- .../src/main/java/herddb/openjpa/DBDictionary.java | 1 + 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/herddb-thirdparty/openjpa-test/pom.xml b/herddb-thirdparty/openjpa-test/pom.xml index 96466f92e..c19af4fc7 100644 --- a/herddb-thirdparty/openjpa-test/pom.xml +++ b/herddb-thirdparty/openjpa-test/pom.xml @@ -40,7 +40,7 @@ org.apache.openjpa - openjpa + openjpa-persistence-jdbc 3.1.3-SNAPSHOT diff --git a/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml b/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml index 13a97460c..b983a90a2 100644 --- a/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml +++ b/herddb-thirdparty/openjpa-test/src/main/resources/META-INF/persistence.xml @@ -27,9 +27,9 @@ - @@ -41,9 +41,9 @@ true - diff --git a/herddb-thirdparty/openjpa/pom.xml b/herddb-thirdparty/openjpa/pom.xml index ac2afecec..0c7a02a88 100644 --- a/herddb-thirdparty/openjpa/pom.xml +++ b/herddb-thirdparty/openjpa/pom.xml @@ -34,8 +34,8 @@ org.apache.openjpa - openjpa - 3.1.1 + openjpa-jdbc + 3.1.3-SNAPSHOT commons-dbcp diff --git a/herddb-thirdparty/openjpa/src/main/java/herddb/openjpa/DBDictionary.java b/herddb-thirdparty/openjpa/src/main/java/herddb/openjpa/DBDictionary.java index 1dd40fc7f..5671870b9 100644 --- a/herddb-thirdparty/openjpa/src/main/java/herddb/openjpa/DBDictionary.java +++ b/herddb-thirdparty/openjpa/src/main/java/herddb/openjpa/DBDictionary.java @@ -32,6 +32,7 @@ public DBDictionary() { supportsCascadeUpdateAction = false; schemaCase = SCHEMA_CASE_LOWER; delimitedCase = SCHEMA_CASE_PRESERVE; +// useSchemaName = false; // make OpenJPA escape everything, because Apache Calcite has a lot of reserved words, like 'User', 'Value'... setDelimitIdentifiers(true);