2016-12-14 79 views
0

我試圖從多個表檢索使用本機查詢到一個自定義POJO聯合值。我想要檢索的其中一個值是JSONB字段。雖然我能夠使用該字段獲取實體,但是當我將其強制到自定義POJO中時,出現'org.hibernate.MappingException:無法映射JDBC類型:1111'異常。以下是我使用的:JPA原生查詢映射POJO類與PostgreSQL上的JSONB值

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); 

使用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; 
} 

有了它的MyJson類:

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

    private String value; 
} 

而且

@Entity 
@Data 
@NoArgsConstructor 
public class Price { 

    @Id 
    private Long id; 
    private BigDecimal price; 
} 

而且我的自定義POJO

@AllArgsConstructor 
@Data 
public class CustomPOJO { 

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

'@TypeDef'自定義方言映射的執行方式與this類似。 @SqlResultSetMapping我從here得到。 現在,我嘗試使用我的自定義映射查詢:

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(); 

我意識到,當我用我的自定義SqlResultSetMapping註釋,Hibernate並不認識的類型定義。我該如何解決這個問題?請注意,我不能使用TypedQueries,因爲我的實際查詢是複雜的,而我可以用JPA查詢語法處理。如有必要,我可以在github上上傳一個示例項目。

+0

看看這個教程:http://www.thoughts-on-java.org/persist-postgresqls-jsonb-data-type-hibernate/ –

+0

這就是我第一次使用(我甚至連接它)。問題是,只要我使用SqlResultSetMapping,自定義方言就不會被識別。 – SlideM

回答

0

我設法解決它。事實證明,您需要告訴SqlResultSetMapping中的每個列應該表示哪種類型。對於字段類MyJson的Jsonb字段,您需要使用自定義的UserType類'MyJsonType'(Implementation on this Site)。這看起來是這樣的:

@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)}) 
     }) 

很顯然,你需要適當的構造函數自定義POJO類,在我的例子,多數民衆贊成與@AllArgsConstructor註釋照顧。