使用@Convert转换地图(JPA)密钥的方法? [英] Way to use @Convert to convert key of a Map (JPA)?

查看:160
本文介绍了使用@Convert转换地图(JPA)密钥的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java 8的java.time.LocalDate,并希望将其转换为sql date,以便可以将其持久化.这是我的转换器:

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

}

这里是如何使用它:

@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
}

当我尝试保存MutualFund对象时,出现以下异常:

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.

推荐答案

您的Map映射尚未完成,因此您遇到了异常.

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)导航地图的LocalDate键是Price对象的字段:

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)nav的关键元素不是Price对象的一部分,那么您需要将其显式映射到列:

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

和地图注释:

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

编辑 事实证明,Hibernate比EclipseLink要求最高

EDIT It turned out that Hibernate is most demanding than EclipseLink

使用@Converter(autoApply = true)时,它无需指向具有显式和隐式键列的转换器.

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;

没有autoApply我无法使其工作.仅当使用attributeName ="key."声明转换器时,才能构建持久性上下文.

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

,但未正确使用转换器.在模式生成期间,尝试将键列生成为BLOB(并且由于未给出长度而失败),并且在插入/获取期间触发了序列化而不是转换.我找不到解决方法.

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.

这篇关于使用@Convert转换地图(JPA)密钥的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