从 DATE 到 java.time.LocalDate 的 JPA 转换器不适用于 Glassfish 4.1
JPA converter from DATE to java.time.LocalDate not applying in Glassfish 4.1
我做了一个转换器,这样当我从数据库中读取 DATE 字段时,它应该能够将它们强制转换为 java.time.LocalDate
对象。但是,当我尝试这样做时,它给了我这个错误:
The object [3/16/17 12:00 AM], of class [class java.sql.Timestamp], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[startDate-->TEST_TABLE.START_DATE]] with descriptor [RelationalDescriptor(com.test.TestEntity --> [DatabaseTable(TEST_TABLE)])], could not be converted to [class [B].
TEST_TABLE
是我的 table,它有一个类型为 DATE
的列 START_DATE
。这是转换器:
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.sql.Date;
import java.time.LocalDate;
@Converter(autoApply = true)
public class OracleLocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate attribute) {
return (attribute != null ? Date.valueOf(attribute) : null);
}
@Override
public LocalDate convertToEntityAttribute(Date dbData) {
return (dbData != null ? dbData.toLocalDate() : null);
}
}
为什么它认为我的专栏是时间戳? oracle 中的所有日期都被强制为 java.sql.Timestamp
吗?
class java.sql.Timestamp is the one the persistence provider uses to parse a date from the DB regardless the value is just a date. It makes sense because it allows the persistence provider to get the time part of a DATETIME or a TIMESTAMP. Note that this class extends from java.util.Date not java.sql.Date.
因此,将您的转换器更新为这样的东西应该可以解决问题:
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter(autoApply = true)
public class OracleLocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate attribute) {
return attribute == null ? null : Date.from(attribute.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
@Override
public LocalDate convertToEntityAttribute(Date dbData) {
return dbData == null ? null : dbData.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
}
我做了一个转换器,这样当我从数据库中读取 DATE 字段时,它应该能够将它们强制转换为 java.time.LocalDate
对象。但是,当我尝试这样做时,它给了我这个错误:
The object [3/16/17 12:00 AM], of class [class java.sql.Timestamp], from mapping [org.eclipse.persistence.mappings.DirectToFieldMapping[startDate-->TEST_TABLE.START_DATE]] with descriptor [RelationalDescriptor(com.test.TestEntity --> [DatabaseTable(TEST_TABLE)])], could not be converted to [class [B].
TEST_TABLE
是我的 table,它有一个类型为 DATE
的列 START_DATE
。这是转换器:
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.sql.Date;
import java.time.LocalDate;
@Converter(autoApply = true)
public class OracleLocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate attribute) {
return (attribute != null ? Date.valueOf(attribute) : null);
}
@Override
public LocalDate convertToEntityAttribute(Date dbData) {
return (dbData != null ? dbData.toLocalDate() : null);
}
}
为什么它认为我的专栏是时间戳? oracle 中的所有日期都被强制为 java.sql.Timestamp
吗?
class java.sql.Timestamp is the one the persistence provider uses to parse a date from the DB regardless the value is just a date. It makes sense because it allows the persistence provider to get the time part of a DATETIME or a TIMESTAMP. Note that this class extends from java.util.Date not java.sql.Date.
因此,将您的转换器更新为这样的东西应该可以解决问题:
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter(autoApply = true)
public class OracleLocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate attribute) {
return attribute == null ? null : Date.from(attribute.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
@Override
public LocalDate convertToEntityAttribute(Date dbData) {
return dbData == null ? null : dbData.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
}