当前位置: 首页 > 面试题库 >

JPA(EclipseLink)定制类型是否可能?

鲍永春
2023-03-14
问题内容

我尤其对使用PostgreSQLs json类型感兴趣。

问题的核心似乎是Eclipselink中没有要json 类型的内部映射。因此,使用朴素的方法:

@Column(name = "json", columnDefinition = "json")
public String getJson() {
    return json;
}

…并尝试插入对象,但出现异常:

Internal Exception: org.postgresql.util.PSQLException: ERROR: column "json" is of type json but expression is of type character varying

我猜很公平。

浏览EclipseLink文档,似乎适用的自定义项(转换映射,本机查询,转换器)依赖于由受支持的映射(数字,日期,字符串等)组成的数据,因此这使使用它变得很尴尬供应商特定类型。

令人沮丧的主要原因是jsonposgresql 中的类型表示为与text / varchar相同,并且我相信(目前(但不是永远))只是该类型的别名-
因此,驱动程序具有足够的能力来传输此类型,这只是我的验证规则。

在解决方案方面,我不介意失去可移植性(就数据库不可知和使用特定于供应商的类型而言),而只是想要一种允许我将json类型用作常规JPA实体上的属性并保留所有它习惯的其他行为(模式生成,合并,持久化,事务代码


问题答案:

遍历SO的过程中,我发现了许多类似这样的问题,这些问题涉及映射到Postgres的JSON或XML类型。似乎没有人遇到过从自定义Postgres类型读取的问题,因此这里是使用纯JPA类型转换机制进行读取和写入的解决方案。

Postgres
JDBC驱动程序将未知类型(到Java)的所有属性映射到org.postgresql.util.PGobject对象,因此足以为该类型创建转换器。这是实体示例:

@Entity
public class Course extends AbstractEntity {
    @Column(name = "course_mapped", columnDefinition = "json")
    @Convert(converter = CourseMappedConverter.class)
    private CourseMapped courseMapped;  // have no idea why would you use String json instead of the object to map

    // getters and setters
}

这里是转换器的示例:

@Converter
public class CourseMappedConverter implements AttributeConverter<CourseMapped, PGobject> {
    @Override
    public PGobject convertToDatabaseColumn(CourseMapped courseMapped) {
        try {
            PGobject po = new PGobject();
            // here we tell Postgres to use JSON as type to treat our json
            po.setType("json");
            // this is Jackson already added as dependency to project, it could be any JSON marshaller
            po.setValue((new ObjectMapper()).writeValueAsString(courseMapped));
            return po;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return null;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public CourseMapped convertToEntityAttribute(PGobject po) {
        try {
            return (new ObjectMapper()).readValue(po.getValue(),CourseMapped.class);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

如果您确实需要在实体中坚持使用String JSON表示形式,则可以为String类型创建类似这样的转换器

implements AttributeConverter<String, PGobject>

这是一个非常肮脏的(尽管有效的)概念证明,它还使用伪造的对象序列化来告诉JPA如果对象已更改,

https://github.com/sasa7812/psql-cache-evict-
POC



 类似资料:
  • 问题的核心似乎是Eclipselink中没有到类型的内部映射。因此,使用一种简单的方法: ...在尝试插入一个对象时,我遇到了一个异常: 我想很公平。 通过查看EclipseLink文档,似乎适用的定制(转换映射、本机查询、转换器)依赖于由所支持的映射(数字、日期、字符串等)组成的数据,因此使用特定于供应商的类型很难做到这一点。 这是如此令人沮丧的主要原因是,posgresql中的类型与text/

  • 我知道类似的问题,但它们是在Hibernate的范围内被问到和回答的。我也有同样的问题,但我正在使用Eclipselink,想知道对于Hibernate,是否有更好的或替代的解决方案。 简单地回顾一下这个问题: 我有两个相互继承的类: 现在我想把一个孩子变成父母,或者反过来。 我希望现在p的数据库行是。 另一种方法是这样的: 在这种情况下,我希望与一起保存,并丢失的值。 然而,上面所描述的并不奏效

  • 我收到一个编译错误: 然而,当我移除mapstruct注释处理器时,它可以很好地编译。 所以我认为mapstruct是在类生成之前扫描它们?对此有什么解决方案吗?

  • JPA存储过程参数注释 https://docs.oracle.com/javaee/7/api/javax/persistence/StoredProcedureParameter.html 根据文档,它的类型是JDBC类型。 它应该是Java类型,因为它是类(不是 java.sql.Types.xxx 或JDBCType)?

  • 来自以下来源: https://www.amazon.com/java-complete-reference-herbert-schildt/dp/0071808558 第8章:在继承中使用final 对于私有、静态、最终方法,应该使用早期(静态)方法绑定 所以正如我所认为的,这两个方法应该有不同的绑定类型。检查字节码: 在这里我看到了两个有害的指示。那么有什么方法可以确定类字节码使用了哪种绑定呢

  • 我创建了一个自定义数据类型,用于存储有效和规范化的电子邮件地址: 及其相应的JPA2.1转换器,用于自动向数据库存储和从数据库检索: 现在,我可以将它用作person实体的属性: 这个效果很好。但我有一个问题,当我试图找到所有人的电子邮件地址开始使用QueryDSL。我已经用作为字符串注释了email属性。这样,就可以创建Querydsl元模型,使我能够进行查询(使用),如下所示: 但运行时会出现