Java 如何通过 JPA 2.1 获得包含属性和列表的多选结果?

How to get multiselect results containing both properties and lists via JPA 2.1 in Java?

目标是使用多选获取员工的名字、姓氏和待办事项列表:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root emp = q.from(Employee.class);

q.multiselect(
    emp.get("firstName").alias("fname"),
    emp.get("lastName").alias("lname"),
    emp.get("toDoList").alias("toDoList")
).where(cb.equal(emp.get("id"), 12345));

List<Tuple> tuples = em.createQuery(q).getResultList();
Iterator<Tuple> iter = tuples.iterator();

while(iter.hasNext()){
    Tuple t = iter.next();
    //t.get("fName");     // returns String
    //t.get("lName");     // returns String
    //t.get("toDoList");  // returns String

    //?????
    //...

}

toDoList 只是一个简单的字符串列表。假设员工 12345 有 4 个待办事项。这意味着我得到以下结果集:

---------------------------------
| firstName | lastName | toDo   |
---------------------------------
| John      | Doe      | sleep  |
---------------------------------
| John      | Doe      | eat    |
---------------------------------
| John      | Doe      | play   |
---------------------------------
| John      | Doe      | laugh  |
---------------------------------

现在我正在寻找一种创建 ONE Employee 实例并一次性设置其 firstName、lastName 和 toDoList 的聪明方法:

Employee employee = new Employee();
employee.setFirstName(...);
employee.setLastName(...);
employee.setToDoList(...); 

最好的方法是什么?如果我添加其他关系(即 favoriteSongs),事情会变得更加复杂。

不幸的是,您必须为 multiselect 调用的每个组合编写代码才能从元组列表中获取数据,而且该代码可能非常脏。

通过一个查询获取关系存在主要缺点:

  • 读取数据的java代码会变得很脏
  • 一个查询起初听​​起来性能不错,但这将为每个提取的行检索重复数据

所以我实际上相信在许多情况下(比如我的情况),执行单独的查询来获取数据是更好的方法。换句话说,我将避免使用混乱的代码,而是使用单选。生成的用于获取投影数据的代码更易于维护且更具可读性。以下是我找到的一些重要链接:

SQL for JPQL with join fetch

A user may want every relationship loaded, but join fetching every relationship, in particular every ToMany relationships will lead to a huge join (outer joins at that), fetching a huge amount of duplicate data.

2. Fetch Join in JPQL

And the main disadvantage is that we need to write additional code which executes the query. But it gets even worse, if the entity has multiple relations and we need to initialize different relations for different use cases. In this case we need to write a query for every required combination of fetch joined relations. This can become quite messy.