[openjpa] branch master updated (1652794 -> 0530b5b)

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[openjpa] branch master updated (1652794 -> 0530b5b)

struberg
This is an automated email from the ASF dual-hosted git repository.

struberg pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git.


    from 1652794  use local connection without SSL for MySQL in Docker
     new 9461ffd  OPENJPA-2775 OPENJPA-2555 fraction of seconds in MySQL
     new 3b4c2e6  OPENJPA-2755 OPENJPA-2555 use scale to set Date fractions
     new 0530b5b  OPENJPA-2755 OPENJPA-2555 support fractions of a second

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/resources/META-INF/persistence.xml    |  3 +-
 .../org/apache/openjpa/jdbc/meta/MappingInfo.java  | 20 ++---
 .../openjpa/jdbc/schema/DynamicSchemaFactory.java  |  2 +-
 .../org/apache/openjpa/jdbc/sql/DBDictionary.java  | 53 ++++++++++++-
 .../apache/openjpa/jdbc/sql/MySQLDictionary.java   | 16 +++-
 .../openjpa/persistence/access/FieldSub3.java      |  1 +
 .../persistence/access/TestExplicitAccess.java     |  3 +
 .../persistence/kernel/TestDateQueries.java        | 89 ++++++++++++++++++++++
 .../kernel/common/apps/AllFieldTypesTest.java      | 89 ++++++++++++++++++++++
 openjpa-slice/pom.xml                              |  2 +-
 pom.xml                                            |  8 +-
 11 files changed, 258 insertions(+), 28 deletions(-)

Reply | Threaded
Open this post in threaded view
|

[openjpa] 01/03: OPENJPA-2775 OPENJPA-2555 fraction of seconds in MySQL

struberg
This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git

commit 9461ffdfcd870b1aeadf1eab3e8181c983a595b4
Author: Mark Struberg <[hidden email]>
AuthorDate: Wed Oct 31 20:51:31 2018 +0100

    OPENJPA-2775 OPENJPA-2555 fraction of seconds in MySQL
   
    This is a first fix for supporting fractions of a second in MySQL.
---
 .../src/main/resources/META-INF/persistence.xml    |  3 +-
 .../org/apache/openjpa/jdbc/meta/MappingInfo.java  | 20 +++-----
 .../org/apache/openjpa/jdbc/sql/DBDictionary.java  | 53 ++++++++++++++++++++--
 .../apache/openjpa/jdbc/sql/MySQLDictionary.java   | 16 +++++--
 .../openjpa/persistence/access/FieldSub3.java      |  1 +
 .../persistence/access/TestExplicitAccess.java     |  3 ++
 openjpa-slice/pom.xml                              |  2 +-
 pom.xml                                            |  8 ++--
 8 files changed, 79 insertions(+), 27 deletions(-)

diff --git a/openjpa-examples/jest/src/main/resources/META-INF/persistence.xml b/openjpa-examples/jest/src/main/resources/META-INF/persistence.xml
index 1f5d266..a561180 100644
--- a/openjpa-examples/jest/src/main/resources/META-INF/persistence.xml
+++ b/openjpa-examples/jest/src/main/resources/META-INF/persistence.xml
@@ -21,8 +21,7 @@
     version="1.0">
 
     <persistence-unit name="jestdemo">
-
-     <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
 
         <class>demo.Movie</class>
         <class>demo.Actor</class>
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java
index 2af5541..454e4a1 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingInfo.java
@@ -582,17 +582,17 @@ public abstract class MappingInfo implements Serializable {
             getMappingDefaults().defaultMissingInfo();
         if ((!given.isEmpty() || (!adapt && !fill))
             && given.size() != tmplates.length) {
-         // also consider when this info has columns from multiple tables
-         given = getColumns(table.getIdentifier());
-         if ((!adapt && !fill) && given.size() != tmplates.length) {
-         // try default table
-         given = getColumns("");
+            // also consider when this info has columns from multiple tables
+            given = getColumns(table.getIdentifier());
+            if ((!adapt && !fill) && given.size() != tmplates.length) {
+                // try default table
+                given = getColumns("");
                 if ((!adapt && !fill) && given.size() != tmplates.length) {
                     throw new MetaDataException(_loc.get(prefix + "-num-cols",
                             context, String.valueOf(tmplates.length),
                             String.valueOf(given.size())));
-             }
-         }
+                }
+            }
         }
 
         Column[] cols = new Column[tmplates.length];
