Skip to content

Commit 6776798

Browse files
authored
fix bug for TypeUtils.castToTimestamp, for issue #3906 and #3907 (#3908)
* fix bug for TypeUtils.castToTimestamp, for issue #3906 and #3907 * update * optimize * lazy load
1 parent d86f135 commit 6776798

File tree

4 files changed

+95
-5
lines changed

4 files changed

+95
-5
lines changed

core/src/main/java/com/alibaba/fastjson2/util/JdbcSupport.java

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.alibaba.fastjson2.writer.ObjectWriter;
1111

1212
import java.io.Reader;
13+
import java.lang.reflect.Constructor;
1314
import java.lang.reflect.Type;
1415
import java.sql.SQLException;
1516
import java.sql.Time;
@@ -26,6 +27,15 @@ public class JdbcSupport {
2627
static Class CLASS_CLOB;
2728
static volatile boolean CLASS_CLOB_ERROR;
2829

30+
static Constructor CONSTRUCTOR_TIMESTAMP;
31+
static volatile boolean CONSTRUCTOR_TIMESTAMP_ERROR;
32+
33+
static Constructor CONSTRUCTOR_DATE;
34+
static volatile boolean CONSTRUCTOR_DATE_ERROR;
35+
36+
static Constructor CONSTRUCTOR_TIME;
37+
static volatile boolean CONSTRUCTOR_TIME_ERROR;
38+
2939
public static ObjectReader createTimeReader(Class objectClass, String format, Locale locale) {
3040
return new TimeReader(format, locale);
3141
}
@@ -47,15 +57,66 @@ public static ObjectWriter createTimeWriter(String format) {
4757
}
4858

4959
public static Object createTimestamp(long millis) {
50-
return new Timestamp(millis);
60+
if (CONSTRUCTOR_TIMESTAMP == null && !CONSTRUCTOR_TIMESTAMP_ERROR) {
61+
try {
62+
Class<?> clazz = Class.forName("java.sql.Timestamp");
63+
CONSTRUCTOR_TIMESTAMP = clazz.getConstructor(long.class);
64+
} catch (Throwable e) {
65+
CONSTRUCTOR_TIMESTAMP_ERROR = true;
66+
}
67+
}
68+
69+
if (CONSTRUCTOR_TIMESTAMP == null) {
70+
throw new JSONException("class java.sql.Timestamp not found");
71+
}
72+
73+
try {
74+
return CONSTRUCTOR_TIMESTAMP.newInstance(millis);
75+
} catch (Exception e) {
76+
throw new JSONException("create java.sql.Timestamp error", e);
77+
}
5178
}
5279

5380
public static Object createDate(long millis) {
54-
return new java.sql.Date(millis);
81+
if (CONSTRUCTOR_DATE == null && !CONSTRUCTOR_DATE_ERROR) {
82+
try {
83+
Class<?> clazz = Class.forName("java.sql.Date");
84+
CONSTRUCTOR_DATE = clazz.getConstructor(long.class);
85+
} catch (Throwable e) {
86+
CONSTRUCTOR_DATE_ERROR = true;
87+
}
88+
}
89+
90+
if (CONSTRUCTOR_DATE == null) {
91+
throw new JSONException("class java.sql.Date not found");
92+
}
93+
94+
try {
95+
return CONSTRUCTOR_DATE.newInstance(millis);
96+
} catch (Exception e) {
97+
throw new JSONException("create java.sql.Date error", e);
98+
}
5599
}
56100

57101
public static Object createTime(long millis) {
58-
return new java.sql.Time(millis);
102+
if (CONSTRUCTOR_TIME == null && !CONSTRUCTOR_TIME_ERROR) {
103+
try {
104+
Class<?> clazz = Class.forName("java.sql.Time");
105+
CONSTRUCTOR_TIME = clazz.getConstructor(long.class);
106+
} catch (Throwable e) {
107+
CONSTRUCTOR_TIME_ERROR = true;
108+
}
109+
}
110+
111+
if (CONSTRUCTOR_TIME == null) {
112+
throw new JSONException("class java.sql.Time not found");
113+
}
114+
115+
try {
116+
return CONSTRUCTOR_TIME.newInstance(millis);
117+
} catch (Exception e) {
118+
throw new JSONException("create java.sql.Time error", e);
119+
}
59120
}
60121

61122
public static ObjectWriter createClobWriter(Class objectClass) {

core/src/main/java/com/alibaba/fastjson2/util/TypeUtils.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,22 @@ public static <T> T cast(Object obj, Class<T> targetClass, ObjectReaderProvider
14581458
}
14591459
}
14601460

1461+
if (obj instanceof Date) {
1462+
long time = ((Date) obj).getTime();
1463+
String className = targetClass.getName();
1464+
1465+
switch (className) {
1466+
case "java.sql.Timestamp":
1467+
return (T) JdbcSupport.createTimestamp(time);
1468+
case "java.sql.Date":
1469+
return (T) JdbcSupport.createDate(time);
1470+
case "java.sql.Time":
1471+
return (T) JdbcSupport.createTime(time);
1472+
default:
1473+
break;
1474+
}
1475+
}
1476+
14611477
if (targetClass == String.class) {
14621478
if (obj instanceof Character) {
14631479
return (T) obj.toString();

fastjson1-compatible/src/main/java/com/alibaba/fastjson/util/TypeUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,11 +546,11 @@ public static BigInteger castToBigInteger(Object value) {
546546
return com.alibaba.fastjson2.util.TypeUtils.toBigInteger(value);
547547
}
548548

549-
public static Timestamp castToTimestamp(final Object value) {
549+
public static Object castToTimestamp(final Object value) {
550550
return com.alibaba.fastjson2.util.TypeUtils.cast(value, Timestamp.class);
551551
}
552552

553-
public static java.sql.Date castToSqlDate(final Object value) {
553+
public static Object castToSqlDate(final Object value) {
554554
return com.alibaba.fastjson2.util.TypeUtils.cast(value, java.sql.Date.class);
555555
}
556556

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.alibaba.fastjson2;
2+
3+
import com.alibaba.fastjson.util.TypeUtils;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
7+
8+
public class Issue3906 {
9+
@Test
10+
public void test() throws NoSuchMethodException {
11+
assertDoesNotThrow(() -> TypeUtils.castToTimestamp(new java.util.Date()));
12+
}
13+
}

0 commit comments

Comments
 (0)