2

I have made a converter such that when I read DATE fields out of the database, it should be able to coerce them to java.time.LocalDate objects. However, when I try to do so, it gives me this error:

 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 is my table, which has a column START_DATE which is of type DATE. Here is the converter:

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);
    }
}

Why does it think that my column is a timestamp? Do all dates in oracle get coerced to java.sql.Timestamp?

dic19
  • 17,821
  • 6
  • 40
  • 69
FatalCatharsis
  • 3,407
  • 5
  • 44
  • 74

1 Answers1

2

The 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.

So, updating your converter to something like this should do the trick:

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();
    }
}
dic19
  • 17,821
  • 6
  • 40
  • 69