java 使用hibernate隔离查询JSONMap字段

xoshrz7s  于 2023-06-28  发布在  Java
关注(0)|答案(1)|浏览(121)

我有一个Hibernate实体,它有一个Map到jsonb列的字段。如果我对整个对象进行操作,我可以使用Repository轻松地存储和检索它:

@Entity
public class Parent {
...
  @Column(name = "children", nullable = false, columnDefinition = "JSONB")
  @Type(JsonType.class)
  List<Child> children;
...

我想添加一个Repository方法来单独加载该列。我试过:

@Query("""
      SELECT p.children
      FROM Parent p
      WHERE p.id = :parentId
      """)
  List<Child> getChildren(@Param("parentId") long parentId);

这给了我一个错误:

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.example.Child]
    at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:322)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:195)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)
...

转换器必须存在于我的项目中,因为我可以将Parent类作为一个整体加载,而List<Child>就在那里。我怎样才能重用它来独立地加载这个列呢?

5rgfhyps

5rgfhyps1#

您有以下选项,

选项一

像这样使用JPQL

@Query("""
      SELECT new com.package.entity.ClassName(p.children)
      FROM Parent p
      WHERE p.id = :parentId
      """)

确保您正在使用的构造函数存在于类中,

选项二

使用@NamedNativeQuery而不是普通的@Query
例如:实体类:

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
@SqlResultSetMapping(
        name = "userEntityMapping",
        classes = {
                @ConstructorResult(
                        targetClass = StatsDTO.class,
                        columns = {
                                @ColumnResult(name = "campId", type = Integer.class),
                                @ColumnResult(name = "userCount", type = Byte.class),
                                @ColumnResult(name = "modifiedAt", type = Instant.class)
                        }
                )
        }
)
@NamedNativeQuery(
        name = "UserEntity.getStatsDTO",
        query = "YOUR_QUERY",
        resultSetMapping = "userEntityMapping"
)
@Table(name = "user_campaign_objective")
public class UserEntity implements Serializable {
    private static final long serialVersionUID = 1224483473794225719L;

    @Id
    @Column(name = "campaign_id")
    private BigInteger campId;
}

存储库类:

public interface UserRepository extends CrudRepository<UserEntity, Long> {
    @Query(nativeQuery = true)
    List<StatsDTO> getStatsDTO(Long campId);
}

选项三

使用投影界面

public interface QueryResponse {
    String getColumn3();
    Byte getColumn2();
    Instant getColumn3();
}

确保getter中的列名是精确的

相关问题