因此,我尝试使用Hibernate Criteria API进行相当复杂的查询。我有以下实体类:
代码
礼品
GiftVendor
GiftVendorStatus
具有以下关系:
代码1<> 1礼品
礼品1<> * GiftVendor
GiftVendor 1<> 1 GiftVendorStatus
我需要构建一个Criteria查询,该查询返回一个Code对象列表,但这仅限于具有Gift的至少具有GiftVendorStatus Online的GiftVendor的代码。以下是我用来构建标准的代码:
Criteria base = CodeDao.getBaseCriteria();
base.createAlias("gift","gift");
base.createAlias("gift.giftVendor","giftVendor");
base.createAlias("giftVendor.giftVendorStatus","giftVendorStatus");
base.add(Restrictions.like("giftVendorStatus.description", "Online%"));
return base.list();
这给了我一个Code对象列表,受到我预期的限制。但是,它还会执行其他查询来构建Gift对象的所有未使用的关系,即使我已经使用Lazy的获取模式设置了所有映射。这导致我的10000多个结果中的每一个都有4个额外的单独查询。
我有使用可以按预期工作的HQL进行查询的代码:
String hql = "select c FROM Code c inner join c.gift g inner join g.giftVendors gv inner join gv.giftVendorStatus gvs" +
" WHERE gvs.description like :desc";
HashMap<String,Object> params = new HashMap<String, Object>();
params.put("desc", "Online%");
return performQuery(hql, params);
该代码按预期方式为我提供了一个Code对象列表,而没有执行所有额外的查询来填充Gift对象。如何告诉Hibernate不要使用Criteria API进行额外的查询?
更新:这里的问题不是礼品表的检索,而是礼品表中不相关的一对一关系。例如,Gift与GiftCommentAggregateCache具有一对一的关系。此表与此特定查询无关,因此我希望应用延迟初始化规则,并且除非尝试读取,否则不会发生对GiftCommentAggregateCache的查询。但是,使用上面写出的Criteria查询,它会使单独的查询填充GiftCommentAggregateCache的模型对象。
如果我使用:
base.setFetchMode("gift.giftCommentAggregateCache", FetchMode.JOIN);
那时我没有任何问题。但是,这意味着为了使其按照我的预期工作,我需要为Gift所拥有的每一个未使用的一对一关系添加该行。关于为什么映射中指定的惰性规则没有在这里发挥作用的任何想法?
我尝试过几件不同的事情:
base.setFetchMode("gift", FetchMode.LAZY); // Still does additional queries
和
base.setFetchMode("gift", FetchMode.SELECT); // Still does additional queries
和
base.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // Still does additional queries
和
base.setResultTransformer(Criteria.ROOT_ENTITY); // Still does additional queries
和
base.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); // Still does additional queries
和
base.setProjection(Projections.property("gift")); // Does not do additional queries, but incorrectly returns a List of Gift objects, instead of a List of Code objects
答案 0 :(得分:0)
加入提取:Hibernate使用OUTER JOIN在同一个SELECT中检索关联的实例或集合。
换句话说,尝试使用base.setFetchMode(“gift”,FetchMode.JOIN)
我希望有所帮助。
干杯