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