2016-12-14 6 views
0

Ich versuchte, verknüpfte Werte aus mehreren Tabellen in einem benutzerdefinierten POJO mithilfe einer systemeigenen Abfrage abzurufen. Einer der Werte, die ich abrufen möchte, ist ein JSONB-Feld. Während ich in der Lage bin, die Entität mit diesem Feld zu erhalten, erhalte ich eine 'org.hibernate.MappingException: Keine Dialekt-Zuordnung für JDBC-Typ: 1111' Ausnahme, wenn ich sie in den benutzerdefinierten POJO erzwinge. Hier ist, was ich verwendet:JPA native Abfragezuordnung POJO-Klasse mit JSONB-Wert auf PostgreSQL

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

Mit der POJO suchen:

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

Mit seiner MyJson Klasse:

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

    private String value; 
} 

Und

@Entity 
@Data 
@NoArgsConstructor 
public class Price { 

    @Id 
    private Long id; 
    private BigDecimal price; 
} 

Und meine Gewohnheit POJO

@AllArgsConstructor 
@Data 
public class CustomPOJO { 

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

Die benutzerdefinierte Dialektzuordnung '@TypeDef' ist implementiert wie this. Die @SqlResultSetMapping habe ich von here. Jetzt versuche ich meine benutzerdefinierte Zuordnung abfragen mit:

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

Ich weiß, dass Hibernate ist die Typdefinition nicht erkennen, wenn ich meine benutzerdefinierten SqlResultSetMapping Annotation verwenden. Wie kann ich das beheben? Beachten Sie, dass TypedQueries nicht verwendet werden kann, da meine tatsächlichen Abfragen zu komplex sind, als ich mit der JPA-Abfragesyntax verarbeiten kann. Bei Bedarf kann ich ein Beispielprojekt auf GitHub hochladen.

+0

Werfen Sie einen Blick auf dieses Tutorial: http://www.thoughts-on-java.org/persist-postgresqls-jsonb-data-type-hibernate/ –

+0

Das ist, was ich in erster Linie verwendet (ich habe es sogar verlinkt). Das Problem ist, dass der benutzerdefinierte Dialekt nicht erkannt wird, sobald ich das SqlResultSetMapping verwende. – SlideM

Antwort

0

Ich habe es geschafft, es zu beheben. Wie sich herausstellt, müssen Sie jeder Spalte in SqlResultSetMapping mitteilen, welchen Typ sie darstellen soll. Für das Jsonb-Feld der Feldklasse MyJson müssen Sie die benutzerdefinierte UserType-Klasse 'MyJsonType' (Implementation on this Site) verwenden. Das sieht wie folgt aus:

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

Offensichtlich müssen Sie den entsprechenden Konstruktor für die benutzerdefinierte pojo Klasse, in meinem Beispiel Pflege mit der @AllArgsConstructor Anmerkung genommen thats,.

Verwandte Themen