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 <[email protected]>
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>