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


The following commit(s) were added to refs/heads/master by this push:
     new e9f3f9c  OPENJPA-2883 fix handling of java.sql.Time on MSSQL
e9f3f9c is described below

commit e9f3f9cdfcbb6479e02a477730debb320e5e5dbe
Author: Mark Struberg <strub...@apache.org>
AuthorDate: Wed Mar 31 19:09:03 2021 +0200

    OPENJPA-2883 fix handling of java.sql.Time on MSSQL
---
 .../openjpa/jdbc/sql/SQLServerDictionary.java      | 27 +++++++++++++++-------
 .../TestTemporalTypeQueryParameterBinding.java     |  9 ++++++++
 openjpa-project/BUILDING.txt                       |  4 ++--
 pom.xml                                            |  6 ++++-
 4 files changed, 35 insertions(+), 11 deletions(-)

diff --git 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
index c50ccb1..a7061c4 100644
--- 
a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
+++ 
b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLServerDictionary.java
@@ -25,11 +25,13 @@ import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Time;
 import java.sql.Types;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.OffsetDateTime;
+import java.util.Calendar;
 import java.util.Locale;
 
 import org.apache.openjpa.jdbc.identifier.DBIdentifier;
@@ -61,13 +63,12 @@ public class SQLServerDictionary extends 
AbstractSQLServerDictionary {
     public boolean uniqueIdentifierAsVarbinary = true;
 
     /**
-     * Whether to send Time values as DateTime or as Time.
-     * This affects how the Database actually looks like.
-     * sendTimeAsDatetime is supported as of SQLServer2008 and
-     * is only to be used with TIME columns.
-     * Previous to that a DATETIME column had to be used with a fixed 
1970-01-01 date.
+     * SQLServer doesn't like a java.sql.Time as default.
+     * So either we send it as String or people configure 
sendTimeAsDatetime=false on the Connection.
+     * This is depending how the Database actually is setup.
+     * To mitigate misconfiguration we can work around by sending the time as 
String to the JDBC driver.
      */
-    public Boolean sendTimeAsDatetime = null;
+    public Boolean sendTimeAsString = null;
 
     public SQLServerDictionary() {
         platform = "Microsoft SQL Server";
@@ -95,8 +96,8 @@ public class SQLServerDictionary extends 
AbstractSQLServerDictionary {
             // serverMajorVersion of 8==2000, 9==2005, 10==2008,  11==2012
             if (meta.getDatabaseMajorVersion() >= 9) {
                 setSupportsXMLColumn(true);
-                if (sendTimeAsDatetime == null) {
-                    sendTimeAsDatetime = Boolean.TRUE;
+                if (sendTimeAsString == null) {
+                    sendTimeAsString = Boolean.FALSE;
                 }
             }
             if (meta.getDatabaseMajorVersion() >= 10) {
@@ -404,6 +405,16 @@ public class SQLServerDictionary extends 
AbstractSQLServerDictionary {
         return rs.getObject(column, OffsetDateTime.class);
     }
 
+    @Override
+    public void setTime(PreparedStatement stmnt, int idx, Time val, Calendar 
cal, Column col) throws SQLException {
+        if (sendTimeAsString) {
+            stmnt.setString(idx, val.toString());
+        }
+        else {
+            // use Time
+            super.setTime(stmnt, idx, val, cal, col);
+        }
+    }
 
     @Override
     public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find,
diff --git 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestTemporalTypeQueryParameterBinding.java
 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestTemporalTypeQueryParameterBinding.java
index 90c9cbd..923c19d 100644
--- 
a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestTemporalTypeQueryParameterBinding.java
+++ 
b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jdbc/query/TestTemporalTypeQueryParameterBinding.java
@@ -133,6 +133,15 @@ public class TestTemporalTypeQueryParameterBinding extends 
SingleEMFTestCase {
         assertEquals(1, q.getResultList().size());
     }
 
+    public void testNamedTimeParam() {
+        Date d2 = new Date(T2);
+
+        Query q = em.createQuery("SELECT p FROM TimeKeeper p WHERE p.time=:t");
+        q.setParameter("t",  d2, TemporalType.TIME);
+
+        assertEquals(1, q.getResultList().size());
+    }
+
     public void testPositionalParameterConvertedFromDateValue() {
         Date d1 = new Date(T1);
         Date d2 = new Date(T2);
diff --git a/openjpa-project/BUILDING.txt b/openjpa-project/BUILDING.txt
index 07358e2..e75d6cf 100644
--- a/openjpa-project/BUILDING.txt
+++ b/openjpa-project/BUILDING.txt
@@ -212,8 +212,8 @@ For running against a h2 based installation:
 For running against a hsqldb based installation:
  -ea -Dopenjpa.ConnectionDriverName=org.hsqldb.Driver 
-Dopenjpa.ConnectionURL=jdbc:hsqldb:mem:openjpa20-hsqldb-database 
-Dopenjpa.ConnectionUserName=sa -Dopenjpa.ConnectionPassword=
 
-For running tests against a SQLServer Docker based installation:
- -ea 
-Dopenjpa.ConnectionDriverName=com.microsoft.sqlserver.jdbc.SQLServerDriver 
-Dopenjpa.ConnectionURL=jdbc:sqlserver://localhost:1433 
-Dopenjpa.ConnectionUserName=SA -Dopenjpa.ConnectionPassword=OpenJP8tst
+For running tests against a Microsoft SQLServer Docker based installation:
+ -ea 
-Dopenjpa.ConnectionDriverName=com.microsoft.sqlserver.jdbc.SQLServerDriver 
-Dopenjpa.ConnectionURL=jdbc:sqlserver://localhost:1433;sendTimeAsDatetime=false
 -Dopenjpa.ConnectionUserName=SA -Dopenjpa.ConnectionPassword=OpenJP8tst
 
 TODO: finish!
 
diff --git a/pom.xml b/pom.xml
index 0de9a01..583d793 100644
--- a/pom.xml
+++ b/pom.xml
@@ -947,7 +947,11 @@
                 <openjpa.mssql.dbname>openjpatst</openjpa.mssql.dbname>
                 <openjpa.mssql.username>SA</openjpa.mssql.username>
                 <openjpa.mssql.password>OpenJP8tst</openjpa.mssql.password>
-                
<openjpa.mssql.url>jdbc:sqlserver://localhost:${docker.external.mssql.port}</openjpa.mssql.url>
+                <!--
+                  * sendTimeAsDatetime=false is important to make SQLServer 
understand java.sql.Time parameters.
+                  * Alternatively you can set the SQLServerDictionary 
parameter sendTimeAsString=true
+                 -->
+                
<openjpa.mssql.url>jdbc:sqlserver://localhost:${docker.external.mssql.port};sendTimeAsDatetime=false</openjpa.mssql.url>
 
                 
<!--<connection.url>jdbc:postgresql://localhost/openjpa</connection.url>-->
                 <connection.url>${openjpa.mssql.url}</connection.url>

Reply via email to