有没有一种优雅而通用的方法将PostgreSQL hstore转换为JPA 2.1 DataType?

时间:2014-03-07 05:55:14

标签: java hibernate postgresql jpa eclipselink

我使用JPA 2.1 Converter将PostgreSQL hstore转换为Map<String, String>。 但我没有找到适用于EclipseLink和Hibernate等不同JPA提供程序的通用方法。所以我需要为每个JPA提供程序编写不同的转换器。

以下是对EclipseLink和Hibernate使用不同转换器的示例。 https://github.com/phstudy/jpa-converter-sample

对于不同的JPA提供商,是否存在通用方式?

3 个答案:

答案 0 :(得分:5)

PostgreSQL JDBC驱动程序提供org.postgresql.util.HStoreConverter实用程序类,可以进行Stringbyte[]转换。您可以使用它来实现自己的JPA 2.1 Converter

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.Map;
import org.postgresql.util.HStoreConverter;

@Converter
public class MyHStoreConverter implements AttributeConverter<Map<String, String>, String> {
    @Override
    public String convertToDatabaseColumn(Map<String, String> attribute) {
        return HStoreConverter.toString(attribute);
    }

    @Override
    public Map<String, String> convertToEntityAttribute(String dbData) {
        return HStoreConverter.fromString(dbData);
    }
}

然后,在实体中使用JPA Convert注释:

@Entity
public class MyEntity {
    @Convert(converter = MyHStoreConverter.class)
    private Map<String, String> hstoreAttribute;
}

这是一个仅使用JPA标准的实现,因此应该是JPA-provider不可知的。但是,使用Converter映射到通用Map<>之前已被Hibernate错误HHH-8804阻止,但已在Hibernate 5.0.0和4.3.11中修复。

答案 1 :(得分:0)

我没有使用它,但我的理解是新的JPA 2.1 @Converter旨在带来一种创建自定义类型的通用方法。

看起来你有正确的解决方案但是你遇到了EclipseLink和Hibernate实现的麻烦。

您可以通过单convertToEntityAttribute(Object object)方法处理所有不同的案例来找到出路。

答案 2 :(得分:0)

我已尝试(部分)您的代码,但在生成表时会出现异常: 内部异常:org.postgresql.util.PSQLException:错误:类型»hstore«不存在(Postgresql 9.1)。这意味着我只有一个想法。尝试定义两种方法:

@Override
convertToEntityAttribute(Object object)

//without @Override
convertToEntityAttribute(String string)

然后对其他方法执行相同操作。最终改变哪一个被覆盖。

PS:您可以使用@ElementCollection批注直接映射Map,这样可以避免使用转换器(如果您不使用已有数据的旧数据库)