【问题标题】:Alias for properties that exist only in subclasses (Hibernate Criteria)仅存在于子类中的属性的别名(Hibernate Criteria)
【发布时间】:2015-03-14 13:29:19
【问题描述】:

考虑 Operation 类及其 3 个子类:

 class Operation {}
 class OpA extends Operation { }
 class OpB extends Operation { Account account; }
 class OpC extends Operation { Account account; }

只有OpBOpC 有一个名为account 的字段。

我要查询account 属性:

session.createCriteria(Operation.class)
       .add(Restrictions.eq("account", account))
       .list();

这行得通。 Hibernate 忽略了 OperationOpA 都没有名为 account 的字段这一事实,并返回 OpBOpC 的正确结果。

但是,现在我还想查询帐户所有者,并按其排序。然后我为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 个单独的表(来自 OpBOpC),因此 Hibernate 抱怨:

Not unique table/alias: 'account1_'

我的问题:如何以最简单的方式仅使用Criteria(无 SQL,HQL)同时查询帐户和帐户所有者?

【问题讨论】:

  • 所需的 SQL 是什么样的?
  • @Pedrag:对不起,我不知道。

标签: java hibernate subquery hibernate-criteria detachedcriteria


【解决方案1】:

这是我的解决方案。它只能部分工作:

 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,因为它不接受别名。

也许有办法对此进行调整,或者这个解决方案太复杂而有更简单的解决方案?

【讨论】:

    【解决方案2】:

    以下两种解决方案均无效。两者都导致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();
    

    【讨论】:

      【解决方案3】:

      尝试添加一个AccountOperation抽象类为:

      public abstract class AccountOperation extends Operation {
          public abstract Account getAccount();    
      }
      

      现在OpBOpC 都将扩展AccountOperation

      您的查询将变为:

      Criteria c = session.createCriteria(AccountOperation.class, "op")
          .createAlias("op.account", "ac")
          .add(Restrictions.eq("ac", account))
          .addOrder(Order.asc("ac.owner"))
          .list();
      

      【讨论】:

      • 是的,我的例子是多余的,但这只是一个例子。我的问题是Not unique table/alias: 'account1_' 异常。
      • 对不起,弗拉德,我不在办公室,之前无法测试它。好吧,你的例子给了我这个例外:Not unique table/alias: 'ac1_'.
      • 使用 IN 指令,我在 org.hibernate.type.descriptor.java.IntegerTypeDescriptor.unwrap 得到 java.lang.Class cannot be cast to java.lang.Integer
      • 弗拉德,由于某种原因,类被赋予了编号,所以像Restrictions.in("op.class", new Integer[]{1,2}) 这样的东西会找到它们(相应的编号每次都会改变)。但即使它只选择包含account 的类,也会发生同样的Not unique table/alias: 'ac1_' 异常。
      • 我实际上无法创建新界面。我需要的子类只在运行时才知道。感谢您的帮助。
      猜你喜欢
      • 2017-04-14
      • 1970-01-01
      • 2012-01-29
      • 2018-03-02
      • 2023-03-28
      • 2017-03-15
      • 2013-08-25
      • 2011-10-17
      • 1970-01-01
      相关资源
      最近更新 更多