DB2: Fix: DataBind/Read of native LocalDates

This commit is contained in:
Roland Praml
2022-01-26 16:51:55 +01:00
committed by Roland Praml
parent 78a647a72e
commit 2e1a6eec04
7 changed files with 103 additions and 34 deletions
@@ -15,6 +15,7 @@ import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
@@ -54,6 +55,15 @@ public class DatabasePlatform {
protected boolean supportsSavepointId = true;
protected boolean useMigrationStoredProcedures = false;
/**
* Can we use native java time API objects in
* {@link ResultSet#getObject(int, Class)} and
* {@link PreparedStatement#setObject(int, Object)}.
*
* Not all drivers (DB2 e.g.) will support this.
*/
protected boolean supportsNativeJavaTime = true;
/**
* The behaviour used when ending a read only transaction at read committed isolation level.
@@ -827,4 +837,8 @@ public class DatabasePlatform {
protected void escapeLikeCharacter(char ch, StringBuilder sb) {
sb.append(likeEscapeChar).append(ch);
}
public boolean supportsNativeJavaTime() {
return supportsNativeJavaTime;
}
}
@@ -24,6 +24,7 @@ public class DB2Platform extends DatabasePlatform {
// TOOD: Check if we need to introduce a new platform (DB2_LUW_11 ?)
this.maxTableNameLength = 18;
this.maxConstraintNameLength = 18;
this.supportsNativeJavaTime = false;
this.truncateTable = "truncate table %s reuse storage ignore delete triggers immediate";
this.sqlLimiter = new Db2SqlLimiter();
@@ -755,7 +755,11 @@ public final class DefaultTypeManager implements TypeManager {
typeMap.put(java.nio.file.Path.class, new ScalarTypePath());
addType(java.time.Period.class, new ScalarTypePeriod());
addType(java.time.LocalDate.class, new ScalarTypeLocalDate(jsonDate));
if (config.getDatabasePlatform().supportsNativeJavaTime()) {
addType(java.time.LocalDate.class, new ScalarTypeLocalDateNative(jsonDate));
} else {
addType(java.time.LocalDate.class, new ScalarTypeLocalDate(jsonDate));
}
addType(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime(jsonDateTime));
addType(OffsetDateTime.class, new ScalarTypeOffsetDateTime(jsonDateTime, zoneId));
addType(ZonedDateTime.class, new ScalarTypeZonedDateTime(jsonDateTime, zoneId));
@@ -795,7 +799,11 @@ public final class DefaultTypeManager implements TypeManager {
log.debug("Registering Joda data types");
addType(LocalDateTime.class, new ScalarTypeJodaLocalDateTime(jsonDateTime));
addType(DateTime.class, new ScalarTypeJodaDateTime(jsonDateTime));
addType(LocalDate.class, new ScalarTypeJodaLocalDate(jsonDate));
if (config.getDatabasePlatform().supportsNativeJavaTime()) {
addType(LocalDate.class, new ScalarTypeJodaLocalDateNative(jsonDate));
} else {
addType(LocalDate.class, new ScalarTypeJodaLocalDate(jsonDate));
}
addType(org.joda.time.DateMidnight.class, new ScalarTypeJodaDateMidnight(jsonDate));
addType(org.joda.time.Period.class, new ScalarTypeJodaPeriod());
@@ -14,7 +14,7 @@ import java.sql.Types;
/**
* ScalarType for Joda LocalDate. This maps to a JDBC Date.
*/
final class ScalarTypeJodaLocalDate extends ScalarTypeBaseDate<LocalDate> {
class ScalarTypeJodaLocalDate extends ScalarTypeBaseDate<LocalDate> {
ScalarTypeJodaLocalDate(JsonConfig.Date mode) {
super(mode, LocalDate.class, false, Types.DATE);
@@ -61,19 +61,4 @@ final class ScalarTypeJodaLocalDate extends ScalarTypeBaseDate<LocalDate> {
}
return (LocalDate) value;
}
@Override
public void bind(DataBinder binder, LocalDate value) throws SQLException {
if (value == null) {
binder.setNull(Types.DATE);
} else {
binder.setObject(java.time.LocalDate.of(value.getYear(), value.getMonthOfYear(), value.getDayOfMonth()));
}
}
@Override
public LocalDate read(DataReader reader) throws SQLException {
java.time.LocalDate jtDate = reader.getObject(java.time.LocalDate.class);
return jtDate == null ? null : new org.joda.time.LocalDate(jtDate.getYear(), jtDate.getMonthValue(), jtDate.getDayOfMonth());
}
}
@@ -0,0 +1,37 @@
package io.ebeaninternal.server.type;
import io.ebean.config.JsonConfig;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.DataReader;
import io.ebeaninternal.server.core.BasicTypeConverter;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Types;
/**
* ScalarType for Joda LocalDate. This maps to a LocalDate. Not all drivers/platforms may support this.
*/
final class ScalarTypeJodaLocalDateNative extends ScalarTypeJodaLocalDate{
ScalarTypeJodaLocalDateNative(JsonConfig.Date mode) {
super(mode);
}
@Override
public void bind(DataBinder binder, LocalDate value) throws SQLException {
if (value == null) {
binder.setNull(Types.DATE);
} else {
binder.setObject(java.time.LocalDate.of(value.getYear(), value.getMonthOfYear(), value.getDayOfMonth()));
}
}
@Override
public LocalDate read(DataReader reader) throws SQLException {
java.time.LocalDate jtDate = reader.getObject(java.time.LocalDate.class);
return jtDate == null ? null : new org.joda.time.LocalDate(jtDate.getYear(), jtDate.getMonthValue(), jtDate.getDayOfMonth());
}
}
@@ -16,7 +16,7 @@ import java.time.ZonedDateTime;
/**
* ScalarType for java.time.LocalDate. This maps to a JDBC Date.
*/
final class ScalarTypeLocalDate extends ScalarTypeBaseDate<LocalDate> {
class ScalarTypeLocalDate extends ScalarTypeBaseDate<LocalDate> {
ScalarTypeLocalDate(JsonConfig.Date mode) {
super(mode, LocalDate.class, false, Types.DATE);
@@ -63,19 +63,4 @@ final class ScalarTypeLocalDate extends ScalarTypeBaseDate<LocalDate> {
}
return (LocalDate) value;
}
@Override
public void bind(DataBinder binder, LocalDate value) throws SQLException {
if (value == null) {
binder.setNull(Types.DATE);
} else {
binder.setObject(value);
}
}
@Override
public LocalDate read(DataReader reader) throws SQLException {
return reader.getObject(LocalDate.class);
}
}
@@ -0,0 +1,39 @@
package io.ebeaninternal.server.type;
import io.ebean.config.JsonConfig;
import io.ebean.core.type.DataBinder;
import io.ebean.core.type.DataReader;
import io.ebeaninternal.server.core.BasicTypeConverter;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
/**
* ScalarType for java.time.LocalDate. This maps to a LocalDate. Not all drivers/platforms may support this.
*/
final class ScalarTypeLocalDateNative extends ScalarTypeLocalDate {
ScalarTypeLocalDateNative(JsonConfig.Date mode) {
super(mode);
}
@Override
public void bind(DataBinder binder, LocalDate value) throws SQLException {
if (value == null) {
binder.setNull(Types.DATE);
} else {
binder.setObject(value);
}
}
@Override
public LocalDate read(DataReader reader) throws SQLException {
return reader.getObject(LocalDate.class);
}
}