当前位置: 首页 > 知识库问答 >
问题:

JPA(EclipseLink)自定义类型可能吗?

危砚
2023-03-14

问题的核心似乎是Eclipselink中没有到JSON类型的内部映射。因此,使用一种简单的方法:

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

...在尝试插入一个html" target="_blank">对象时,我遇到了一个异常:

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

我想很公平。

通过查看EclipseLink文档,似乎适用的定制(转换映射、本机查询、转换器)依赖于由所支持的映射(数字、日期、字符串等)组成的数据,因此使用特定于供应商的类型很难做到这一点。

这是如此令人沮丧的主要原因是,posgresql中的JSON类型与text/varchar表示相同,我认为(目前,但不是永远)只是该类型的别名--因此驱动程序更有能力传输该类型,在我看来,它只是验证规则。

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

共有1个答案

仲皓君
2023-03-14

通过遍历,我发现了许多类似于映射到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;
        }
    }
}
implements AttributeConverter<String, PGobject>
 类似资料:
  • 问题内容: 我尤其对使用PostgreSQLs 类型感兴趣。 问题的核心似乎是Eclipselink中没有要 类型的内部映射。因此,使用朴素的方法: …并尝试插入对象,但出现异常: 我猜很公平。 浏览EclipseLink文档,似乎适用的自定义项(转换映射,本机查询,转换器)依赖于由受支持的映射(数字,日期,字符串等)组成的数据,因此这使使用它变得很尴尬供应商特定类型。 令人沮丧的主要原因是pos

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

  • Rust 自定义数据类型主要是通过下面这两个关键字来创建: struct: 定义一个结构体 enum: 定义一个枚举类型 而常量的创建可以通过 const 和 static 关键字来创建。

  • 存在多种方法来重新定义现有类型的行为以及提供新的类型。 重写类型编译 一个常见的需求是强制更改类型的“字符串”版本,即在create table语句或其他SQL函数(如cast)中呈现的版本。例如,应用程序可能希望强制呈现 BINARY 适用于除一个平台外的所有平台 BLOB 待渲染。在本例中,使用现有的泛型类型 LargeBinary ,是大多数用例的首选。但是为了更准确地控制类型,每个方言的编

  • 1. 包含头文件 #import <AdHubSDK/AdHubSDK.h> 2. AdHubCustomView 的创建和初始化 在需要导入广告的ViewController头文件中导入头文件并声明实例以及声明代理 #import <AdHubSDK/AdHubSDK.h> @interface AdHubCustomViewController ()<AdHubCustomViewDele

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