mirror of
https://github.com/apache/openjpa.git
synced 2025-03-06 16:39:11 +00:00
OPENJPA-2453: Add support to retain milliseconds of 'un-rounded' Date field.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1566872 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
731649a2c9
commit
d802d74930
@ -301,7 +301,31 @@ public class DBDictionary
|
||||
public int maxEmbeddedClobSize = -1;
|
||||
public int inClauseLimit = -1;
|
||||
public int datePrecision = MILLI;
|
||||
|
||||
/**
|
||||
* @deprecated Use 'dateMillisecondBehavior' instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean roundTimeToMillisec = true;
|
||||
|
||||
/*
|
||||
* This defines how the milliseconds of a Date field are handled
|
||||
* when the Date is retrieved from the database, as follows:
|
||||
*
|
||||
* ROUND: This is the default. The
|
||||
* Date will be rounded to the nearest millisecond.
|
||||
* DROP: The milliseconds will be dropped, thus rounding is not
|
||||
* performed. As an example, a date of '2010-01-01 12:00:00.687701'
|
||||
* stored in the database will become '2010-01-01 12:00:00.000' in
|
||||
* the Date field of the entity.
|
||||
* RETAIN: The milliseconds will not be rounded and retained. As an
|
||||
* example, a date of '2010-01-01 12:00:00.687701' stored in the
|
||||
* database will become '2010-01-01 12:00:00.687' in the Date field
|
||||
* of the entity.
|
||||
*/
|
||||
public enum DateMillisecondBehaviors { DROP, ROUND, RETAIN };
|
||||
private DateMillisecondBehaviors dateMillisecondBehavior;
|
||||
|
||||
public int characterColumnSize = 255;
|
||||
public String arrayTypeName = "ARRAY";
|
||||
public String bigintTypeName = "BIGINT";
|
||||
@ -793,8 +817,16 @@ public class DBDictionary
|
||||
// get the fractional seconds component, rounding away anything beyond
|
||||
// milliseconds
|
||||
int fractional = 0;
|
||||
if (roundTimeToMillisec) {
|
||||
fractional = (int) Math.round(tstamp.getNanos() / (double) MILLI);
|
||||
switch (getMillisecondBehavior()) {
|
||||
case DROP :
|
||||
fractional = 0;
|
||||
break;
|
||||
case RETAIN :
|
||||
fractional = (int) (tstamp.getNanos() / (double) MILLI);
|
||||
break;
|
||||
case ROUND :
|
||||
fractional = (int) Math.round(tstamp.getNanos() / (double) MILLI);
|
||||
break;
|
||||
}
|
||||
|
||||
// get the millis component; some JDBC drivers round this to the
|
||||
@ -5622,6 +5654,33 @@ public class DBDictionary
|
||||
|
||||
public String getIdentityColumnName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default behavior is ROUND
|
||||
*/
|
||||
public DateMillisecondBehaviors getMillisecondBehavior() {
|
||||
// If the user hasn't configured this property, fall back
|
||||
// to looking at the old property in the mean time till
|
||||
// we can get rid of it.
|
||||
if (dateMillisecondBehavior == null) {
|
||||
if (roundTimeToMillisec) {
|
||||
dateMillisecondBehavior = DateMillisecondBehaviors.ROUND;
|
||||
} else {
|
||||
dateMillisecondBehavior = DateMillisecondBehaviors.DROP;
|
||||
}
|
||||
}
|
||||
return dateMillisecondBehavior;
|
||||
}
|
||||
|
||||
public void setDateMillisecondBehavior(String str) {
|
||||
if (str != null) {
|
||||
// Tolerate different case
|
||||
str = str.toUpperCase();
|
||||
dateMillisecondBehavior = DateMillisecondBehaviors.valueOf(str);
|
||||
} else {
|
||||
dateMillisecondBehavior = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isUsingRange(long start, long end) {
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.apache.openjpa.persistence.temporal;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -31,8 +32,8 @@ import org.apache.openjpa.persistence.OpenJPAEntityManager;
|
||||
import org.apache.openjpa.persistence.test.SQLListenerTestCase;
|
||||
|
||||
public class TestTemporalTimestamp extends SQLListenerTestCase {
|
||||
private OpenJPAEntityManager em;
|
||||
|
||||
private OpenJPAEntityManager em;
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
|
||||
public void setUp() {
|
||||
setSupportedDatabases(
|
||||
@ -42,8 +43,34 @@ public class TestTemporalTimestamp extends SQLListenerTestCase {
|
||||
return;
|
||||
}
|
||||
|
||||
setUp(CLEAR_TABLES, TemporalEntity.class, "openjpa.jdbc.DBDictionary", "RoundTimeToMillisec=false");
|
||||
setUp(CLEAR_TABLES, TemporalEntity.class, "openjpa.jdbc.DBDictionary",
|
||||
"DateMillisecondBehavior=" + DBDictionary.DateMillisecondBehaviors.DROP,
|
||||
"openjpa.Log", "SQL=TRACE,Tests=TRACE", "openjpa.ConnectionFactoryProperties"
|
||||
,"PrintParameters=true");
|
||||
assertNotNull(emf);
|
||||
// noRound:
|
||||
// expected:<253402322399000> but was:<253402325999000>
|
||||
/* Date got = new Date(253402322399000L);
|
||||
Date exp = new Date(253402325999000L);
|
||||
System.out.println("NoRounding");
|
||||
System.out.println("Got = " + sdf.format(got).toString());
|
||||
System.out.println("Exp = " + sdf.format(exp).toString());
|
||||
*/
|
||||
//testNoRoundingNoMillisecondLoss
|
||||
//expected:<253402322399999> but was:<253402325999999>
|
||||
/* got = new Date(253402322399999L);
|
||||
exp = new Date(253402325999999L);
|
||||
System.out.println("testNoRoundingNoMillisecondLoss");
|
||||
System.out.println("Got = " + sdf.format(got).toString());
|
||||
System.out.println("Exp = " + sdf.format(exp).toString());
|
||||
*/
|
||||
//expected:<253402322400000> but was:<253402326000000>
|
||||
/* got = new Date(253402322400000L);
|
||||
exp = new Date(253402326000000L);
|
||||
System.out.println("testRounding");
|
||||
System.out.println("Got = " + sdf.format(got).toString());
|
||||
System.out.println("Exp = " + sdf.format(exp).toString());
|
||||
*/
|
||||
|
||||
loadDB();
|
||||
}
|
||||
@ -62,6 +89,32 @@ public class TestTemporalTimestamp extends SQLListenerTestCase {
|
||||
assertEquals(testDate.getMinutes(), 59);
|
||||
assertEquals(testDate.getSeconds(), 59);
|
||||
assertEquals(testDate.getYear(), 8099);
|
||||
assertTrue(sdf.format(testDate).toString().endsWith(".000"));
|
||||
}
|
||||
em.close();
|
||||
}
|
||||
|
||||
public void testNoRoundingNoMillisecondLoss() {
|
||||
JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
|
||||
DBDictionary dict = conf.getDBDictionaryInstance();
|
||||
dict.setDateMillisecondBehavior(DBDictionary.DateMillisecondBehaviors.RETAIN.toString());
|
||||
|
||||
em = emf.createEntityManager();
|
||||
final List<TemporalEntity> temporalEntityList = findAll(em);
|
||||
assertNotNull(temporalEntityList);
|
||||
assertNotEquals(temporalEntityList.size(), 0);
|
||||
for (final TemporalEntity temporalEntity : temporalEntityList) {
|
||||
Date testDate = temporalEntity.getTestDate();
|
||||
assertEquals(testDate.getDay(), 5);
|
||||
assertEquals(testDate.getMonth(), 11);
|
||||
assertEquals(testDate.getDate(), 31);
|
||||
assertEquals(testDate.getHours(), 23);
|
||||
assertEquals(testDate.getMinutes(), 59);
|
||||
assertEquals(testDate.getSeconds(), 59);
|
||||
assertEquals(testDate.getYear(), 8099);
|
||||
assertTrue(sdf.format(testDate).toString().endsWith(".999"));
|
||||
System.out.println("sdf.format(testDate).toString() = " +
|
||||
sdf.format(testDate).toString());
|
||||
}
|
||||
em.close();
|
||||
}
|
||||
@ -70,7 +123,7 @@ public class TestTemporalTimestamp extends SQLListenerTestCase {
|
||||
JDBCConfiguration conf = (JDBCConfiguration) emf.getConfiguration();
|
||||
DBDictionary dict = conf.getDBDictionaryInstance();
|
||||
// set value back to default
|
||||
dict.roundTimeToMillisec = true;
|
||||
dict.setDateMillisecondBehavior(DBDictionary.DateMillisecondBehaviors.ROUND.toString());
|
||||
|
||||
em = emf.createEntityManager();
|
||||
final List<TemporalEntity> temporalEntityList = findAll(em);
|
||||
@ -85,6 +138,8 @@ public class TestTemporalTimestamp extends SQLListenerTestCase {
|
||||
assertEquals(testDate.getMinutes(), 0);
|
||||
assertEquals(testDate.getSeconds(), 0);
|
||||
assertEquals(testDate.getYear(), 8100);
|
||||
// assertEquals(testDate.getTime(), 253402326000000L);
|
||||
assertTrue(sdf.format(testDate).toString().endsWith(".000"));
|
||||
}
|
||||
em.close();
|
||||
}
|
||||
|
@ -1409,6 +1409,53 @@ before storing them in the database.
|
||||
Defaults to 1000000.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem id="DBDictionary.DateMillisecondBehavior">
|
||||
<para>
|
||||
<indexterm>
|
||||
<primary>
|
||||
JDBC
|
||||
</primary>
|
||||
<secondary>
|
||||
DateMillisecondBehavior
|
||||
</secondary>
|
||||
</indexterm>
|
||||
<literal>DateMillisecondBehavior</literal>:
|
||||
When retrieving a <literal>Date</literal> value from a database which stores the value in
|
||||
a TIMESTAMP column, the values retrieved will be rounded to the nearest
|
||||
millisecond. So a date of '2010-01-01 12:00:00.687701' stored in the
|
||||
database will become '2010-01-01 12:00:00.688' in the <literal>Date</literal> field of the
|
||||
entity. The following date stored in the database as '9999-12-31 23:59:59.9999'
|
||||
will become '10000-01-01 00:00:00.000'. This rounding may not be desirable. With this
|
||||
property, a user has options which will direct OpenJPA how to handle the milliseconds. This
|
||||
property can be set to one of the enums defined in
|
||||
<literal>DBDictionary.DateMillisecondBehaviors</literal>. The options defined in
|
||||
<literal>DBDictionary.DateMillisecondBehaviors</literal> are as follows:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>DateMillisecondBehaviors.ROUND</literal>: This is the default. The
|
||||
<literal>Date</literal> will be rounded to the nearest millisecond, as described above.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>DateMillisecondBehaviors.DROP</literal>: The milliseconds will be dropped, thus
|
||||
rounding is not performed. As an example, a date of '2010-01-01 12:00:00.687701' stored in the
|
||||
database will become '2010-01-01 12:00:00.000' in the <literal>Date</literal> field of the
|
||||
entity.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<literal>DateMillisecondBehaviors.RETAIN</literal>: The milliseconds will not be rounded, but will
|
||||
be retained. As an example, a date of '2010-01-01 12:00:00.687701' stored in the
|
||||
database will become '2010-01-01 12:00:00.687' in the <literal>Date</literal> field of the
|
||||
entity.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem id="DBDictionary.DateTypeName">
|
||||
<para>
|
||||
<indexterm>
|
||||
|
Loading…
x
Reference in New Issue
Block a user