Way to use @Convert to convert key of a Map (JPA)?

冷暖自知 提交于 2020-01-24 20:25:11

问题


I am using java.time.LocalDate of Java 8, and want to convert that to sql date so that it can be persisted. Here is my converter:

@Converter(autoApply = true)
public class LocalDatePersistenceConverter implements
    AttributeConverter<LocalDate, Date> {

        @Override
        public Date convertToDatabaseColumn(LocalDate attribute) {
        return java.sql.Date.valueOf(attribute);
        }

        @Override
        public LocalDate convertToEntityAttribute(Date dbData) {
        return dbData.toLocalDate();
        }

}

Here is how it is getting used:

@Entity
@Access(AccessType.FIELD)
public class MutualFund implements Serializable {

    @Id
    private final String schemeName;

    @Convert(attributeName="key",converter=LocalDatePersistenceConverter.class)
    @ElementCollection
    private Map<LocalDate, Price> nav;

    //Other fields and methods
}

When I try to persist a MutualFund object, I get following exception:

java.lang.IllegalStateException: @Convert placed on Map attribute [mypackage.MutualFund.nav] must define attributeName of 'key' or 'value'

What is wrong in this code? Please help. Thanks.


回答1:


Your mapping of the Map is not completed so you are getting the exception.

There are two options for Map mapping, not sure which one you were trying to achieve.

A) The LocalDate key of the nav map is a field of the Price object:

@Embeddable
public class Price implements Serializable {
    @Convert(converter=LocalDatePersistenceConverter.class) 
    //you don't need @convert if it is annotated with @Converter(autoApply = true)
    public LocalDate mark;
    public double price;
}

Then in your collection mapping you need to specify the key field used:

@ElementCollection
@MapKey(name="mark")
public Map<LocalDate, Price> nav;

B) The key element of nav is not part of the Price object, then you need to explicity map it to a column:

@Embeddable
public class Price implements Serializable {
    public double price;
}

and the map annotation:

@Convert(converter=LocalDatePersistenceConverter.class)
@ElementCollection
@MapKeyColumn(name="mark")
public Map<LocalDate, Price> nav;

EDIT It turned out that Hibernate is most demanding than EclipseLink

With @Converter(autoApply = true) it works without pointing to the converter with both explicit and implicit key column.

@ElementCollection
@MapKeyColumn(name="mark") //this annotation can be omitted then the key column is called nav_KEY
public Map<LocalDate, Price> nav;

I could not make it work without autoApply. Persistence context could be build only if converter was declared with attributeName="key.":

@Convert(attributeName="key.", converter=LocalDatePersistenceConverter.class)
@ElementCollection
public Map<LocalDate, Price> nav = new HashMap<>();

but the converter was not correctly apllied. During schema generation the key column was tried to be generated as BLOB (and failed as no length was given) and serializaton instead of conversion was triggered during insert/fetching. I could not find a way to fix it.



来源:https://stackoverflow.com/questions/29861951/way-to-use-convert-to-convert-key-of-a-map-jpa

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!