我有像这样的JPQL:
select distinct d
from Department d
left join fetch d.employees
当我想获取部门实体的一个懒惰属性时, distinct不再工作。
select distinct d, substring(d.htmlDescription, 1,400)
from Department d
left join fetch d.employees
查询返回的部门与其中的员工数量一样多。
substring(d.htmlDescription)
很重要,因为该属性被定义为CLOB(在postgresql下输入TEXT):
@Column(columnDefinition = "TEXT")
@Basic(fetch = FetchType.LAZY)
String htmlBody;
子字符串函数在sql中被翻译,从而限制了数据库和Web服务器之间传输的数据量。
作为一种解决方法,我试图将查询分为两部分:
select d, substring(d.htmlDescription, 1,400)
from Department d where d in (
select distinct d1
from Department d1 left join fetch d1.employees
)
这不起作用,因为JOIN FETCH
不能在子查询的FROM
子句中使用。
答案 0 :(得分:2)
最后我通过以下方式找到了解决问题的方法:
htmlBody字段现在位于另一个实体中。因此,部门实体更轻松。
class Department{
...
@OneToOne (fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
Content content = new Content();
...
}
class Content{
...
@Column(columnDefinition = "TEXT")
@Basic(fetch = FetchType.LAZY)
String htmlBody;
...
}
然后我可以使用以下请求:
List<Department> deps = em.get().createQuery(
"select distinct d " +
"from Department d " +
"order by d.id desc ", Department.class)
.setFirstResult(first)
.setMaxResults(count)
.getResultList();
List<Object[]> tuple = em.get().createQuery(
"select d, substring(d.content.htmlBody, 1,400)" +
"from Department d " +
"left join fetch d.employees" +
"where d in (:deps) order by d.id desc")
.setParameter("deps", deps)
.getResultList();
... //Filter the duplicates due to the fetching
那样,我有2个SQL查询。员工的提取是在少量数据发生的第二次查询中完成的。子字符串在SQL中实现。完美!
答案 1 :(得分:0)
由于我无法发表评论,我想指出一些令我怀疑的事情。
distinct d, substring(d.htmlDescription, 1,400)
返回的对象是什么?你能用单独的查询获取那个String,还是用Java获取那个?