将 Spring Data 与 PostgreSQL JsonB 类型属性一起使用

Posted

技术标签:

【中文标题】将 Spring Data 与 PostgreSQL JsonB 类型属性一起使用【英文标题】:Using Spring Data with PostgreSQL JsonB type properties 【发布时间】:2021-07-27 21:27:08 【问题描述】:

我很难在 Spring Data 中使用带有 JsonB 数据类型的 PostgreSQL。我有下表:

create table mytable (
  ...
  MYDATA JsonB not null,
  ...
);

然后,我有以下实体:

@Entity
@Table(name = "mytable")
...
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
public class MyEntity 
  ...
    @NotNull
    @Type(type = "jsonb")
    @Column(name = "MYDATA", nullable = false)
    private MyAbstractData myAbstractData;
    ...

MyAbstractData 定义如下:

...
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
    @Type(value = MyConcreteData.class, name = "data")
)
...
public abstract class MyAbstractData implements Serializable 
    private String key;
    ...

最后但同样重要的是,MyConcreteData 如下所示:

public class MyConcreteData extends MyAbstractData 
...

我的仓库如下:

@Repository
public interface MyEntityRepo extends CrudRepository<MyEntity, Long> 
  public Optional<MyEntity> findByIdAndSomething (Long id, Something something);

在数据库中,我可以插入值,例如,'"type":"data","key":"i1"' 但是,执行以下操作:

Optional<MyEntity> myEntity = myEntityRepo.findByIdAndSomething(1L, something);

我得到以下异常:

org.springframework.orm.hibernate5.HibernateSystemException: java.lang.IllegalArgumentException: The given string value: "\"type\":\"data\",\"key\":\"i1\"" cannot be transformed to Json object; nested exception is org.hibernate.HibernateException: java.lang.IllegalArgumentException: The given string value: "\"type\":\"data\",\"key\":\"i1\"" cannot be transformed to Json object

但是,我能够使用 fasterxml ObjectMapper 成功序列化/反序列化 MyConcreteData 类,并从字符串““type”:“data”,“key”:“i1””创建一个有效的 JsonNode。

我知道我的案子可能很难跟进,但我仍然希望有人能提供帮助。

非常感谢。

西摩

【问题讨论】:

只是提一下,与我在这里所说的相反,在集成测试期间,使用 H2 数据库时会引发上述异常。因此,如前所述,它不会出现在 PostgreSQL 中,而是在集成测试期间出现在 H2 中。据我所知,这应该不是问题,因为 H2 支持 JsonB。 【参考方案1】:

我正在回答我自己的问题。为了使上面显示的示例正常工作,用于在 H2 数据库中插入数据 test 的脚本应使用 FORMAT JSON 语法,例如:

INSERT INTO MYTABLE (..., MYDATA, ...)
  VALUES (..., '"type":"data","key":"i1"' FORMAT JSON,...);

因此,这里的线索是在插入语句中的 JSON 有效负载之后立即使用 FORMAT JSON。这样,Spring Data 完成的查找操作按预期工作。

【讨论】:

以上是关于将 Spring Data 与 PostgreSQL JsonB 类型属性一起使用的主要内容,如果未能解决你的问题,请参考以下文章

将 Spring 安全 ACL 与 spring-data-mongodb 一起使用

如何将 @Transactional 与 Spring Data 一起使用?

如何将 spring-data-rest 与 spring websocket 混合到一个实现中

java 将Jackson与Spring Data MongoDB一起使用

“没有找到类型的属性”......将 QueryDslPredicateExecutor 与 MongoDB 和 Spring-Data 一起使用时

将 spring data jpa 与 ninja java 一起使用