CriteriaQuery OneToMany 与对象列表

时间:2021-03-01 15:48:01

标签: spring-boot criteria hibernate-criteria criteria-api

我有一个动态 api,它将接受将作为响应发送的字段列表。以下是我的实体。

public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "parentPK", nullable = false)
    private Integer id;
    
    // some other fields.
    
    @JsonIgnore
    @OneToMany(mappedBy = "parent")
    @ToString.Exclude
    @JsonManagedReference
    private List<Child> childs;

    private String createdUser;
    private String updatedUser;
}

public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "childPK", nullable = false)
    private Integer id;
    
    @Column(name = "value")
    private String val;
}

现在用户可以传递如下字段

"id", "childs.val", "createdUser"

下面的方法将准备选择查询。

public <T> void preparingSelectionList(List<String> fields, Root<T> root,
        CriteriaQuery<Object[]> criteriaQuery) {
    List<Selection<?>> selectionList = new ArrayList<>();
    List<Join<?, ?>> joins = new ArrayList<>();
    List<String> typeList  = new ArrayList<>();
    
    fields.forEach(field -> {
        if (field.contains(".")) {
            String[] fieldArr = field.split("\\.");
            
            Selection<?> selectionObj = null; 
            
            if(root.get(fieldArr[0]).getJavaType().equals(List.class)) {
                Join<?, ?> join  = root.joinList(fieldArr[0], JoinType.LEFT);
                joins.add(join);
                selectionObj = join.get(fieldArr[1]);
                selectionList.add(selectionObj);
            } else {
                selectionObj = root.get(fieldArr[0]).get(fieldArr[1]);
                selectionList.add(selectionObj);
            }
            
            if(!typeList.contains(fieldArr[0]) && !root.get(fieldArr[0]).getJavaType().equals(List.class)) {
                Join<Object, Object> joinItem = root.join(fieldArr[0], JoinType.LEFT); 
                joins.add(joinItem);
                typeList.add(fieldArr[0]);
            }
        } else {
            Selection<?> selectionObj = root.get(field);
            selectionList.add(selectionObj);
        }
    });
    criteriaQuery.multiselect(selectionList);
}

稍后在我的代码中,

TypedQuery<Object[]> typedQuery = entityManager.createQuery(criteriaQuery);
List<Object[]> resultList = typedQuery.getResultList();

当我调试时,resultList 对象包含如下,

{"id":1,"childs":{"val":"abcd"},"createdUser":"user1"}

我不知道为什么它总是只返回单个值以及为什么不是它的数组。类似于下面的内容。

{"id":1,"childs":[{"val":"abcd"}, {"val":"xyz"}],"createdUser":"user1"}

我在上面遗漏了什么?

0 个答案:

没有答案
相关问题