考虑类Operation
及其3个子类:
class Operation {}
class OpA extends Operation { }
class OpB extends Operation { Account account; }
class OpC extends Operation { Account account; }
只有OpB
和OpC
有一个名为account
的字段。
我想查询account
属性:
session.createCriteria(Operation.class)
.add(Restrictions.eq("account", account))
.list();
这很有效。 Hibernate忽略了Operation
和OpA
都没有名为account
的字段的事实,并返回
OpB
和OpC
的正确结果。
但是,现在我还要查询帐户所有者,并按顺序排序。然后,我为_account
创建了别名account
:
session.createCriteria(Operation.class)
.add(Restrictions.eq("account", account))
.createAlias("account", "_account")
.add(Restrictions.eq("_account.owner", "John"))
.addOrder(Order.asc("_account.owner"))
.list();
这失败了。该帐户有2个单独的表格(来自OpB
和OpC
),因此Hibernate抱怨:
Not unique table/alias: 'account1_'
我的问题:如何以最简单的方式仅使用Criteria
(无SQL,HQL)查询帐户和帐户所有者?
答案 0 :(得分:3)
这是我的解决方案。它仅适用于部分:
Criterion subQ1 = Subqueries.propertyIn("id",
DetachedCriteria.forClass(OpB.class)
.add(Restrictions.eq("account", account))
.createAlias("account", "_account")
.add(Restrictions.eq("_account.owner", "John"))
.setProjection(Projections.groupProperty("id")));
Criterion subQ2 = Subqueries.propertyIn("id",
DetachedCriteria.forClass(OpC.class)
.add(Restrictions.eq("account", account))
.createAlias("account", "_account")
.add(Restrictions.eq("_account.owner", "John"))
.setProjection(Projections.groupProperty("id")));
session.createCriteria(Operacao.class)
.add(Restrictions.disjunction()
.add(subQ1)
.add(subQ2))
.list();
只要我不添加订单,它就会起作用:.addOrder(Order.asc("_account.owner"))
。
订单无法添加到Subqueries
,因为它无效。
它无法添加到Criteria
,因为它不接受别名。
也许有一种方法可以调整这个,或者这个解决方案太复杂了,而且更简单?
答案 1 :(得分:3)
以下两种解决方案无效。两者都会产生Not unique table/alias: 'account1_'
。
我在这里张贴他们来记录什么是行不通的,或者可能是为了给其他人提供想法,而不会使问题本身复杂化:
session.createCriteria(Operation.class)
.createAlias("account", "_account")
.add(
Restrictions.and(
Restrictions.or(
Property.forName("class").eq(OpB.class),
Property.forName("class").eq(OpC.class)),
Restrictions.eq("account", account)
Restrictions.eq("_account.owner", "John"))
)
)
.list();
没有别名:
session.createCriteria(Operacao.class)
.add(Restrictions.eq("account", account))
.createCriteria("account")
.add(Restrictions.eq("owner", "John"))
.list();
答案 2 :(得分:1)
尝试将AccountOperation
抽象类添加为:
public abstract class AccountOperation extends Operation {
public abstract Account getAccount();
}
现在,OpB
和OpC
都会延长AccountOperation
。
您的查询将变为:
Criteria c = session.createCriteria(AccountOperation.class, "op")
.createAlias("op.account", "ac")
.add(Restrictions.eq("ac", account))
.addOrder(Order.asc("ac.owner"))
.list();