我有一个项目列表。每个项目都有一组类别。我想抓住特定类别的所有项目。这部分很简单。我遇到问题的部分是让我的查询返回包含所有类别的项目,而不仅仅是我正在过滤的项目。
session.createCriteria(Item.class) .createAlias("categories","category") .add(Restrictions.eq("category.name",categoryFilter))
上面的代码返回该项目,但仅返回我正在过滤的类别。反正有没有说过对这个限制过滤对象,但是返回完整的对象而不是过滤的对象?我也尝试在HQL中用相同的结果编写它。
答案 0 :(得分:3)
看来FetchMode和createAlias之间确实存在一些讨厌的交互,这看起来像是一个bug。
在https://forums.hibernate.org/viewtopic.php?t=944439对此进行了一些讨论,其中一位开发人员强调说这是正确的行为并且不会被修复。
讨论中也包含了潜在的解决方法。
尝试使用嵌套条件而不是别名:
session.createCriteria(Item.class)
.createCriteria("categories")
.add(Restrictions.eq("name",categoryFilter))
随着集合映射为渴望,这似乎对我有用。不确定在外部标准上使用FetchMode的交互。
答案 1 :(得分:0)
这可能与使用别名和限制没什么关系,但只是默认延迟抓取的结果。
在你的Item的映射中,你可能有类别设置为懒惰,这是默认的,通常是一个好主意。
您可以将此映射更改为渴望,但这可能是一个坏主意。
要保留默认的提取延迟,但要急切地检索特定条件,您可以在那里设置提取模式,类似于
session.createCriteria(Item.class)
.setFetchMode("categories", FetchMode.EAGER)
.createAlias("categories","category")
.add(Restrictions.eq("category.name",categoryFilter))
答案 2 :(得分:0)
如果是错误I reported a while ago:我通常的解决方法是只获取匹配项的ID,然后在后续查询中选择包含其类别的项目:
List<Serializable> ids = session.createCriteria(Item.class)
.createAlias("categories","category")
.add(Restrictions.eq("category.name",categoryFilter))
.setProjection(Projections.id())
.list();
List<Items> items = session.createCriteria(Item.class)
.add(Restrictions.in("id", ids)
.createAlias("categories","category")
.list();
答案 3 :(得分:0)
另一个解决方案是使用Exists子查询,以便FetchMode.JOIN也可以工作。 (这使用DetachedCriteria,但Criteria应该类似)
DetachedCriteria criteria = session.createCriteria(Item.class, "i");
criteria.setFetchMode("categories", FetchMode.JOIN);
DetachedCriteria catCriteria = DetachedCriteria.forClass(Category.class, "category");
catCriteria.add(Restrictions.eq("name", categoryFilter));
catCriteria.add(Restrictions.eqProperty("category.id", "i.categoryId"));
criteria.add(Subqueries.exists(catCriteria.setProjection(Projections.property("category.id"))));
希望这对其他人也有帮助,因为文档很难弄明白。我还添加了github gist附加评论