5

Betrachten wir die Klasse Operation, und seine drei Unterklassen:Alias ​​für Eigenschaften, die nur in Unterklassen (Hibernate Criteria) existieren

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

Nur OpB und OpC ein Feld account genannt haben.

Ich möchte für die account Eigenschaft abfragen:

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

Dies funktioniert. Hibernate ignoriert die Tatsache, dass sowohl Operation als auch OpA kein Feld mit der Bezeichnung account haben, und gibt die korrekten Ergebnisse für OpB und OpC zurück.

Allerdings möchte ich jetzt auch für den Kontoinhaber abfragen und damit bestellen. Ich erstelle dann den Alias ​​_account für 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(); 

Dies schlägt fehl. Es gibt zwei getrennte Tabellen für das Konto (von OpB und OpC), so Hibernate klagt:

Not unique table/alias: 'account1_' 

Meine Frage: Wie kann ich beide Abfrage für das Konto und den Kontoinhaber mit nur Criteria (keine SQL, HQL) auf die einfachste Weise?

+0

Was wäre die gewünschte SQL aussehen? –

+0

@Pedrag: Sorry, ich habe keine Ahnung. – MarcG

Antwort

3

Das ist meine Lösung. Es funktioniert nur teilweise:

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

Es funktioniert, solange ich nicht hinzufügen Bestellung: .addOrder(Order.asc("_account.owner")).

Die Reihenfolge kann nicht zum Subqueries hinzugefügt werden, weil es keinen Effekt haben würde. Und es kann nicht hinzugefügt werden, Criteria, weil es den Alias ​​nicht akzeptiert.

Vielleicht gibt es eine Möglichkeit, dies zu optimieren, oder vielleicht ist diese Lösung zu kompliziert und es gibt eine einfachere?

3

Die beiden folgenden Lösungen funktionieren nicht. Beide ergeben Not unique table/alias: 'account1_'.

Ich veröffentliche sie hier zu dokumentieren, was nicht funktioniert, oder vielleicht Ideen zu geben jemand anderes, ohne die Frage verkomplizieren sich:

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

Ohne Alias:

session.createCriteria(Operacao.class) 
     .add(Restrictions.eq("account", account)) 
     .createCriteria("account") 
     .add(Restrictions.eq("owner", "John")) 
     .list(); 
1

Try

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

Nun sind beide: eine AccountOperation abstrakte Klasse als hinzufügenund OpC wird AccountOperation verlängern.

Ihre Anfrage wird werden:

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

Ja, mein Beispiel ist redundant, aber es ist nur ein Beispiel. Mein Problem ist die 'Nicht eindeutige Tabelle/alias: 'account1_'' Ausnahme. – MarcG

+0

Tut mir leid Vlad, ich war nicht im Büro und konnte es vorher nicht testen. Nun, Ihr Beispiel gibt mir diese Ausnahme: 'Nicht eindeutige Tabelle/Alias: 'ac1_''. – MarcG

+0

Mit der IN-Direktive bekomme ich 'java.lang.Class kann nicht in java.lang.Integer' bei' org.hibernate.type.descriptor.java.IntegerTypeDescriptor.unwrap' umgewandelt werden. – MarcG

Verwandte Themen