You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2020/11/18 09:14:48 UTC

[cayenne] branch master updated (3f614bc -> 9b465cc)

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

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


    from 3f614bc  Add toString() method to new value types
     new 3b64f0c  CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x
     new 9b465cc  CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x

The 2 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:
 RELEASE-NOTES.txt                                  |  1 +
 .../org/apache/cayenne/access/types/DateType.java  | 29 ++++++-
 .../org/apache/cayenne/access/types/TimeType.java  | 29 ++++++-
 .../apache/cayenne/access/types/TimestampType.java | 29 ++++++-
 .../apache/cayenne/access/types/UtilDateType.java  | 97 ++++++++++++++++------
 .../org/apache/cayenne/dba/mysql/MySQLAdapter.java | 10 +++
 .../org/apache/cayenne/access/DateTimeTypesIT.java | 28 +++----
 7 files changed, 179 insertions(+), 44 deletions(-)


[cayenne] 01/02: CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x

Posted by nt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3b64f0c1b2583ab505f32e1a14569a199e00b566
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Wed Nov 18 12:14:16 2020 +0300

    CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x
---
 .../org/apache/cayenne/access/types/DateType.java  | 29 ++++++-
 .../org/apache/cayenne/access/types/TimeType.java  | 29 ++++++-
 .../apache/cayenne/access/types/TimestampType.java | 29 ++++++-
 .../apache/cayenne/access/types/UtilDateType.java  | 97 ++++++++++++++++------
 .../org/apache/cayenne/dba/mysql/MySQLAdapter.java | 10 +++
 .../org/apache/cayenne/access/DateTimeTypesIT.java | 28 +++----
 6 files changed, 178 insertions(+), 44 deletions(-)

diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java
index 5521ada..0c5ba3d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DateType.java
@@ -22,12 +22,35 @@ import java.sql.CallableStatement;
 import java.sql.Date;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
