简体   繁体   English

PostgreSQL上具有JSONB值的JPA本机查询映射POJO类

[英]JPA native query mapping POJO class with JSONB value on PostgreSQL

I was trying to retrieve joined values from multiple tables into a custom POJO using a native query. 我试图使用本机查询将多个表中的联接值检索到自定义POJO中。 One of the values I want to retrieve is a JSONB field. 我要检索的值之一是JSONB字段。 While I'm able to get the entity with that field, I get a 'org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111' exception when I force it into the custom POJO. 当我能够使用该字段获取实体时,当我将其强制进入自定义POJO时,会收到“ org.hibernate.MappingException:JDBC类型的No Dialect映射:1111”异常。 Here is what I used: 这是我使用的:

CREATE TABLE book (
  id BIGSERIAL NOT NULL PRIMARY KEY,
  data JSONB NOT NULL
);
CREATE TABLE price (
  book_id BIGSERIAL NOT NULL PRIMARY KEY,
  price NUMERIC(19,2) NOT NULL
);
INSERT INTO book (id, data) VALUES (0, '{"value": "someValue"}');
INSERT INTO price (book_id, price) VALUES (0, 10.00);

Using the POJO's: 使用POJO:

@Entity
@TypeDef(defaultForType = MyJson.class, name = "MyJsonType", typeClass = MyJsonType.class)
@Data
@SqlResultSetMapping(name = "CustomMapping",
        classes = {
                @ConstructorResult(targetClass = CustomPOJO.class,
                        columns = {@ColumnResult(name = "id"),
                                @ColumnResult(name = "data"),
                                @ColumnResult(name = "price")})
        })
public class Book {

    @Id
    @GeneratedValue
    Long id;

    @Column(nullable = false, columnDefinition = "JSONB")
    MyJson data;
}

With it's MyJson class: 有了MyJson类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyJson implements Serializable {

    private String value;
}

And

@Entity
@Data
@NoArgsConstructor
public class Price {

    @Id
    private Long id;
    private BigDecimal price;
}

And my custom POJO 还有我的自定义POJO

@AllArgsConstructor
@Data
public class CustomPOJO {

    private Long id;
    private MyJson data;
    private BigDecimal price;
}

The '@TypeDef' custom dialect mapping is implemented like this . 这样实现'@TypeDef'自定义方言映射。 The @SqlResultSetMapping I got from here . 我从这里得到的@SqlResultSetMapping。 Now I try to query using my custom mapping: 现在,我尝试使用自定义映射进行查询:

String query = "SELECT id, data, price\n" +
               "FROM book, price\n" +
               "WHERE book.id = price.book_id;";
Query nativeQuery = em.createNativeQuery(query, "CustomMapping");
@SuppressWarnings("unchecked")
List<CustomPOJO> customPOJOS = nativeQuery.getResultList();

I realize that hibernate doesn't recognize the type definition when I use my custom SqlResultSetMapping annotation. 我意识到当我使用自定义SqlResultSetMapping批注时,hibernate无法识别类型定义。 How can I fix that? 我该如何解决? Note that I can't use TypedQueries since my actual queries are way to complex than I can handle with the JPA query syntax. 请注意,我无法使用TypedQueries,因为我的实际查询比JPA查询语法要复杂得多。 If necessary I can upload an example project on github. 如有必要,我可以在github上上传一个示例项目。

I managed to fix it. 我设法解决了。 As it turns out, you need to tell each column in the SqlResultSetMapping which type it should represent. 事实证明,您需要告诉SqlResultSetMapping中的每一列它应该代表哪种类型。 For the Jsonb field of the field class MyJson you need to use the custom UserType class 'MyJsonType' ( Implementation on this Site ). 对于字段类MyJson的Jsonb字段,您需要使用自定义UserType类'MyJsonType'( 在此站点上实现 )。 This looks like this: 看起来像这样:

@SqlResultSetMapping(name = "CustomMapping",
        classes = {
                @ConstructorResult(targetClass = CustomPOJO.class,
                        columns = {@ColumnResult(name = "id", type = Long.class),
                                @ColumnResult(name = "data", type = MyJsonType.class),
                                @ColumnResult(name = "price", type = BigDecimal.class)})
        })

Obviously you need the appropriate constructor for the custom pojo class, in my example thats taken care of with the @AllArgsConstructor annotation. 显然,您需要用于自定义pojo类的适当构造函数,在我的示例中,使用@AllArgsConstructor批注进行了处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM