Hibernate 标准查询中的嵌套 Java 记录

问题描述 投票:0回答:1

我无法使用嵌套 Java 记录进行 hibernate citeria 查询,因为: 原因:org.postgresql.util.PSQLException:错误:“.”处的语法错误

我将Java记录定义如下:

public record RoomRecord(Long id, String identifier, int bedsNumber, int        Set<BedRecord> beds) {
    public record BedRecord(Long id, String identifier, Integer position) {}
}

以下是我的条件查询:

CriteriaBuilder builder = getCriteriaBuilder();
CriteriaQuery<RoomRecord> criteria = builder.createQuery(RoomRecord.class).distinct(true);
Root<Room> root = criteria.from(Room.class);
criteria.where(builder.equal(root.get(Room_.organization), organization));
criteria.select(builder.construct(RoomRecord.class, root.get(Room_.id),       root.get(Room_.identifier), root.get(Room_.floor), root.get(Room_.bedsNumber),
            root.get(Room_.virtualBedsNumber), root.get(Room_.beds)));`
hibernate hibernate-criteria criteriaquery java-record
1个回答
0
投票

您遇到的问题源于 Hibernate(以及一般的 JPA)不完全支持嵌套 Java 记录,特别是在尝试映射 RoomRecord 中的 Set 之类的嵌套关系时。 Hibernate 可能正在努力构建嵌套结构 Room_.beds 的查询,该结构表示为 Set。

解决方案:正确映射嵌套Set

  1. 单独获取集合 最简单的方法是单独处理 Set。您可以分别获取 Room 和 Bed 实体,然后在 Java 代码中手动将它们映射到 RoomRecord。

例如:

CriteriaBuilder builder = getCriteriaBuilder();
    
    // Query for Room entity
    CriteriaQuery<Tuple> roomCriteria = builder.createTupleQuery();
    Root<Room> roomRoot = roomCriteria.from(Room.class);
    roomCriteria.multiselect(
        roomRoot.get(Room_.id),
        roomRoot.get(Room_.identifier),
        roomRoot.get(Room_.bedsNumber)
    );
    roomCriteria.where(builder.equal(roomRoot.get(Room_.organization), organization));
    
    // Execute query and map results to RoomRecord
    List<Tuple> rooms = entityManager.createQuery(roomCriteria).getResultList();
    List<RoomRecord> roomRecords = rooms.stream()
        .map(tuple -> {
            Long roomId = tuple.get(0, Long.class);
    
            // Fetch nested beds for the room
            CriteriaQuery<Bed> bedCriteria = builder.createQuery(Bed.class);
            Root<Bed> bedRoot = bedCriteria.from(Bed.class);
            bedCriteria.where(builder.equal(bedRoot.get(Bed_.room), roomId));
    
            List<Bed> beds = entityManager.createQuery(bedCriteria).getResultList();
            Set<RoomRecord.BedRecord> bedRecords = beds.stream()
                .map(bed -> new RoomRecord.BedRecord(bed.getId(), bed.getIdentifier(), bed.getPosition()))
                .collect(Collectors.toSet());
    
            return new RoomRecord(
                roomId,
                tuple.get(1, String.class),
                tuple.get(2, Integer.class),
                bedRecords
            );
        })
        .collect(Collectors.toList());
© www.soinside.com 2019 - 2024. All rights reserved.