@@ -607,12 +607,6 @@ public abstract class MappingInfo implements Serializable {
         return cols;
     }
 
-    boolean canMerge(List<Column> given, Column[] templates, boolean adapt,
-            boolean fill) {
-     return !((!given.isEmpty() || (!adapt && !fill))
-     && given.size() != templates.length);
-    }
-
     /**
      * Set the proper internal column I/O metadata for the given column's flags.
      */
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 5b09b91..233e184 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
@@ -428,6 +428,24 @@ public class DBDictionary
     protected final Set<String> systemSchemaSet = new HashSet<>();
     protected final Set<String> systemTableSet = new HashSet<>();
     protected final Set<String> fixedSizeTypeNameSet = new HashSet<>();
+
+    /**
+     * set of types that only accept a single precision...
+     */
+    protected final Set<String> fractionalTypeNameSet = new HashSet<>();
+
+    /**
+     * Default amount of digits for fractional Types.
+     * This is not supported/required by every database.
+     *
+     * This value is only being used if no explicit {@code @Column(scale=n)} is set.
+     * Use {@code @Column(scale=-1)} to disable the scale
+     * @see #fractionalTypeNameSet
+     * @see #getFractionLength(Column, String)
+     */
+    protected int defaultFractionLength = 6;
+
+
     protected final Set<String> typeModifierSet = new HashSet<>();
 
     // NamingConfiguration properties
@@ -1838,15 +1856,32 @@ public class DBDictionary
      * subclasses.
      */
     protected String appendSize(Column col, String typeName) {
-        if (fixedSizeTypeNameSet.contains(typeName.toUpperCase(Locale.ENGLISH)))
+        String upperCaseTypeName = typeName.toUpperCase(Locale.ENGLISH);
+        if (fixedSizeTypeNameSet.contains(upperCaseTypeName)) {
             return typeName;
-        if (typeName.indexOf('(') != -1)
+        }
+        if (typeName.indexOf('(') != -1) {
             return typeName;
+        }
+
 
         String size = null;
-        if (col.getSize() > 0) {
+        int colSize = col.getSize();
+
+        if (colSize<=0  && fractionalTypeNameSet.contains(upperCaseTypeName)){
+            // special handling for types with fractions
+            // Attention! We abuse @Column(scale=n)
+            // One can disable all fractions with @Column(scale=-1)
+            if (col.getDecimalDigits() != 0) { // the default
+                colSize = col.getDecimalDigits() == -1 ? 0 : col.getDecimalDigits();
+            }
+            else {
+                colSize = getFractionLength(col, typeName);
+            }
+            size = "(" + colSize + ")";
+        } else if (colSize > 0) {
             StringBuilder buf = new StringBuilder(10);
-            buf.append("(").append(col.getSize());
+            buf.append("(").append(colSize);
             if (col.getDecimalDigits() > 0)
                 buf.append(", ").append(col.getDecimalDigits());
             buf.append(")");
@@ -1857,6 +1892,16 @@ public class DBDictionary
     }
 
     /**
+     * Only get's used if no explicit scale is used.
+     * Attention! @{code @Column(scale=-1)} disables the scale of a column
+     * @return the fraction length of types which have a fraction
+     * @see #fractionalTypeNameSet
+     */
+    protected int getFractionLength(Column col, String typeName) {
+        return defaultFractionLength;
+    }
+
+    /**
      * Helper method that inserts a size clause for a given SQL type.
      *
      * @param typeName  The SQL type e.g. INT
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
index 43209f1..580fa8b 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
@@ -75,7 +75,7 @@ public class MySQLDictionary
      * combined <code>DELETE FROM foo, bar, baz</code> syntax.
      * Defaults to false, since this may fail in the presence of InnoDB tables
      * with foreign keys.
-     * @see http://dev.mysql.com/doc/refman/5.0/en/delete.html
+     * @link http://dev.mysql.com/doc/refman/5.0/en/delete.html
      */
     public boolean optimizeMultiTableDeletes = false;
 
@@ -99,6 +99,8 @@ public class MySQLDictionary
         supportsSelectStartIndex = true;
         supportsSelectEndIndex = true;
 
+
+
         concatenateFunction = "CONCAT({0},{1})";
 
         maxTableNameLength = 64;
@@ -195,11 +197,19 @@ public class MySQLDictionary
             allowsAliasInBulkClause = false;
             supportsForeignKeysComposite = false;
         }
-        if (maj > 5 || (maj == 5 && min >= 1))
+        if (maj > 5 || (maj == 5 && min >= 1)) {
             supportsXMLColumn = true;
+        }
+        if (maj > 5 || (maj == 5 && min >= 7)) {
+            // from this version on MySQL supports fractions of a second
+            timestampTypeName = "DATETIME{0}";
+            fixedSizeTypeNameSet.remove(timestampTypeName);
+            fractionalTypeNameSet.add(timestampTypeName);
+        }
 
-        if (metaData.getDriverMajorVersion() < 5)
+        if (metaData.getDriverMajorVersion() < 5) {
             driverDeserializesBlobs = true;
+        }
     }
 
     @Override
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/FieldSub3.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/FieldSub3.java
index 8bf91c8..5b8b656 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/FieldSub3.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/FieldSub3.java
@@ -22,6 +22,7 @@ import java.util.Date;
 
 import javax.persistence.Access;
 import javax.persistence.AccessType;
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/TestExplicitAccess.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/TestExplicitAccess.java
index 71e1059..f7f87b7 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/TestExplicitAccess.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/access/TestExplicitAccess.java
@@ -34,6 +34,8 @@ import org.apache.openjpa.persistence.ArgumentException;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
 import org.apache.openjpa.persistence.test.SingleEMFTestCase;
 
