You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by ht...@apache.org on 2014/05/01 05:10:57 UTC
svn commit: r1591540 - in /openjpa/branches/2.3.x: ./
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/
openj...
Author: hthomann
Date: Thu May 1 03:10:56 2014
New Revision: 1591540
URL: http://svn.apache.org/r1591540
Log:
OPENJPA-2476: Fixed OptimisticLockEx due to rounding of a Timestamp
Added:
openjpa/branches/2.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/
- copied from r1591536, openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/
openjpa/branches/2.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/timestamp/
- copied from r1591536, openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/timestamp/
openjpa/branches/2.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/timestamp/TestTimestampOptLockEx.java
- copied unchanged from r1591536, openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/timestamp/TestTimestampOptLockEx.java
openjpa/branches/2.3.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/timestamp/VersionTSEntity.java
- copied unchanged from r1591536, openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/optlockex/timestamp/VersionTSEntity.java
Modified:
openjpa/branches/2.3.x/ (props changed)
openjpa/branches/2.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
openjpa/branches/2.3.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
Propchange: openjpa/branches/2.3.x/
------------------------------------------------------------------------------
Merged /openjpa/branches/2.1.x:r1591536
Modified: openjpa/branches/2.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=1591540&r1=1591539&r2=1591540&view=diff
==============================================================================
--- openjpa/branches/2.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original)
+++ openjpa/branches/2.3.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Thu May 1 03:10:56 2014
@@ -96,6 +96,7 @@ import org.apache.openjpa.jdbc.schema.Fo
import org.apache.openjpa.kernel.Filters;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.Seq;
+import org.apache.openjpa.kernel.StateManagerImpl;
import org.apache.openjpa.kernel.exps.Path;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
@@ -1287,24 +1288,13 @@ public class DBDictionary
public void setTimestamp(PreparedStatement stmnt, int idx,
Timestamp val, Calendar cal, Column col)
throws SQLException {
- // ensure that we do not insert dates at a greater precision than
- // that at which they will be returned by a SELECT
- int rounded = (int) Math.round(val.getNanos() /
- (double) datePrecision);
- int nanos = rounded * datePrecision;
- if (nanos > 999999999) {
- // rollover to next second
- val.setTime(val.getTime() + 1000);
- nanos = 0;
- }
- Timestamp valForStmnt = new Timestamp(val.getTime());
- valForStmnt.setNanos(nanos);
-
+ val = StateManagerImpl.roundTimestamp(val, datePrecision);
+
if (cal == null)
- stmnt.setTimestamp(idx, valForStmnt);
+ stmnt.setTimestamp(idx, val);
else
- stmnt.setTimestamp(idx, valForStmnt, cal);
+ stmnt.setTimestamp(idx, val, cal);
}
/**
Modified: openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=1591540&r1=1591539&r2=1591540&view=diff
==============================================================================
--- openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ openjpa/branches/2.3.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Thu May 1 03:10:56 2014
@@ -25,6 +25,7 @@ import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Modifier;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
@@ -159,6 +160,8 @@ public class StateManagerImpl implements
private transient ReentrantLock _instanceLock = null;
+ private int _datePrecision = -1;
+
/**
* <p>set to <code>false</code> to prevent the postLoad method from
* sending lifecycle callback events.</p>
@@ -716,13 +719,48 @@ public class StateManagerImpl implements
public void setNextVersion(Object version) {
assignVersionField(version);
}
+
+ public static Timestamp roundTimestamp(Timestamp val, int datePrecision) {
+ // ensure that we do not insert dates at a greater precision than
+ // that at which they will be returned by a SELECT
+ int rounded = (int) Math.round(val.getNanos() / (double) datePrecision);
+ long time = val.getTime();
+ int nanos = rounded * datePrecision;
+ if (nanos > 999999999) {
+ // rollover to next second
+ time = time + 1000;
+ nanos = 0;
+ }
+ val = new Timestamp(time);
+ val.setNanos(nanos);
+ return val;
+ }
+
private void assignVersionField(Object version) {
+
+ if (version instanceof Timestamp) {
+ if (_datePrecision == -1) {
+ try {
+ OpenJPAConfiguration conf = _broker.getConfiguration();
+ Class confCls = Class.forName("org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl");
+ if (confCls.isAssignableFrom(conf.getClass())) {
+ Object o = conf.getClass().getMethod("getDBDictionaryInstance").invoke(conf, (Object[]) null);
+ _datePrecision = o.getClass().getField("datePrecision").getInt(o);
+ } else {
+ _datePrecision = 1000;
+ }
+ } catch (Throwable e) {
+ _datePrecision = 1000;
+ }
+ }
+
+ version = roundTimestamp((Timestamp) version, _datePrecision);
+ }
_version = version;
FieldMetaData vfield = _meta.getVersionField();
if (vfield != null)
- store(vfield.getIndex(), JavaTypes.convert(version,
- vfield.getTypeCode()));
+ store(vfield.getIndex(), JavaTypes.convert(version, vfield.getTypeCode()));
}
public PCState getPCState() {
Modified: openjpa/branches/2.3.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/2.3.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml?rev=1591540&r1=1591539&r2=1591540&view=diff
==============================================================================
--- openjpa/branches/2.3.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml (original)
+++ openjpa/branches/2.3.x/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml Thu May 1 03:10:56 2014
@@ -1405,9 +1405,36 @@ This value is usually one million, meani
to store time values with a precision of one millisecond. Particular
databases may have more or less precision.
OpenJPA will round all time values to this degree of precision
-before storing them in the database.
-Defaults to 1000000.
- </para>
+before storing them in the database. This property can be set to one
+of the following precisions:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+<literal>DECI</literal>: 100000000
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<literal>CENIT</literal>: 10000000
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<literal>MILLI (default precision)</literal>: 1000000
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<literal>MICRO</literal>: 1000
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<literal>NANO (max precision)</literal>: 1
+ </para>
+ </listitem>
+ </itemizedlist>
</listitem>
<listitem id="DBDictionary.DateMillisecondBehavior">
<para>