You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2008/10/03 23:16:50 UTC
svn commit: r701537 - in /openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/
openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/
Author: faywang
Date: Fri Oct 3 14:16:50 2008
New Revision: 701537
URL: http://svn.apache.org/viewvc?rev=701537&view=rev
Log:
OPENJPA-736 use jdbc api getGeneratedKey to combine insert
and select SQL for generated id strategy = GenerationType.IDENTITY
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingPreparedStatement.java
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java?rev=701537&r1=701536&r2=701537&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedStatementManagerImpl.java Fri Oct 3 14:16:50 2008
@@ -20,9 +20,12 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
+import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
+import java.util.List;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.schema.Column;
@@ -81,27 +84,7 @@
* Flush the given row.
*/
protected void flushInternal(RowImpl row) throws SQLException {
- // can't batch rows with auto-inc columns
- Column[] autoAssign = null;
- if (row.getAction() == Row.ACTION_INSERT)
- autoAssign = row.getTable().getAutoAssignedColumns();
-
flushAndUpdate(row);
-
- // set auto assign values
- if (autoAssign != null && autoAssign.length > 0
- && row.getPrimaryKey() != null) {
- OpenJPAStateManager sm = row.getPrimaryKey();
- ClassMapping mapping = (ClassMapping) sm.getMetaData();
- Object val;
- for (int i = 0; i < autoAssign.length; i++) {
- val = _dict.getGeneratedKey(autoAssign[i], _conn);
- mapping.assertJoinable(autoAssign[i]).setAutoAssignedValue(sm,
- _store, autoAssign[i], val);
- }
- sm.setObjectId(
- ApplicationIds.create(sm.getPersistenceCapable(), mapping));
- }
}
/**
@@ -109,9 +92,12 @@
*/
protected void flushAndUpdate(RowImpl row)
throws SQLException {
+ Column[] autoAssign = getAutoAssignColumns(row);
+ String[] autoAssignColNames = getAutoAssignColNames(autoAssign, row);
+
// prepare statement
String sql = row.getSQL(_dict);
- PreparedStatement stmnt = prepareStatement(sql);
+ PreparedStatement stmnt = prepareStatement(sql, autoAssignColNames);
// setup parameters and execute statement
if (stmnt != null)
@@ -127,6 +113,9 @@
"update-failed-no-failed-obj", String.valueOf(count),
sql).getMessage());
}
+ if (autoAssignColNames != null)
+ populateAutoAssignCols(stmnt, autoAssign, autoAssignColNames, row);
+
} catch (SQLException se) {
throw SQLExceptions.getStore(se, row.getFailedObject(), _dict);
} finally {
@@ -138,6 +127,78 @@
}
}
}
+
+ /**
+ * This method will only be called when there is auto assign columns.
+ * If database supports getGeneratedKeys, the keys will be obtained
+ * from the result set associated with the stmnt. If not, a separate
+ * sql to select the key will be issued from DBDictionary.
+ */
+ protected List populateAutoAssignCols(PreparedStatement stmnt,
+ Column[] autoAssign, String[] autoAssignColNames, RowImpl row)
+ throws SQLException {
+ List vals = null;
+ if (_dict.supportsGetGeneratedKeys) {
+ // set auto assign values to id col
+ vals = getGeneratedKeys(stmnt, autoAssignColNames);
+ }
+ setObjectId(vals, autoAssign, autoAssignColNames, row);
+ return vals;
+ }
+
+ protected void setObjectId(List vals, Column[] autoAssign,
+ String[] autoAssignColNames, RowImpl row)
+ throws SQLException{
+ OpenJPAStateManager sm = row.getPrimaryKey();
+ ClassMapping mapping = (ClassMapping) sm.getMetaData();
+ Object val = null;
+ for (int i = 0; i < autoAssign.length; i++) {
+ if (_dict.supportsGetGeneratedKeys && vals != null &&
+ vals.size() > 0)
+ val = vals.get(i);
+ else
+ val = _dict.getGeneratedKey(autoAssign[i], _conn);
+ mapping.assertJoinable(autoAssign[i]).setAutoAssignedValue(sm,
+ _store, autoAssign[i], val);
+ }
+ sm.setObjectId(
+ ApplicationIds.create(sm.getPersistenceCapable(), mapping));
+ }
+
+ /**
+ * This method will only be called when the database supports
+ * getGeneratedKeys.
+ */
+ protected List getGeneratedKeys(PreparedStatement stmnt,
+ String[] autoAssignColNames)
+ throws SQLException {
+ ResultSet rs = stmnt.getGeneratedKeys();
+ List vals = new ArrayList();
+ while (rs.next()) {
+ for (int i = 0; i < autoAssignColNames.length; i++)
+ vals.add(rs.getObject(autoAssignColNames[i]));
+ }
+ rs.close();
+ return vals;
+ }
+
+ protected Column[] getAutoAssignColumns(RowImpl row) {
+ Column[] autoAssign = null;
+ if (row.getAction() == Row.ACTION_INSERT)
+ autoAssign = row.getTable().getAutoAssignedColumns();
+ return autoAssign;
+ }
+
+ protected String[] getAutoAssignColNames(Column[] autoAssign, RowImpl row) {
+ String[] autoAssignColNames = null;
+ if (autoAssign != null && autoAssign.length > 0
+ && row.getPrimaryKey() != null) {
+ autoAssignColNames = new String[autoAssign.length];
+ for (int i = 0; i < autoAssign.length; i++)
+ autoAssignColNames[i] = autoAssign[i].getName();
+ }
+ return autoAssignColNames;
+ }
public void flush() {
}
@@ -150,13 +211,26 @@
RowImpl row) throws SQLException {
return stmnt.executeUpdate();
}
-
+
+ /**
+ * This method is to provide override for non-JDBC or JDBC-like
+ * implementation of preparing statement.
+ */
+ protected PreparedStatement prepareStatement(String sql)
+ throws SQLException {
+ return prepareStatement(sql, null);
+ }
/**
* This method is to provide override for non-JDBC or JDBC-like
* implementation of preparing statement.
*/
- protected PreparedStatement prepareStatement(String sql)
+ protected PreparedStatement prepareStatement(String sql,
+ String[] autoAssignColNames)
throws SQLException {
- return _conn.prepareStatement(sql);
+ // pass in AutoAssignColumn names
+ if (autoAssignColNames != null && _dict.supportsGetGeneratedKeys)
+ return _conn.prepareStatement(sql, autoAssignColNames);
+ else
+ return _conn.prepareStatement(sql);
}
}
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=701537&r1=701536&r2=701537&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Fri Oct 3 14:16:50 2008
@@ -193,6 +193,7 @@
public boolean supportsAlterTableWithAddColumn = true;
public boolean supportsAlterTableWithDropColumn = true;
public boolean supportsComments = false;
+ public boolean supportsGetGeneratedKeys = false;
public String reservedWords = null;
public String systemSchemas = null;
public String systemTables = null;
@@ -393,6 +394,7 @@
// JDBC3-only method, so it might throw a
// AbstractMethodError
isJDBC3 = metaData.getJDBCMajorVersion() >= 3;
+ supportsGetGeneratedKeys = metaData.supportsGetGeneratedKeys();
} catch (Throwable t) {
// ignore if not JDBC3
}
Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingPreparedStatement.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingPreparedStatement.java?rev=701537&r1=701536&r2=701537&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingPreparedStatement.java (original)
+++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingPreparedStatement.java Fri Oct 3 14:16:50 2008
@@ -415,7 +415,7 @@
}
public ResultSet getGeneratedKeys() throws SQLException {
- throw new UnsupportedOperationException();
+ return _stmnt.getGeneratedKeys();
}
public int executeUpdate(String s, int i) throws SQLException {