dan*_*car 8 postgresql hibernate jpa hql jpql
实体关系:交易(@ManyToOne - 默认情况下急切) - >账户
String sql = "SELECT new com.test.Pojo(t.account, SUM(t.value)) FROM Transaction t GROUP BY t.account";
List list = entityManager.createQuery(sql).getResultList();
Run Code Online (Sandbox Code Playgroud)
默认情况下,使用Hibernate实现的JPA将生成1 + n个查询.n个查询用于延迟加载帐户实体.
如何通过单个查询急切地使用此查询并加载所有内容?sql等价物就像是
SELECT account.*, SUM(t.value) FROM transactions JOIN accounts on transactions.account_id = accounts.id GROUP BY account.id
Run Code Online (Sandbox Code Playgroud)
,一种在PostgreSQL上运行良好的语法.根据我的发现,Hibernate正在生成一个可以证明延迟加载的查询.
SELECT account.id, SUM(t.value) FROM transactions JOIN accounts on transactions.account_id = accounts.id GROUP BY account.id
Run Code Online (Sandbox Code Playgroud)
尝试将该@ManyToOne字段标记为惰性:
@ManyToOne(fetch = FetchType.LAZY)
private Account account;
Run Code Online (Sandbox Code Playgroud)
JOIN FETCH并使用字段之一更改您的查询,account以仅生成一个包含您所需的查询,如下所示:
String sql = "SELECT new com.test.Pojo(acc, SUM(t.value)) "
+ "FROM Transaction t JOIN FETCH t.account acc GROUP BY acc";
Run Code Online (Sandbox Code Playgroud)
更新:
抱歉,你是对的, 的 fetch 属性@ManyToOne不是必需的,因为在 Hibernate 中这是默认值。不起作用JOIN FETCH,它导致QueryException:“查询指定的联接获取,但获取的关联的所有者不存在”。
我尝试过其他一些方法,避免执行 n + 1 次查询的最简单方法是Pojo从查询中删除对象的创建并处理结果列表,手动创建对象:
String hql = "SELECT acc, SUM(t.value)"
+ " FROM " + Transaction.class.getName() + " t"
+ " JOIN t.account acc"
+ " GROUP BY acc";
Query query = getEntityManager().createQuery(hql);
List<Pojo> pojoList = new ArrayList<>();
List<Object[]> list = query.getResultList();
for (Object[] result : list)
pojoList.add(new Pojo((Account)result[0], (BigDecimal)result[1]));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
227 次 |
| 最近记录: |