【发布时间】:2015-07-13 19:15:04
【问题描述】:
上下文
我每周都会向一些企业发送一些文件。无论文件是否发送,我都需要为每个星期和每个企业恢复。
表格
- ent(企业)
- 周(周)
- fil(文件:参考 wek 和 ent)
纯 SQL 解决方案
在 ent 和 wek 之间做一个笛卡尔积,然后左外连接 fil。这有效:
select * from
(
select * from wek, ent e
) as t1
left join fil f
on f.ent_id = t1.ent_id
and f.wek_id = t1.wek_id
问题:
如何将其翻译成 JPA(以 CriteriaBuilder 的方式)?
例如,如果我尝试:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<ResultClass> query = cb.createQuery(ResultClass.class);
Root<Week> week = query.from(Week.class);
Root<Enterprise> query.from(Enterprise.class);
Expression<???> cartesianProduct = ??? //How?
cartesianProduct.leftJoin(???_.file);
query.where(
cb.equal(file.get(File_.wek_id), week.get(Week.week_id));
)
使用 2 个“from”子句可以得到笛卡尔积,但我如何离开加入这个结果?
无法解决的问题:
创建一个视图:
CREATE VIEW view_ent_wek AS
SELECT ent_id as ent_id, wek_id as wek_id, ent_id || '-' || ent_id as id
FROM ent, wek;
将其映射到实体:
@Entity
@Table(name = "view_ent_wek")
public class WeekEnterprise {
@Id
@Column(name = "id")
private String id;
@ManyToOne
@JoinColumn(name = "ent_id")
private Enterprise enterprise;
@ManyToOne
@JoinColumn(name = "wek_id")
private Week week;
[...]
然后我可以在查询中使用它:
Root<WeekEnterprise> weekEnterprise = query.from(WeekEnterprise.class);
weekEnterprise.join(...)
我不喜欢这个解决方案,因为它让我创建了一个显然没有必要的视图。有什么想法吗?
【问题讨论】:
-
不确定但是,你可以试试这个。考虑到,你在
Test1类中将Test2类作为JoinColumn属性。试试这个Root<Test1> root = criteria.from(Test1.class); root.get("test2Object").get("test1FieldInTest2");。我认为它可以让你在Test1和Test2之间进行交叉连接。 -
您究竟想从 JPA 查询中返回什么。我的意思是,你想要列还是实体本身?例如,您是否只想要
ent和wek的ID,后跟一个(可能为null)fil对象?还是要返回ent、wek和(可能为 null)fil对象?
标签: java hibernate postgresql jpa