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

如何使用JPA存储通用实体?

胡景焕
2023-03-14

我有一个通用实体,我想使用JPA持久化,以便它的通用值存储在单个jsonb列中。简化的实体类如下所示:

@Entity
public class Generic<T> {

    @Id
    private String name;

    private Type type;

    private T value; // want to store it in jsonb column

    // ... constructros, getters
}

类型唯一标识泛型值的类,并且允许具有相同类的多个类型:

public enum Type {

    TYPE1(Double.class),
    TYPE2(Double.class),
    TYPE3(Coordinate.class),
    ...
    TYPEN(Double.class);

    private Class<?> aClass;

    TelemetrySignal(Class<?> aClass) {
        this.aClass = aClass;
    }

    Class<?> getClass() {
        return aClass;
    }
}

我没有找到如何使用Hibernate保持这种泛型类的方法。我找到了替代方法和变通方法,但它们在我看来并不理想。我考虑了以下选项:

>

将值的类型设置为JsonNode,并将其类型类标记为com。弗拉德米尔恰。冬眠类型html" target="_blank">json。JsonBinaryType。在这种情况下,只需要一个Java类,但缺点是我必须在其余代码中与JsonNode进行交互。我必须在需要类信息时来回转换,例如,将其传递给适当的处理程序。

我还考虑了选项,但未能实施:

我试图实现我自己的org.hibernate.type.Type并使用com.vladmihalcea.hibernate.type.ImMutableType来简化它。这个想法是在处理value列时查看type列,并将值反序列化为相应的类。但是我未能正确实现T get(ResultSet rs, String[]name,...),因为我只获取当前列的值名称,而无法从ResultSet中获取type列的值(Hibernate为所有列创建别名)。

我尝试使用两个字段:@瞬态T值和JsonNode genericValue。其思想是在@PrePersist方法中将值从@瞬态T值转换为JsonNode genericValue,并使用@PostLoad方法中带有类信息的类型字段将JsonNode转换为@瞬态T值。但事实证明,在PrePersist方法中,Transient字段是空的。

目前我已经停止了第二个选项,但我考虑了第五个选项:为此实体创建自定义存储库并仅对此类使用JdbcTemboard而不是Hibernate。这绝对是可能的,因为我可以从ResultSet获取type列并将值反序列化为适当的类。但我仍然有机会有人会使用Hibernate提供替代选项。有什么想法吗?


共有1个答案

鱼浩荡
2023-03-14

JPA提供了一种将数据库转换为实体的方法,但您需要额外的层来将数据库对象转换为所需的对象类型。

我认为这种逻辑是错误的。。。但无论如何。。。

@Entity
@Table(name ="generic_table") // put the correct name
public class Generic {

  @Id
  private String name;

  @Column(name = "generic_type")
  @Enumerated(EnumType.STRING)   // put here the correct conf for each field
  private Type type;

  @Column(name = "generic_value")
  private binary[] value; // want to store it in jsonb column then it's a binary array for us. 


}

稍后创建一个进行解析的方法:

public <T> T parseGeneric(class<T>, binary[] content){
  // parsing here
}

希望这对你有帮助!

 类似资料:
  • 以下是我的模型:- 我的存储库和服务:- 控制器:- org.springframework.beans.factory.beanCreationException:创建类路径资源[org/springframework/boot/autocconfigure/orm/jpa/hibernatejpaconfiguration.class]中定义的名为“Entity ManagerFactory”

  • 我正在开发一个迁移软件,它将使用来自REST服务的未知数据。 我已经考虑过使用MongoDB,但我决定不使用它,而是使用PostgreSQL。 读完本文后,我试图在我的SpringBoot应用程序中使用SpringJPA实现它,但我不知道在我的实体中映射。 我试过了,但什么也不懂! 这里就是我所在的地方: 和... 下表: 我该怎么做? 注意:我不想/不需要一个实体来工作。我的JSON将永远是St

  • 问题内容: 我想知道是否可以使用批注使用JPA2 将地图持久化到以下类中 由于我们已经有一个现有的生产数据库,因此理想情况下,值 可以映射到以下现有表: 问题答案: JPA 2.0通过注释可以支持原语集合,你可以将其与集合支持一起使用。这样的事情应该起作用: 另请参见(在JPA 2.0规范中) 2.6 - Collections of Embeddable Classes and Basic Ty

  • 我有几个实体,并使用Spring Data JPA存储库与规范查询我的数据库。因此,我创建了一个泛型类< code>SpecBuilder来基于查询描述(< code>MyQueryDescriptor)构建我的查询。 我的存储库: 和 现在有三件事我不太确定:< br> 1) 使用泛型SpecBuilder是一个干净的设计吗? 2) 有没有办法避免为每个实体编写这些存储库接口?假设一个通用存储库

  • 问题内容: 我有以下实体类: 然而, 持续的,然后从与JPA 2.2结果数据库读取的实体/在信息丢失 :所述的改变(在所使用的数据库的时间戳)。例如: 我需要使用:我不能使用,因为区域规则会发生变化(无论如何,这也会遭受此信息丢失的困扰)。我无法使用,因为某事发生在世界任何地方,出于准确性原因,我需要它发生时的原始内容。我无法使用,因为用户填写了事件的开始时间(事件就像约会一样)。 要求: 需要能

  • 我们正在研究一个包含大量DB表的Restful项目。虽然对这些表的操作几乎相同,主要是插入/更新/删除/提取(insert/update/delete/fetch)。 我的问题是: 我们是否必须为我们创建的每一个实体(域类)创建一个存储库(扩展JpaRepository),或者,有一个选项可以为所有实体创建一个能够处理上述所有功能的GenericRepository?即为所有人提供一个单一的Gen