是否值得使用Hibernate + PostgreSql JSONB?

Ave*_*tes 9 hibernate jpa jsonb

我正在研究使用Hibernate 5和PostgreSQL JSONB,但是我遇到了Hibernate正确支持它的问题.

你有任何解决方案,可能是库,如何实现对Hibernate + Spring JPA的JSONB支持?

此外,您可以通过这种方法注意到哪些优点和缺点?

Cep*_*pr0 23

感谢Vlad Mihalcea我们有这样的机会!)

他创建了hibernate类型的 lib:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>2.1.1</version>
</dependency> 
Run Code Online (Sandbox Code Playgroud)

它为'json','jsonb'和其他类型添加了对Hibernate的支持:

@Data
@NoArgsConstructor
@Entity
@Table(name = "parents")
@TypeDefs({
        @TypeDef(name = "string-array", typeClass = StringArrayType.class),
        @TypeDef(name = "int-array", typeClass = IntArrayType.class),
        @TypeDef(name = "json", typeClass = JsonStringType.class),
        @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
public class Parent implements Serializable {

    @Id
    @GeneratedValue(strategy = SEQUENCE)
    private Integer id;

    @Column(length = 32, nullable = false)
    private String name;

    @Type(type = "jsonb")
    @Column(columnDefinition = "jsonb")
    private List<Child> children;

    @Type(type = "string-array")
    @Column(columnDefinition = "text[]")
    private String[] phones;

    public Parent(String name, List<Child> children, String... phones) {
        this.name = name;
        this.children = children;
        this.phones = phones;
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Child implements Serializable {
    private String name;
}
Run Code Online (Sandbox Code Playgroud)

更多信息:1,2

  • @Aventes Vlad是[Hibernate作者]之一(http://stackoverflow.com/users/1025118/vlad-mihalcea) (4认同)
  • @Aventes [Hibernate Types 框架](https://github.com/vladmihalcea/hibernate-types) 拥有超过 750 个 GitHub star,每月下载量超过 40 万次。因此,社区相当大,因为 Hibernate Types 框架提供了对 JSON、ARRAY、Inet、HStore、TSVector、DB 特定枚举、YearMonth 和许多其他功能的支持。 (2认同)
  • JSON 和 ARRAY 是标准的,但并非 Hibernate 支持的所有数据库都支持它们。有一天,它可能会支持。同时,您可以使用 Hibernate Types 项目。 (2认同)

dim*_*nnv 10

Hibernate 6+ (2022+) 更新

随着 Hibernate 6 的出现,开箱即用地映射到 PostgreSQL JSON(B) 成为可能

只需要对该字段进行注释即可JdbcTypeCode(SqlTypes.JSON)

对于非类型化 JSON:

@Entity
public class Entity {
    ...
    @JdbcTypeCode(SqlTypes.JSON)
    private Map<String, String> payload;
    ...
}
Run Code Online (Sandbox Code Playgroud)

(尽管并非每个 JSON 都会序列化为 Map)。

使用被序列化为自定义 Java 类型的 JSON:

public class Foo implements Serializable {
  
    private String strValue;
    private Long longValue;
  
    public String getStrValue() {
        return strValue;
    }
  
    public void setStringProp(String stringProp) {
        this.strValue = strValue;
    }
  
    public Long getLongValue() {
        return longProp;
    }
  
    public void setLongValue(Long longValue) {
        this.longValue = longValue;
    }
}


@Entity
public class Entity {
    ...
    @JdbcTypeCode(SqlTypes.JSON)
    private Foo fooJson;
    ...
}
Run Code Online (Sandbox Code Playgroud)

请参阅本文了解更多示例: https://thorben-janssen.com/persist-postgresqls-jsonb-data-type-hibernate/


GRO*_*X13 6

@Cepr0 -s 答案是正确的,但尽管我遇到了一些问题。当我尝试将它与 PostgreSQL 一起使用时遇到异常org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111。就我而言,解决这个问题的方法是添加自定义休眠方言。资源可能会有所帮助。

// CustomPostgreSQLDialect.java
public class CustomPostgreSQLDialect extends PostgreSQL10Dialect {

    public CustomPostgreSQLDialect() {
        super();
        registerHibernateType(Types.OTHER, StringArrayType.class.getName());
        registerHibernateType(Types.OTHER, IntArrayType.class.getName());
        registerHibernateType(Types.OTHER, JsonStringType.class.getName());
        registerHibernateType(Types.OTHER, JsonBinaryType.class.getName());
        registerHibernateType(Types.OTHER, JsonNodeBinaryType.class.getName());
        registerHibernateType(Types.OTHER, JsonNodeStringType.class.getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

-

# application.yml
spring:
  jpa:
    properties:
      hibernate:
        dialect: "com.test.CustomPostgreSQLDialect"
Run Code Online (Sandbox Code Playgroud)