+// -ea -Dopenjpa.ConnectionDriverName=com.mysql.jdbc.Driver -Dopenjpa.ConnectionPassword=openjpatst
+// -Dopenjpa.ConnectionURL=jdbc:mysql://localhost:3306/openjpatst -Dopenjpa.ConnectionUserName=openjpatst
 public class TestExplicitAccess extends SingleEMFTestCase {
 
     @Override
@@ -476,6 +478,7 @@ public class TestExplicitAccess extends SingleEMFTestCase {
         fs.setName("EntitySuperName");
         // Call base setter with property access
         Date now = new Date();
+
         fs.setCreateDate(now);
 
         SuperPropertyEntity spe = new SuperPropertyEntity();
diff --git a/openjpa-slice/pom.xml b/openjpa-slice/pom.xml
index 4746a0c..74f042b 100644
--- a/openjpa-slice/pom.xml
+++ b/openjpa-slice/pom.xml
@@ -84,7 +84,7 @@
                 <dependency>
                     <groupId>mysql</groupId>
                     <artifactId>mysql-connector-java</artifactId>
-                    <version>${mysql.version}</version>
+                    <version>${mysql.connector.version}</version>
                     <scope>test</scope>
                 </dependency>
             </dependencies>
diff --git a/pom.xml b/pom.xml
index 5dbc9d8..c07884e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
         <!-- common JDBC driver versions -->
         <derby.version>10.14.2.0</derby.version>
         <hsqldb.version>2.4.1</hsqldb.version>
-        <mysql.version>8.0.12</mysql.version>
+        <mysql.connector.version>8.0.13</mysql.connector.version>
         <postgresql.version>42.2.5</postgresql.version>
         <!-- other common versions -->
         <slf4j.version>1.7.23</slf4j.version>
@@ -532,7 +532,7 @@
                 <dependency>
                     <groupId>mysql</groupId>
                     <artifactId>mysql-connector-java</artifactId>
-                    <version>${mysql.version}</version>
+                    <version>${mysql.connector.version}</version>
                     <scope>test</scope>
                 </dependency>
             </dependencies>
@@ -561,7 +561,7 @@
                 <dependency>
                     <groupId>mysql</groupId>
                     <artifactId>mysql-connector-java</artifactId>
-                    <version>${mysql.version}</version>
+                    <version>${mysql.connector.version}</version>
                     <scope>test</scope>
                 </dependency>
             </dependencies>
@@ -1403,7 +1403,7 @@
             <dependency>
                 <groupId>mysql</groupId>
                 <artifactId>mysql-connector-java</artifactId>
-                <version>${mysql.version}</version>
+                <version>${mysql.connector.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.apache.commons</groupId>

Reply | Threaded
Open this post in threaded view
|

[openjpa] 02/03: OPENJPA-2755 OPENJPA-2555 use scale to set Date fractions

struberg
In reply to this post by struberg
This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git

commit 3b4c2e6f427de1f6f1e21a9c5a0cca4e5730167e
Author: Mark Struberg <[hidden email]>
AuthorDate: Thu Nov 1 14:20:49 2018 +0100

    OPENJPA-2755 OPENJPA-2555 use scale to set Date fractions
---
 .../openjpa/jdbc/schema/DynamicSchemaFactory.java  |  2 +-
 .../apache/openjpa/jdbc/sql/MySQLDictionary.java   |  2 +-
 .../persistence/kernel/TestDateQueries.java        | 27 +++++++++++
 .../kernel/common/apps/AllFieldTypesTest.java      | 53 ++++++++++++++++++++++
 4 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java
index f6b3c92..d0e3129 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.java
@@ -251,7 +251,7 @@ public class DynamicSchemaFactory
             setSize(size);
             if (typeName != null)
                 setTypeIdentifier(DBIdentifier.newColumnDefinition(typeName));
-            if (decimals >= 0)
+            if (decimals != 0)
                 setDecimalDigits(decimals);
             return true;
         }
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
index 580fa8b..4d061f2 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/MySQLDictionary.java
@@ -99,7 +99,7 @@ public class MySQLDictionary
         supportsSelectStartIndex = true;
         supportsSelectEndIndex = true;
 
-
+        datePrecision = MICRO;
 
         concatenateFunction = "CONCAT({0},{1})";
 
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
index 4ff28de..7677340 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
@@ -27,6 +27,7 @@
  */
 package org.apache.openjpa.persistence.kernel;
 
+import java.sql.Timestamp;
 import java.text.SimpleDateFormat;
 import java.util.Collection;
 import java.util.Date;
@@ -71,6 +72,15 @@ public class TestDateQueries extends BaseKernelTest {
         startTx(_pm);
         AllFieldTypesTest test = new AllFieldTypesTest();
         test.setTestDate(_date);
+
+        // prepare scale test fields
+        Timestamp tst = new Timestamp(1000000000L);
+        tst.setNanos(123456789);
+        test.setTestDateMaxScale(tst);
+        test.setTestDateScale0(tst);
+        test.setTestDateScale3(tst);
+        test.setTestDateScale6(tst);
+
         _pm.persist(test);
 
         test = new AllFieldTypesTest();
@@ -81,6 +91,8 @@ public class TestDateQueries extends BaseKernelTest {
         test.setTestDate(_after);
         _pm.persist(test);
         endTx(_pm);
+
+        _pm.clear();
     }
 
     public void testEquals() {
@@ -95,6 +107,21 @@ public class TestDateQueries extends BaseKernelTest {
         assertEquals(2, vals.size());
     }
 
+    public void testDateScale() {
+        Timestamp referenceTst = new Timestamp(1000000000L);
+
+        Collection vals = executeQuery("testDate = :date");
+        AllFieldTypesTest aft = (AllFieldTypesTest) vals.iterator().next();
+        assertNotNull(aft);
+
+        long time = aft.getTestDateMaxScale().getTime();
+        long nanos = aft.getTestDateMaxScale().getNanos();
+
+        // cut of the ms
+        assertEquals(referenceTst, time - (time%1000));
+
+    }
+
     public void testBefore() {
         Collection vals = executeQuery("testDate < :date");
         assertEquals(1, vals.size());
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
index 00bca61..eb99c3c 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
@@ -20,10 +20,12 @@ package org.apache.openjpa.persistence.kernel.common.apps;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
 
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
@@ -55,10 +57,28 @@ public class AllFieldTypesTest {
     private char testchar;
     private String testString;
     private String testBigString;
+
     @Temporal(TemporalType.DATE)
     private Date testDate;
+
     @Temporal(TemporalType.DATE)
     private Calendar testCalendar;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(scale=-1)
+    private Timestamp testDateScale0;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(scale=3)
+    private Timestamp testDateScale3;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(scale=6)
+    private Timestamp testDateScale6;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    private Timestamp testDateMaxScale;
+
     private Object testObject;
     private BigInteger testBigInteger;
     private BigDecimal testBigDecimal;
@@ -188,6 +208,39 @@ public class AllFieldTypesTest {
         this.testBigDecimal = testBigDecimal;
     }
 
+    public Timestamp getTestDateScale0() {
+        return testDateScale0;
+    }
+
+    public void setTestDateScale0(Timestamp testDateScale0) {
+        this.testDateScale0 = testDateScale0;
+    }
+
+    public Timestamp getTestDateScale3() {
+        return testDateScale3;
+    }
+
+    public void setTestDateScale3(Timestamp testDateScale3) {
+        this.testDateScale3 = testDateScale3;
+    }
+
+    public Timestamp getTestDateScale6() {
+        return testDateScale6;
+    }
+
+    public void setTestDateScale6(Timestamp testDateScale6) {
+        this.testDateScale6 = testDateScale6;
+    }
+
+    public Timestamp getTestDateMaxScale() {
+        return testDateMaxScale;
+    }
+
+    public void setTestDateMaxScale(Timestamp testDateMaxScale) {
+        this.testDateMaxScale = testDateMaxScale;
+    }
+
+
     public void randomize(boolean objects, boolean blobs) {
         testint = AbstractTestCase.randomInt().intValue();
         testlong = AbstractTestCase.randomLong().longValue();

Reply | Threaded
Open this post in threaded view
|

[openjpa] 03/03: OPENJPA-2755 OPENJPA-2555 support fractions of a second

struberg
In reply to this post by struberg
This is an automated email from the ASF dual-hosted git repository.

struberg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git

commit 0530b5b72ba00a3014e67c9ee4c3e8bfcddabb76
Author: Mark Struberg <[hidden email]>
AuthorDate: Thu Nov 1 21:06:41 2018 +0100

    OPENJPA-2755 OPENJPA-2555 support fractions of a second
   
    For now just in MySQL. Should also get added to PostgreSQL.
    Txs also to Ancoron Luciferis for a patch which also
    gave some important input!
---
 .../org/apache/openjpa/jdbc/sql/DBDictionary.java  |  2 +-
 .../persistence/kernel/TestDateQueries.java        | 82 +++++++++++++++++++---
 .../kernel/common/apps/AllFieldTypesTest.java      | 72 ++++++++++++++-----
 3 files changed, 127 insertions(+), 29 deletions(-)

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 233e184..888e35a 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
@@ -432,7 +432,7 @@ public class DBDictionary
     /**
      * set of types that only accept a single precision...
      */
-    protected final Set<String> fractionalTypeNameSet = new HashSet<>();
+    public final Set<String> fractionalTypeNameSet = new HashSet<>();
 
     /**
      * Default amount of digits for fractional Types.
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
index 7677340..dc01b06 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/TestDateQueries.java
@@ -35,6 +35,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.jdbc.sql.DBDictionary;
 import org.apache.openjpa.persistence.OpenJPAEntityManager;
 import org.apache.openjpa.persistence.OpenJPAQuery;
 import org.apache.openjpa.persistence.kernel.common.apps.AllFieldTypesTest;
@@ -45,6 +47,7 @@ public class TestDateQueries extends BaseKernelTest {
     private Date _date = null;
     private Date _before = null;
     private Date _after = null;
+    private final Timestamp referenceTst = new Timestamp(10000000000L);
 
     /**
      * Creates a new instance of TestDateQueries
@@ -74,12 +77,18 @@ public class TestDateQueries extends BaseKernelTest {
         test.setTestDate(_date);
 
         // prepare scale test fields
-        Timestamp tst = new Timestamp(1000000000L);
-        tst.setNanos(123456789);
-        test.setTestDateMaxScale(tst);
-        test.setTestDateScale0(tst);
-        test.setTestDateScale3(tst);
-        test.setTestDateScale6(tst);
+        Timestamp tst = new Timestamp(referenceTst.getTime());
+
+        // we stay under 5 to avoid rounding issues with some databases
+        tst.setNanos(123412341);
+
+        test.setTestTstMaxScale(tst);
+        test.setTestTstScale0(tst);
+        test.setTestTstScale3(tst);
+        test.setTestTstScale6(tst);
+        test.setTestDateMaxScale(new Date(tst.getTime()));
+        test.setTestDateScale0(new Date(tst.getTime()));
+        test.setTestDateScale3(new Date(tst.getTime()));
 
         _pm.persist(test);
 
@@ -108,18 +117,71 @@ public class TestDateQueries extends BaseKernelTest {
     }
 
     public void testDateScale() {
-        Timestamp referenceTst = new Timestamp(1000000000L);
+        DBDictionary dbDictionary = ((JDBCConfiguration) _pm.getConfiguration()).getDBDictionaryInstance();
+        if (!dbDictionary.fractionalTypeNameSet.contains(dbDictionary.timestampTypeName)) {
+            getLog().info("skipping testDateScale because DB doesn't support different fractions in timestamps");
+            return;
+        }
 
         Collection vals = executeQuery("testDate = :date");
         AllFieldTypesTest aft = (AllFieldTypesTest) vals.iterator().next();
         assertNotNull(aft);
 
-        long time = aft.getTestDateMaxScale().getTime();
-        long nanos = aft.getTestDateMaxScale().getNanos();
+        long time = aft.getTestTstMaxScale().getTime();
+        long nanos = aft.getTestTstMaxScale().getNanos();
 
         // cut of the ms
-        assertEquals(referenceTst, time - (time%1000));
+        assertEquals(referenceTst.getTime(), time - (time % 1000));
+
+        // we have to do some guessing as not every database
+        // is able to store fractions of a second.
+        int maxDigitsFromDb = getNonZeroDigits(nanos);
+        if (maxDigitsFromDb >= 3) {
+            {
+                time = aft.getTestTstScale0().getTime();
+                nanos = aft.getTestTstScale0().getNanos();
+                assertEquals(referenceTst.getTime(), time - (time % 1000));
+                assertEquals(0, getNonZeroDigits(nanos));
+            }
+
+            {
+                time = aft.getTestDateScale0().getTime();
+                assertEquals(referenceTst.getTime(), time - (time % 1000));
+            }
+
+            {
+                time = aft.getTestTstScale3().getTime();
+                nanos = aft.getTestTstScale3().getNanos();
+                assertEquals(referenceTst.getTime(), time - (time % 1000));
+                assertEquals(3, getNonZeroDigits(nanos));
+            }
+
+            {
+                time = aft.getTestDateMaxScale().getTime();
+                assertEquals(referenceTst.getTime() + 123, time);
+            }
+
+            {
+                time = aft.getTestDateScale3().getTime();
+                assertEquals(referenceTst.getTime() + 123, time);
+            }
+
+        }
+
+        if (maxDigitsFromDb >= 6) {
+            time = aft.getTestTstScale6().getTime();
+            nanos = aft.getTestTstScale6().getNanos();
+            assertEquals(referenceTst.getTime(), time - (time % 1000));
+            assertEquals(6, getNonZeroDigits(nanos));
+        }
+    }
+
+    private int getNonZeroDigits(long val) {
+        String sval = Long.toString(val);
+        int digits = 0;
+        for (; digits < sval.length() && sval.charAt(digits) != '0'; digits++);
 
+        return digits;
     }
 
     public void testBefore() {
diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
index eb99c3c..22d09b5 100644
--- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
+++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/kernel/common/apps/AllFieldTypesTest.java
@@ -66,18 +66,31 @@ public class AllFieldTypesTest {
 
     @Temporal(TemporalType.TIMESTAMP)
     @Column(scale=-1)
-    private Timestamp testDateScale0;
+    private Timestamp testTstScale0;
 
     @Temporal(TemporalType.TIMESTAMP)
     @Column(scale=3)
-    private Timestamp testDateScale3;
+    private Timestamp testTstScale3;
 
     @Temporal(TemporalType.TIMESTAMP)
     @Column(scale=6)
-    private Timestamp testDateScale6;
+    private Timestamp testTstScale6;
 
     @Temporal(TemporalType.TIMESTAMP)
-    private Timestamp testDateMaxScale;
+    private Timestamp testTstMaxScale;
+
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(scale=-1)
+    private Date testDateScale0;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    @Column(scale=3)
+    private Date testDateScale3;
+
+
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date testDateMaxScale;
 
     private Object testObject;
     private BigInteger testBigInteger;
@@ -208,38 +221,61 @@ public class AllFieldTypesTest {
         this.testBigDecimal = testBigDecimal;
     }
 
-    public Timestamp getTestDateScale0() {
-        return testDateScale0;
+    public Timestamp getTestTstScale0() {
+        return testTstScale0;
     }
 
-    public void setTestDateScale0(Timestamp testDateScale0) {
-        this.testDateScale0 = testDateScale0;
+    public void setTestTstScale0(Timestamp testTstScale0) {
+        this.testTstScale0 = testTstScale0;
     }
 
-    public Timestamp getTestDateScale3() {
-        return testDateScale3;
+    public Timestamp getTestTstScale3() {
+        return testTstScale3;
     }
 
-    public void setTestDateScale3(Timestamp testDateScale3) {
-        this.testDateScale3 = testDateScale3;
+    public void setTestTstScale3(Timestamp testTstScale3) {
+        this.testTstScale3 = testTstScale3;
     }
 
-    public Timestamp getTestDateScale6() {
-        return testDateScale6;
+    public Timestamp getTestTstScale6() {
+        return testTstScale6;
     }
 
-    public void setTestDateScale6(Timestamp testDateScale6) {
-        this.testDateScale6 = testDateScale6;
+    public void setTestTstScale6(Timestamp testTstScale6) {
+        this.testTstScale6 = testTstScale6;
     }
 
-    public Timestamp getTestDateMaxScale() {
+    public Timestamp getTestTstMaxScale() {
+        return testTstMaxScale;
+    }
+
+    public void setTestTstMaxScale(Timestamp testTstMaxScale) {
+        this.testTstMaxScale = testTstMaxScale;
+    }
+
+    public Date getTestDateMaxScale() {
         return testDateMaxScale;
     }
 
-    public void setTestDateMaxScale(Timestamp testDateMaxScale) {
+    public void setTestDateMaxScale(Date testDateMaxScale) {
         this.testDateMaxScale = testDateMaxScale;
     }
 
+    public Date getTestDateScale0() {
+        return testDateScale0;
+    }
+
+    public void setTestDateScale0(Date testDateScale0) {
+        this.testDateScale0 = testDateScale0;
+    }
+
+    public Date getTestDateScale3() {
+        return testDateScale3;
+    }
+
+    public void setTestDateScale3(Date testDateScale3) {
+        this.testDateScale3 = testDateScale3;
+    }
 
     public void randomize(boolean objects, boolean blobs) {
         testint = AbstractTestCase.randomInt().intValue();