hibernate Blaze-Persistence:如何从getResultList()获取真实对象?

wwwo4jvm  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(95)

我有一个很好的Blaze-Persistence查询,它带有一个WITH CTE,与多个其他查询一起使用,并使用联合。查询具有正确的结果(截至SQL)。

public List<FilterResult> getFilters(HourSearchDto hourSearchDto) {
  ...
  FinalSetOperationCriteriaBuilder<FilterResult> cb = cbf.create(entityManager, FilterResult.class)
    // Start with the WITH()
    .with(HourCTE.class, false)
      .from(Hour.class, "hour")
      .bind("id").select("id")
      .bind("employeeId").select("employee.id")
      .bind("taskId").select("task.id")
      .where("UPPER(hour.description)").like().expression("'%" + hourSearchDto.getDescription().toUpperCase() + "%'").noEscape()
    .end()
    // First select, for reference Employee. Use the selectNew(FilterResult.class) to map the result to FilterResult.
    .selectNew(FilterResult.class)
      .with("employee.id", "id")
      .with("'EMPLOYEE'", "referenceName")
      .with("COUNT(hour.employeeId)", "count")
      .with("FORMAT('%1$s (%2$s)', employee.firstName, COUNT(hour.employeeId))", "displayValue")
    .end()
    .from(Employee.class, "employee")
    .leftJoinOn(HourCTE.class, "hour")
      .on("hour.employeeId").eqExpression("employee.id")
    .end()
    // UNION to add next select.
    .union()
    // Next select, for reference Task. Simple select as first select above maps the result to FilterResult already.
    .select("task.id", "id")
    .select("'TASK'", "referenceName")
    .select("COUNT(hour.taskId)", "count")
    .select("FORMAT('%1$s (%2$s)', task.name, COUNT(hour.taskId))", "displayValue")
    .from(Task.class, "task")
    .leftJoinOn(HourCTE.class, "hour")
      .on("hour.taskId").eqExpression("task.id")
    .end()
    .endSet()
    .orderByAsc("referenceName")
    .orderByAsc("displayValue");

    return cb.getQuery().getResultList();
}

问题是,结果作为ArrayList<Object[4]>返回,而不是预期的ArrayList<FilterResult>。当我删除联合及其查询时,.selectNew(FilterResult.class)正确地构造了ArrayList<FilterResult>
如何确保完整的查询(包括联合)也返回ArrayList<FilterResult>
为了完整起见:

public class FilterResult {

    @Id
    Long id;

    String referenceName;

    Long count;

    String displayValue;

    public FilterResult() {
    }

    public FilterResult(Long id, String referenceName, Long count, String displayValue) {
        this.id = id;
        this.referenceName = referenceName;
        this.count = count;
        this.displayValue = displayValue;
    }

    // Getters
}
@CTE
@Entity
public class HourCTE {

    @Id
    private Long id;

    private Long employeeId;

    private Long taskId;
}
x6yk4ghg

x6yk4ghg1#

这是当前API的限制。您可以跟踪https://github.com/Blazebit/blaze-persistence/issues/565以了解此事的进展情况。一种可能的解决方法是将联合零件 Package 到另一个CTE中,然后在从该CTE中选择的查询中仅使用一次selectNew零件。

相关问题