休眠条件:在没有映射关联的情况下加入表

Posted

技术标签:

【中文标题】休眠条件:在没有映射关联的情况下加入表【英文标题】:Hibernate criteria: Joining table without a mapped association 【发布时间】:2010-10-17 18:09:28 【问题描述】:

我想使用 Hibernate 的标准 api 来制定连接两个实体的特定查询。假设我有两个实体,宠物和所有者,所有者有很多宠物,但至关重要的是,该关联没有映射到 Java 注释或 xml 中。

使用 hql,我可以通过在查询中指定联接(而不是将一组宠物添加到所有者类)来选择拥有名为“fido”的宠物的所有者。

可以使用休眠条件来完成相同的操作吗?如果有怎么办?

谢谢, J

【问题讨论】:

【参考方案1】:

我的理解是,如果您使用 HQL 执行此操作,您将创建一个带有过滤器的笛卡尔连接,而不是内部连接。条件查询不支持这样做。

【讨论】:

大卫在这点上是正确的,你不能用标准来做到这一点,你可以用 HSQL 做到这一点 有谁知道是否仍然无法使用条件查询来加入未映射的实体? 我认为可以使用 HQL with 子句 @Suganthan 不,这是不可能的,只是在工作中测试过,因为我们遇到了类似的问题。 @DavidM 投赞成票,因为这是明确和正确的,因为我真的不明白为什么投反对票!【参考方案2】:

有一个SQLCriterion,你可以给它任意的SQL,并添加到你的Criteria。在SQL 字符串中,令牌 alias “将被根实体的别名替换。”

【讨论】:

怎么做?有什么例子吗? 未提供示例或(至少)链接。 SQLCriterion 具有受保护的构造函数【参考方案3】:

在 NHibernate 中,您可以使用定义为 DetachedCriteria 的子查询。不确定它在 Java 中是否同样有效,很可能是相同的:

DetachedCriteria pets = DetachedCriteria.For<Pet>("pet")
  .SetProjection(Projections.Property("pet.ownername"))
  .Add(/* some filters */ );

session.CreateCriteria(typeof(Owner))
  .Add(Subqueries.PropertyIn("name", pets);

假设它是使用所有者的名字加入的。

【讨论】:

【参考方案4】:

这确实可以通过标准来实现:

DetachedCriteria ownerCriteria = DetachedCriteria.forClass(Owner.class);
ownerCriteria.setProjection(Property.forName("id"));
ownerCriteria.add(Restrictions.eq("ownername", "bob"));

Criteria criteria = getSession().createCriteria(Pet.class);
criteria.add(Property.forName("ownerId").in(ownerCriteria));

更新:这实际上执行子查询而不是连接,但它允许您在两个没有定义休眠关系的实体上使用 Criteria。

【讨论】:

为什么有这么多赞成票?还是两个不同的标准吧? 问题是这不是连接,而是子查询 - 这意味着您不能按第一个条件的列对结果进行排序。 我猜它变成了子查询而不是连接 我必须在表和视图之间进行查询,并且没有显式关联。这工作得很好。 我如何检索结果?我可以将它作为 List> 吗?【参考方案5】:
Criterion ownerCriterion = Restrictions.sqlRestriction(SELECT ownerId FROM   Owner WHERE ownerName ='bob');
Criteria criteria = getSession().createCriteria(Pet.class);
criteria.createCriteria("ownerId").add(ownerCriterion);

【讨论】:

以上是关于休眠条件:在没有映射关联的情况下加入表的主要内容,如果未能解决你的问题,请参考以下文章

如何使用休眠条件运行函数?

Hibernate创建没有关系表的关系

在一对多映射中使用休眠条件(以行表列作为搜索条件之一的搜索标题表)

如何在没有连接的情况下在自关联中使用条件?

为啥要在hibernate中使用关联?

如何在第三个表中没有公共列的情况下连接三个表?