+import java.util.Calendar;
 
 /**
  * @since 3.0
  */
 public class DateType implements ExtendedType<Date> {
 
+    private final Calendar calendar;
+    private final boolean useCalendar;
+
+    /**
+     * @since 4.2
+     */
+    public DateType() {
+        this(false);
+    }
+
+    /**
+     * @since 4.2
+     */
+    public DateType(boolean useCalendar) {
+        this.useCalendar = useCalendar;
+        if(this.useCalendar) {
+            this.calendar = Calendar.getInstance();
+        } else {
+            this.calendar = null;
+        }
+    }
+
     @Override
     public String getClassName() {
         return Date.class.getName();
@@ -35,12 +58,12 @@ public class DateType implements ExtendedType<Date> {
 
     @Override
     public Date materializeObject(ResultSet rs, int index, int type) throws Exception {
-        return rs.getDate(index);
+        return useCalendar ? rs.getDate(index, calendar) : rs.getDate(index);
     }
 
     @Override
     public Date materializeObject(CallableStatement rs, int index, int type) throws Exception {
-        return rs.getDate(index);
+        return useCalendar ? rs.getDate(index, calendar) : rs.getDate(index);
     }
 
     @Override
@@ -53,6 +76,8 @@ public class DateType implements ExtendedType<Date> {
 
         if (value == null) {
             statement.setNull(pos, type);
+        } else if(useCalendar) {
+            statement.setDate(pos, value, calendar);
         } else {
             statement.setDate(pos, value);
         }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java
index 46821bd..d0db8c8 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimeType.java
@@ -22,12 +22,35 @@ import java.sql.CallableStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.Time;
+import java.util.Calendar;
 
 /**
  * @since 3.0
  */
 public class TimeType implements ExtendedType<Time> {
 
+    private final Calendar calendar;
+    private final boolean useCalendar;
+
+    /**
+     * @since 4.2
+     */
+    public TimeType() {
+        this(false);
+    }
+
+    /**
+     * @since 4.2
+     */
+    public TimeType(boolean useCalendar) {
+        this.useCalendar = useCalendar;
+        if(this.useCalendar) {
+            this.calendar = Calendar.getInstance();
+        } else {
+            this.calendar = null;
+        }
+    }
+
     @Override
     public String getClassName() {
         return Time.class.getName();
@@ -35,12 +58,12 @@ public class TimeType implements ExtendedType<Time> {
 
     @Override
     public Time materializeObject(ResultSet rs, int index, int type) throws Exception {
-        return rs.getTime(index);
+        return useCalendar ? rs.getTime(index, calendar) : rs.getTime(index);
     }
 
     @Override
     public Time materializeObject(CallableStatement rs, int index, int type) throws Exception {
-        return rs.getTime(index);
+        return useCalendar ? rs.getTime(index, calendar) : rs.getTime(index);
     }
 
     @Override
@@ -53,6 +76,8 @@ public class TimeType implements ExtendedType<Time> {
 
         if (value == null) {
             statement.setNull(pos, type);
+        } else if(useCalendar) {
+            statement.setTime(pos, value, calendar);
         } else {
             statement.setTime(pos, value);
         }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java
index cecf325..a89772d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/TimestampType.java
@@ -22,12 +22,35 @@ import java.sql.CallableStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.Timestamp;
+import java.util.Calendar;
 
 /**
  * @since 3.0
  */
 public class TimestampType implements ExtendedType<Timestamp> {
 
+    private final Calendar calendar;
+    private final boolean useCalendar;
+
+    /**
+     * @since 4.2
+     */
+    public TimestampType() {
+        this(false);
+    }
+
+    /**
+     * @since 4.2
+     */
+    public TimestampType(boolean useCalendar) {
+        this.useCalendar = useCalendar;
+        if(this.useCalendar) {
+            this.calendar = Calendar.getInstance();
+        } else {
+            this.calendar = null;
+        }
+    }
+
     @Override
     public String getClassName() {
         return Timestamp.class.getName();
@@ -35,12 +58,12 @@ public class TimestampType implements ExtendedType<Timestamp> {
 
     @Override
     public Timestamp materializeObject(ResultSet rs, int index, int type) throws Exception {
-        return rs.getTimestamp(index);
+        return useCalendar ? rs.getTimestamp(index, calendar) : rs.getTimestamp(index);
     }
 
     @Override
     public Timestamp materializeObject(CallableStatement cs, int index, int type) throws Exception {
-        return cs.getTimestamp(index);
+        return useCalendar ? cs.getTimestamp(index, calendar) : cs.getTimestamp(index);
     }
 
     @Override
@@ -53,6 +76,8 @@ public class TimestampType implements ExtendedType<Timestamp> {
 
         if (value == null) {
             statement.setNull(pos, type);
+        } else if(useCalendar) {
+            statement.setTimestamp(pos, value, calendar);
         } else {
             statement.setTimestamp(pos, value);
         }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java b/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
index b87a72e..2e9d7b0 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
@@ -24,7 +24,9 @@ import org.apache.cayenne.dba.TypesMapping;
 import java.sql.CallableStatement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
+import java.sql.Time;
 import java.sql.Types;
+import java.util.Calendar;
 import java.util.Date;
 
 /**
@@ -33,43 +35,59 @@ import java.util.Date;
  */
 public class UtilDateType implements ExtendedType<Date> {
 
+    private final Calendar calendar;
+    private final boolean useCalendar;
+
     /**
-     * Returns "java.util.Date".
+     * @since 4.2
      */
-    @Override
-    public String getClassName() {
-        return Date.class.getName();
+    public UtilDateType() {
+        this(false);
     }
 
-    protected Object convertToJdbcObject(Date val, int type) throws Exception {
-        if (type == Types.DATE) {
-            return new java.sql.Date(val.getTime());
-        } else if (type == Types.TIME) {
-            return new java.sql.Time(val.getTime());
-        } else if (type == Types.TIMESTAMP) {
-            return new java.sql.Timestamp(val.getTime());
+    /**
+     * @since 4.2
+     */
+    public UtilDateType(boolean useCalendar) {
+        this.useCalendar = useCalendar;
+        if(this.useCalendar) {
+            this.calendar = Calendar.getInstance();
         } else {
-            throw new IllegalArgumentException(
-                    "Only DATE, TIME or TIMESTAMP can be mapped as '" + getClassName()
-                            + "', got " + TypesMapping.getSqlNameByType(type));
+            this.calendar = null;
         }
     }
 
+    /**
+     * Returns "java.util.Date".
+     */
+    @Override
+    public String getClassName() {
+        return Date.class.getName();
+    }
+
     @Override
     public Date materializeObject(ResultSet rs, int index, int type) throws Exception {
         Date val;
         switch (type) {
             case Types.TIMESTAMP:
-                val = rs.getTimestamp(index);
+                val = useCalendar
+                        ? rs.getTimestamp(index, calendar)
+                        : rs.getTimestamp(index);
                 break;
             case Types.DATE:
-                val = rs.getDate(index);
+                val = useCalendar
+                        ? rs.getDate(index, calendar)
+                        : rs.getDate(index);
                 break;
             case Types.TIME:
-                val = rs.getTime(index);
+                val = useCalendar
+                        ? rs.getTime(index, calendar)
+                        : rs.getTime(index);
                 break;
             default:
-                val = rs.getTimestamp(index);
+                val = useCalendar
+                        ? rs.getTimestamp(index, calendar)
+                        : rs.getTimestamp(index);
                 break;
         }
 
@@ -82,16 +100,24 @@ public class UtilDateType implements ExtendedType<Date> {
         Date val;
         switch (type) {
             case Types.TIMESTAMP:
-                val = cs.getTimestamp(index);
+                val = useCalendar
+                        ? cs.getTimestamp(index, calendar)
+                        : cs.getTimestamp(index);
                 break;
             case Types.DATE:
-                val = cs.getDate(index);
+                val = useCalendar
+                        ? cs.getDate(index, calendar)
+                        : cs.getDate(index);
                 break;
             case Types.TIME:
-                val = cs.getTime(index);
+                val = useCalendar
+                        ? cs.getTime(index, calendar)
+                        : cs.getTime(index);
                 break;
             default:
-                val = cs.getTimestamp(index);
+                val = useCalendar
+                        ? cs.getTimestamp(index, calendar)
+                        : cs.getTimestamp(index);
                 break;
         }
 
@@ -110,7 +136,30 @@ public class UtilDateType implements ExtendedType<Date> {
         if (value == null) {
             statement.setNull(pos, type);
         } else {
-            statement.setObject(pos, convertToJdbcObject(value, type), type);
+            if (type == Types.DATE) {
+                if(useCalendar) {
+                    statement.setDate(pos, new java.sql.Date(value.getTime()), calendar);
+                } else {
+                    statement.setDate(pos, new java.sql.Date(value.getTime()));
+                }
+            } else if (type == Types.TIME) {
+                Time time = new Time(value.getTime());
+                if(useCalendar) {
+                    statement.setTime(pos, time, calendar);
+                } else {
+                    statement.setTime(pos, time);
+                }
+            } else if (type == Types.TIMESTAMP) {
+                if(useCalendar) {
+                    statement.setTimestamp(pos, new java.sql.Timestamp(value.getTime()), calendar);
+                } else {
+                    statement.setTimestamp(pos, new java.sql.Timestamp(value.getTime()));
+                }
+            } else {
+                throw new IllegalArgumentException(
+                        "Only DATE, TIME or TIMESTAMP can be mapped as '" + getClassName()
+                                + "', got " + TypesMapping.getSqlNameByType(type));
+            }
         }
     }
 
@@ -121,6 +170,6 @@ public class UtilDateType implements ExtendedType<Date> {
         }
 
         long time = value.getTime();
-        return "\'" + new java.sql.Timestamp(time) + "\'";
+        return '\'' + new java.sql.Timestamp(time).toString() + '\'';
     }
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
index 1c28171..32044e0 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
@@ -36,10 +36,14 @@ import org.apache.cayenne.access.translator.ejbql.EJBQLTranslatorFactory;
 import org.apache.cayenne.access.translator.ejbql.JdbcEJBQLTranslatorFactory;
 import org.apache.cayenne.access.types.ByteArrayType;
 import org.apache.cayenne.access.types.CharType;
+import org.apache.cayenne.access.types.DateType;
 import org.apache.cayenne.access.types.ExtendedType;
 import org.apache.cayenne.access.types.ExtendedTypeFactory;
 import org.apache.cayenne.access.types.ExtendedTypeMap;
 import org.apache.cayenne.access.types.JsonType;
+import org.apache.cayenne.access.types.TimeType;
+import org.apache.cayenne.access.types.TimestampType;
+import org.apache.cayenne.access.types.UtilDateType;
 import org.apache.cayenne.access.types.ValueObjectTypeRegistry;
 import org.apache.cayenne.configuration.Constants;
 import org.apache.cayenne.configuration.RuntimeProperties;
@@ -153,6 +157,12 @@ public class MySQLAdapter extends JdbcAdapter {
 		map.registerType(charType);
 		map.registerType(new ByteArrayType(false, false));
 		map.registerType(new JsonType(charType, true));
+
+		// register non-default types for the dates, see CAY-2691
+		map.registerType(new DateType(true));
+		map.registerType(new TimeType(true));
+		map.registerType(new TimestampType(true));
+		map.registerType(new UtilDateType(true));
 	}
 
 	@Override
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DateTimeTypesIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DateTimeTypesIT.java
index 2031afa..94b2312 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DateTimeTypesIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DateTimeTypesIT.java
@@ -48,13 +48,13 @@ public class DateTimeTypesIT extends ServerCase {
     private DataContext context;
 
     @Test
-    public void testCalendar() throws Exception {
+    public void testCalendar() {
 
         CalendarEntity test = context.newObject(CalendarEntity.class);
 
         Calendar cal = Calendar.getInstance();
         cal.clear();
-        cal.set(2002, 1, 1);
+        cal.set(2002, Calendar.FEBRUARY, 1);
 
         test.setCalendarField(cal);
         context.commitChanges();
@@ -69,12 +69,12 @@ public class DateTimeTypesIT extends ServerCase {
     }
 
     @Test
-    public void testDate() throws Exception {
+    public void testDate() {
         DateTestEntity test = context.newObject(DateTestEntity.class);
 
         Calendar cal = Calendar.getInstance();
         cal.clear();
-        cal.set(2002, 1, 1);
+        cal.set(2002, Calendar.FEBRUARY, 1);
         Date nowDate = cal.getTime();
         test.setDateColumn(nowDate);
         context.commitChanges();
@@ -87,12 +87,12 @@ public class DateTimeTypesIT extends ServerCase {
     }
 
     @Test
-    public void testTime() throws Exception {
+    public void testTime() {
         DateTestEntity test = context.newObject(DateTestEntity.class);
 
         Calendar cal = Calendar.getInstance();
         cal.clear();
-        cal.set(1970, 0, 1, 1, 20, 30);
+        cal.set(1970, Calendar.JANUARY, 1, 1, 20, 30);
         Date nowTime = cal.getTime();
         test.setTimeColumn(nowTime);
         context.commitChanges();
@@ -112,12 +112,12 @@ public class DateTimeTypesIT extends ServerCase {
     }
 
     @Test
-    public void testTimestamp() throws Exception {
+    public void testTimestamp() {
         DateTestEntity test = context.newObject(DateTestEntity.class);
 
         Calendar cal = Calendar.getInstance();
         cal.clear();
-        cal.set(2003, 1, 1, 1, 20, 30);
+        cal.set(2003, Calendar.FEBRUARY, 1, 1, 20, 30);
 
         // most databases fail millisecond accuracy
         // cal.set(Calendar.MILLISECOND, 55);
@@ -133,12 +133,12 @@ public class DateTimeTypesIT extends ServerCase {
     }
 
     @Test
-    public void testSQLTemplateTimestamp() throws Exception {
+    public void testSQLTemplateTimestamp() {
         DateTestEntity test = context.newObject(DateTestEntity.class);
 
         Calendar cal = Calendar.getInstance();
         cal.clear();
-        cal.set(2003, 1, 1, 1, 20, 30);
+        cal.set(2003, Calendar.FEBRUARY, 1, 1, 20, 30);
 
         // most databases fail millisecond accuracy
         // cal.set(Calendar.MILLISECOND, 55);
@@ -154,12 +154,12 @@ public class DateTimeTypesIT extends ServerCase {
     }
 
     @Test
-    public void testSQLTemplateDate() throws Exception {
+    public void testSQLTemplateDate() {
         DateTestEntity test = (DateTestEntity) context.newObject("DateTestEntity");
 
         Calendar cal = Calendar.getInstance();
         cal.clear();
-        cal.set(2003, 1, 1, 1, 20, 30);
+        cal.set(2003, Calendar.FEBRUARY, 1, 1, 20, 30);
 
         // most databases fail millisecond accuracy
         // cal.set(Calendar.MILLISECOND, 55);
@@ -175,12 +175,12 @@ public class DateTimeTypesIT extends ServerCase {
     }
 
     @Test
-    public void testSQLTemplateTime() throws Exception {
+    public void testSQLTemplateTime() {
         DateTestEntity test = (DateTestEntity) context.newObject("DateTestEntity");
 
         Calendar cal = Calendar.getInstance();
         cal.clear();
-        cal.set(2003, 1, 1, 1, 20, 30);
+        cal.set(2003, Calendar.FEBRUARY, 1, 1, 20, 30);
 
         // most databases fail millisecond accuracy
         // cal.set(Calendar.MILLISECOND, 55);


[cayenne] 02/02: CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x

Posted by nt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9b465cc034734a4816d873e9531349553c93dd84
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Wed Nov 18 12:14:37 2020 +0300

    CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x
---
 RELEASE-NOTES.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index abaf4de..50e0896 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -21,6 +21,7 @@ CAY-2683 Don't use DISTINCT for joins on to-one related tables
 CAY-2685 JsonType should use the actual JDBC type, not OTHER
 CAY-2686 SQL translator incorrectly quotes fully qualified tables' names
 CAY-2690 dbimport skips length changes for BINARY and VARBINARY columns
+CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x
 
 ----------------------------------
 Release: 4.2.M2