JPA 本机查询映射 POJO class 与 PostgreSQL 上的 JSONB 值
JPA native query mapping POJO class with JSONB value on PostgreSQL
我试图使用本机查询将多个表中的连接值检索到自定义 POJO 中。我要检索的值之一是 JSONB 字段。虽然我能够获得具有该字段的实体,但当我将其强制放入自定义 POJO 时,我得到了一个 'org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111' 异常。这是我使用的:
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 class:
@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 相同。
我从 here 获得的 @SqlResultSetMapping。
现在我尝试使用我的自定义映射进行查询:
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.
上上传示例项目
我设法修复了它。事实证明,您需要告诉 SqlResultSetMapping 中的每一列它应该代表哪种类型。对于字段 class MyJson 的 Jsonb 字段,您需要使用自定义 UserType class '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 的适当构造函数 class,在我的示例中,这是通过 @AllArgsConstructor 注释处理的。
我试图使用本机查询将多个表中的连接值检索到自定义 POJO 中。我要检索的值之一是 JSONB 字段。虽然我能够获得具有该字段的实体,但当我将其强制放入自定义 POJO 时,我得到了一个 'org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111' 异常。这是我使用的:
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 class:
@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 相同。 我从 here 获得的 @SqlResultSetMapping。 现在我尝试使用我的自定义映射进行查询:
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.
上上传示例项目我设法修复了它。事实证明,您需要告诉 SqlResultSetMapping 中的每一列它应该代表哪种类型。对于字段 class MyJson 的 Jsonb 字段,您需要使用自定义 UserType class '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 的适当构造函数 class,在我的示例中,这是通过 @AllArgsConstructor 注释处理的。