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 515f40524..b77a26707 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 @@ -196,7 +196,7 @@ public class DBDictionary public boolean supportsAlterTableWithAddColumn = true; public boolean supportsAlterTableWithDropColumn = true; public boolean supportsComments = false; - public boolean supportsGetGeneratedKeys = false; + public Boolean supportsGetGeneratedKeys = null; public String reservedWords = null; public String systemSchemas = null; public String systemTables = null; @@ -435,8 +435,6 @@ public class DBDictionary // JDBC3-only method, so it might throw a // AbstractMethodError isJDBC3 = metaData.getJDBCMajorVersion() >= 3; - supportsGetGeneratedKeys = - metaData.supportsGetGeneratedKeys(); } catch (Throwable t) { // ignore if not JDBC3 } @@ -457,6 +455,17 @@ public class DBDictionary // While we have the metaData, set some values from it setSupportsDelimitedIds(metaData); setDelimitedCase(metaData); + + // Auto-detect generated keys retrieval support + // unless user specified it. + if (supportsGetGeneratedKeys == null) { + if (isJDBC3) { + supportsGetGeneratedKeys = + metaData.supportsGetGeneratedKeys(); + } else { + supportsGetGeneratedKeys = false; + } + } } connected = true; } diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestGenerationType.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestGenerationType.java index 4c9c9cd51..c70851a66 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestGenerationType.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/identity/TestGenerationType.java @@ -19,18 +19,23 @@ package org.apache.openjpa.persistence.identity; import java.util.List; + import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; import javax.persistence.Query; -import junit.framework.TestCase; import junit.textui.TestRunner; + import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.persistence.OpenJPAEntityManager; import org.apache.openjpa.persistence.test.SingleEMFTestCase; /** - * Simple test case to test the GenerationType for @Id... + * Simple test case to test the GenerationType for + * {@link javax.persistence.Id}. + * Tests both ways of generated keys retrieval: separate query + * and JDBC3 {@link java.sql.Statement#getGeneratedKeys} + * if the database supports them. * * @author Kevin Sutter */ @@ -38,14 +43,26 @@ public class TestGenerationType extends SingleEMFTestCase { public void setUp() { - setUp(IdentityGenerationType.class); + if (getName().endsWith("WithoutGetGeneratedKeys")) { + setUp(IdentityGenerationType.class, + "openjpa.jdbc.DBDictionary", + "supportsGetGeneratedKeys=false"); + } else { + setUp(IdentityGenerationType.class); + } } + /** + * Not all databases support GenerationType.IDENTITY column(s). + */ + private boolean supportsAutoAssign() { + return ((JDBCConfiguration) emf.getConfiguration()) + .getDBDictionaryInstance().supportsAutoAssign; + } + public void testCreateEntityManager() { - // Not all databases support GenerationType.IDENTITY column(s) - if (!((JDBCConfiguration) emf.getConfiguration()). - getDBDictionaryInstance().supportsAutoAssign) { - return; + if (!supportsAutoAssign()) { + return; } EntityManager em = emf.createEntityManager(); @@ -64,10 +81,8 @@ public class TestGenerationType } public void testPersist() { - // Not all databases support GenerationType.IDENTITY column(s) - if (!((JDBCConfiguration) emf.getConfiguration()). - getDBDictionaryInstance().supportsAutoAssign) { - return; + if (!supportsAutoAssign()) { + return; } EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); @@ -77,10 +92,8 @@ public class TestGenerationType } public void testQuery() { - // Not all databases support GenerationType.IDENTITY column(s) - if (!((JDBCConfiguration) emf.getConfiguration()). - getDBDictionaryInstance().supportsAutoAssign) { - return; + if (!supportsAutoAssign()) { + return; } EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); @@ -98,6 +111,14 @@ public class TestGenerationType em.close(); } + public void testPersistWithoutGetGeneratedKeys() { + testPersist(); + } + + public void testQueryWithoutGetGeneratedKeys() { + testQuery(); + } + public static void main(String[] args) { TestRunner.run(TestGenerationType.class); } diff --git a/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml b/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml index 29f5da46b..e06a685f3 100644 --- a/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml +++ b/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml @@ -1467,6 +1467,9 @@ See . automatically generated key for an auto-increment column. For example, "SELECT LAST_INSERT_ID()" for MySQL. This property is set automatically in the dictionary, and should not need to be overridden. +If SupportsGetGeneratedKeys is true, the query will not +be issued but a more efficient JDBC 3.0 mechanism for obtaining generated +keys will be used instead. @@ -2320,6 +2323,30 @@ transaction. Defaults to true. keys. Defaults to true. + + + + + persistent fields + + + automatic field values + + + SupportsGetGeneratedKeys + + +SupportsGetGeneratedKeys: When true, OpenJPA will use +java.sql.Statement.getGeneratedKeys method to obtain +values of auto-increment columns. When false, a query specified by +LastGeneratedKeyQuery will be used for that purpose. +If not set, the value will be auto-detected by querying the JDBC driver. +Setting the value to true requires that the JDBC +driver supports version 3.0 or higher of the JDBC specification +and supports the java.sql.Statement.getGeneratedKeys +method. + +