实体关系:交易(@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();
默认情况下,使用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
,一种在Postgresql上运行良好的语法.根据我的发现,Hibernate正在生成一个可以证明延迟加载的查询.
SELECT account.id,SUM(t.value) FROM transactions JOIN accounts on transactions.account_id = accounts.id GROUP BY account.id
尝试将@ManyToOne字段标记为惰性:
@ManyToOne(fetch = FetchType.LAZY) private Account account;
并使用帐户字段的JOIN FETCH更改您的查询,以便只生成一个您需要的查询,如下所示:
String sql = "SELECT new com.test.Pojo(acc,SUM(t.value)) " + "FROM Transaction t JOIN FETCH t.account acc GROUP BY acc";
更新:
对不起,您是对的,不需要@ManyToOne的fetch属性,因为在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]));