在我的项目中,我使用Groovy和Spring Data JPA' Specification
来构建Hibernate查询。
我无法提供实际查询,但为了说明我的问题,我们说我有建筑实体,每栋楼都有楼层,每层都有房间和Windows。
我尝试模拟的行为类似于本机SQL查询:
SELECT b.*, r.*
FROM building b
INNER JOIN floor f ON b.id = f.building_id
INNER JOIN window w ON f.id = w.floor_id
LEFT OUTER JOIN room r ON f.id = r.floor_id
WHERE w.id = 1;
我有类似下面的规范:
public class MySpec implements Specification<Building> {
@Override
public Predicate toPredicate(final Root<Building> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
final Join floorsJoin = root.join("floors");
final Join windowsJoin = floorsJoin.join("windows");
//I'd like to remove this line
final Fetch floorsFetch = root.fetch("floors"); // <---
floorsFetch.fetch("rooms", JoinType.LEFT);
cb.equal(windowsJoin.get("id"), 1L);
}
}
上面注释的是我的问题。如果我离开它,生成的查询看起来像这样:
SELECT b.*, f2.*, r.*
FROM building b
INNER JOIN floor f ON b.id = f.building_id
INNER JOIN window w ON f.id = w.floor_id
INNER JOIN floor f2 ON b.id = f2.building_id
LEFT OUTER JOIN room r ON f2.id = r.floor_id
WHERE w.id = 1;
(请注意INNER JOIN
的重复floor
和不需要的f2.*
数据
如果我删除它,并使用floorsJoin
代替获取房间,我会收到以下Hibernate错误:
org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list
不需要的f2.*
数据可以,但我无法用floorsJoin
替换上述floorsFetch
,因为我需要加入windows
表格(不提取windows
)且Fetch
类没有.join
方法。
我很难搞清楚如何在仍然生成单个查询的同时完成我需要的工作;当然,我必须遗漏一些简单的东西。
您可以提供的任何想法或建议都会非常感激。
非常感谢, B.J。
答案 0 :(得分:0)
使用JPA Criteria API并不是那么简单。使用Hibernate,您可以简单地将public View onCreateView(...) {
rootView = inflater.inflate(...);
listView = ...;
listView.setOnTouchListner(...
@Override
public boolean onTouch(View v, MotionEvent event) {
return false; // Says that click was not handled here.
}
});
rootView.setOnTouchListner(...
// TODO: Check if click landed outside the ListView
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() != android.R.id.listView) { // Not the list
if (event.getAction() == MotionEvent.ACTION_UP) {
// Up action more reliable than "down"
return true;
}
}
}
);
return rootView;
}
转换为Fetch
我猜,但这对您没那么大帮助。我不确定你在这种情况下如何使用规范,但如果你可以整体编写查询,它可能如下所示
Join