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

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

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

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

谢谢, J

【问题讨论】:

    标签: java hibernate hql criteria


    【解决方案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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-30
        • 2012-03-22
        • 1970-01-01
        • 1970-01-01
        • 2018-01-15
        • 2010-10-28
        • 1970-01-01
        相关资源
        最近更新 更多