5

Рассмотрим класс Operation, и его 3 подкласса:Алиас для свойств, которые существуют только в подклассах (Hibernate Criteria)

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

Что бы желательно SQL выглядеть? –

+0

@Pedrag: Извините, я понятия не имею. – MarcG

ответ

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, потому что он не принимает псевдоним.

Возможно, есть способ настроить это, или, может быть, это решение слишком сложно и есть более простой?

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(); 
1

Try добавить 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(); 
+0

Да, мой пример лишний, но это всего лишь пример. Моя проблема - это «Не уникальная таблица/псевдоним:« account1_ ». – MarcG

+0

Жаль Влада, я был вне офиса и не мог проверить его раньше. Ну, ваш пример дает мне это исключение: 'Не уникальная таблица/псевдоним: 'ac1_''. – MarcG

+0

С директивой IN я получаю 'java.lang.Class нельзя передать в java.lang.Integer' в' org.hibernate.type.descriptor.java.IntegerTypeDescriptor.unwrap'. – MarcG

Смежные вопросы