1
我有一个SQL查询,可以准确获取我需要的数据。问题是我们试图在JPA Criteria API中表达所有查询以保持可移植性,并且我无法弄清楚如何映射这个特定的查询。SQL查询过于复杂以便在JPA Criteria API中显示?
问题是JPA Criteria API子查询类缺少CriteriaQuery类所具有的multiselect()方法。正如你在SQL查询中看到的那样,我计算了子查询中实体中不存在的字段。因此,我无法检索这些字段。
如果有人知道解决方案或可以提供指导,或者即使有人可以验证我在JPA Criteria API中实现的功能是不可能的,我也会非常感激。
的SQL:
SELECT w.NAME AS 'wave_name',
Count(*) AS 'num_lines',
Sum(qty_ordered) AS 'num_units',
Count(DISTINCT unit_of_work_id) AS 'num_units_of_work',
Sum(completed_units) AS 'completed_units',
(Sum(completed_units) + Sum(qty_scratched))/Sum(qty_ordered) AS 'perc_completed_units'
FROM (SELECT t.id,
t.wave_id,
t.quantity_requested AS 'qty_ordered',
t.quantity_scratched AS 'qty_scratched',
t.unit_of_work_id AS 'unit_of_work_id',
Ifnull(m.quantity, 0) AS 'qty_picked',
CASE
WHEN Ifnull(m.quantity, 0) > quantity_requested THEN
quantity_requested
ELSE Ifnull(m.quantity, 0)
END AS 'completed_units'
FROM task t
LEFT OUTER JOIN (SELECT move.task_id,
Sum(quantity) AS 'quantity'
FROM move
GROUP BY task_id) m
ON m.task_id = t.id) s
JOIN wave w
ON w.id = s.wave_id
GROUP BY w.name;
的实体:
@Entity
@Table(name = "task")
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@ManyToOne (cascade = CascadeType.ALL)
@JoinColumn (name = "wave_id", nullable = false)
private Wave wave;
@ManyToOne (cascade = CascadeType.ALL)
@JoinColumn (name = "unit_of_work_id", nullable = false)
private UnitOfWork unitOfWork;
@OneToMany (cascade = CascadeType.ALL, mappedBy = "task")
private Set<Move> moves = new HashSet<Move>();
@Column (name = "quantity_requested")
private Long quantityRequested;
@Column (name = "quantity_scratched")
private Long quantityScratched;
}
@Entity
@Table(name = "wave")
public class Wave {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "wave", cascade = CascadeType.ALL)
private Set<Task> tasks = new HashSet<Task>();
}
@Entity
@Table(name = "unit_of_work")
public class UnitOfWork {
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Column (name = "id")
private Long id;
@OneToMany(mappedBy = "unitOfWork", cascade = CascadeType.ALL)
private Set<Task> tasks = new HashSet<Task>();
}
@Entity
@Table(name = "move")
public class Move {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@ManyToOne (cascade = CascadeType.ALL)
@JoinColumn (name = "task_id", nullable = false)
private Task task;
@Column (name = "quantity")
private Long quantity;
}
为什么只有条件查询为什么不使用命名参数或原生查询方式?如果查询很大,则使用标准方法是没有意义的。 – Arun
我正在处理的项目有一个基于标准的模块,它有助于一般性地将过滤器应用于支持系统中特定数据网格的“预先准备好的”条件查询。直到这一点,“罐装”查询相对简单,这种方法已经足够。但随着更复杂的需求呈现出来,我一直在努力使其对于所有查询都足够通用。我认为,在我的例子中,像这样的疑问就是对这种方法的有力证据。 – Jon
我已经提供了一个示例作为条件的替代方法,请检查它。在这种情况下,我认为标准不是一个好方法。 – Arun