OPENJPA-736: JDBC 3 way of retrieving generated keys - allow user to disable it, doc and test updates.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@780260 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Milosz Tylenda 2009-05-30 13:22:56 +00:00
parent e80110bdd1
commit cb98d4fc33
3 changed files with 75 additions and 18 deletions

View File

@ -196,7 +196,7 @@ public class DBDictionary
public boolean supportsAlterTableWithAddColumn = true; public boolean supportsAlterTableWithAddColumn = true;
public boolean supportsAlterTableWithDropColumn = true; public boolean supportsAlterTableWithDropColumn = true;
public boolean supportsComments = false; public boolean supportsComments = false;
public boolean supportsGetGeneratedKeys = false; public Boolean supportsGetGeneratedKeys = null;
public String reservedWords = null; public String reservedWords = null;
public String systemSchemas = null; public String systemSchemas = null;
public String systemTables = null; public String systemTables = null;
@ -435,8 +435,6 @@ public class DBDictionary
// JDBC3-only method, so it might throw a // JDBC3-only method, so it might throw a
// AbstractMethodError // AbstractMethodError
isJDBC3 = metaData.getJDBCMajorVersion() >= 3; isJDBC3 = metaData.getJDBCMajorVersion() >= 3;
supportsGetGeneratedKeys =
metaData.supportsGetGeneratedKeys();
} catch (Throwable t) { } catch (Throwable t) {
// ignore if not JDBC3 // ignore if not JDBC3
} }
@ -457,6 +455,17 @@ public class DBDictionary
// While we have the metaData, set some values from it // While we have the metaData, set some values from it
setSupportsDelimitedIds(metaData); setSupportsDelimitedIds(metaData);
setDelimitedCase(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; connected = true;
} }

View File

@ -19,18 +19,23 @@
package org.apache.openjpa.persistence.identity; package org.apache.openjpa.persistence.identity;
import java.util.List; import java.util.List;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction; import javax.persistence.EntityTransaction;
import javax.persistence.Query; import javax.persistence.Query;
import junit.framework.TestCase;
import junit.textui.TestRunner; import junit.textui.TestRunner;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.persistence.OpenJPAEntityManager; import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.test.SingleEMFTestCase; 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 * @author Kevin Sutter
*/ */
@ -38,13 +43,25 @@ public class TestGenerationType
extends SingleEMFTestCase { extends SingleEMFTestCase {
public void setUp() { public void setUp() {
if (getName().endsWith("WithoutGetGeneratedKeys")) {
setUp(IdentityGenerationType.class,
"openjpa.jdbc.DBDictionary",
"supportsGetGeneratedKeys=false");
} else {
setUp(IdentityGenerationType.class); setUp(IdentityGenerationType.class);
} }
}
/**
* Not all databases support GenerationType.IDENTITY column(s).
*/
private boolean supportsAutoAssign() {
return ((JDBCConfiguration) emf.getConfiguration())
.getDBDictionaryInstance().supportsAutoAssign;
}
public void testCreateEntityManager() { public void testCreateEntityManager() {
// Not all databases support GenerationType.IDENTITY column(s) if (!supportsAutoAssign()) {
if (!((JDBCConfiguration) emf.getConfiguration()).
getDBDictionaryInstance().supportsAutoAssign) {
return; return;
} }
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
@ -64,9 +81,7 @@ public class TestGenerationType
} }
public void testPersist() { public void testPersist() {
// Not all databases support GenerationType.IDENTITY column(s) if (!supportsAutoAssign()) {
if (!((JDBCConfiguration) emf.getConfiguration()).
getDBDictionaryInstance().supportsAutoAssign) {
return; return;
} }
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
@ -77,9 +92,7 @@ public class TestGenerationType
} }
public void testQuery() { public void testQuery() {
// Not all databases support GenerationType.IDENTITY column(s) if (!supportsAutoAssign()) {
if (!((JDBCConfiguration) emf.getConfiguration()).
getDBDictionaryInstance().supportsAutoAssign) {
return; return;
} }
EntityManager em = emf.createEntityManager(); EntityManager em = emf.createEntityManager();
@ -98,6 +111,14 @@ public class TestGenerationType
em.close(); em.close();
} }
public void testPersistWithoutGetGeneratedKeys() {
testPersist();
}
public void testQueryWithoutGetGeneratedKeys() {
testQuery();
}
public static void main(String[] args) { public static void main(String[] args) {
TestRunner.run(TestGenerationType.class); TestRunner.run(TestGenerationType.class);
} }

View File

@ -1467,6 +1467,9 @@ See <xref linkend="ref_guide_dbsetup_sql92"/>.
automatically generated key for an auto-increment column. For example, automatically generated key for an auto-increment column. For example,
<literal>"SELECT LAST_INSERT_ID()"</literal> for MySQL. This property is set <literal>"SELECT LAST_INSERT_ID()"</literal> for MySQL. This property is set
automatically in the dictionary, and should not need to be overridden. automatically in the dictionary, and should not need to be overridden.
If <literal>SupportsGetGeneratedKeys</literal> is true, the query will not
be issued but a more efficient JDBC 3.0 mechanism for obtaining generated
keys will be used instead.
</para> </para>
</listitem> </listitem>
<listitem id="DBDictionary.LongVarbinaryTypeName"> <listitem id="DBDictionary.LongVarbinaryTypeName">
@ -2320,6 +2323,30 @@ transaction. Defaults to <literal>true</literal>.
keys. Defaults to <literal>true</literal>. keys. Defaults to <literal>true</literal>.
</para> </para>
</listitem> </listitem>
<listitem id="DBDictionary.SupportsGetGeneratedKeys">
<para>
<indexterm>
<primary>
persistent fields
</primary>
<secondary>
automatic field values
</secondary>
<tertiary>
SupportsGetGeneratedKeys
</tertiary>
</indexterm>
<literal>SupportsGetGeneratedKeys</literal>: When true, OpenJPA will use
<methodname>java.sql.Statement.getGeneratedKeys</methodname> method to obtain
values of auto-increment columns. When false, a query specified by
<literal>LastGeneratedKeyQuery</literal> 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 <methodname>java.sql.Statement.getGeneratedKeys</methodname>
method.
</para>
</listitem>
<listitem id="DBDictionary.SupportsHaving"> <listitem id="DBDictionary.SupportsHaving">
<para> <para>
<indexterm> <indexterm>