2010-12-27 4 views
1

Ich stieß auf ein Problem mit Hibernate in Bezug auf die Ausführung von HQL-Abfrage für Klassen, die Vererbung verwenden.Hibernate erben Problem bei der Verwendung von HQL-Anweisung


Modellstruktur

public class Filed { 

private Long id; 
private String name; 

public Long getId() { 
return this.id; 
} 

public void setId(Long id) { 
this.id = id; 
} 

public String getName(){ 
this.name; 
} 

public void setName(String name) { 
this.name = name; 
} 

} 



public class SuperField extend Field { 

private String role; 

public String getRole(){ 
return this.role; 
} 

public void setRole(String role) { 
this.role = role; 
} 

} 

Mapping

<hibernate-mapping> 
<class name="org.stackoveflow.Field" table="FILEDS" schema="STACK"> 
    <id name="id" type="java.lang.Long"> 
    <column name="FILED_ID" precision="22" scale="0" /> 
    <generator class="sequence"> 
    <param name="sequence">STACK.FIELDS_SEQ</param> 
    </generator> 
    </id> 
    <property name="name" type="string" column="NAME"/> 
</class> 
</hibernate-mapping> 

<hibernate-mapping> 
<class name="org.stackoveflow.SuperField" table="SUPER_FILEDS" schema="STACK"> 
    <id name="id" type="java.lang.Long"> 
    <column name="FILED_ID" precision="22" scale="0" /> 
    <generator class="sequence"> 
    <param name="sequence">STACK.SUPER_FIELDS_SEQ</param> 
    </generator> 
    </id> 
    <property name="name" type="string" column="NAME"/> 
    <property name="role" type="string" column="ROLE"/> 
</class> 
</hibernate-mapping> 

Dann haben wir zwei Funktionen.

public Long countFiledByName(String name) { 

    String query = "select count(*) from Filed Field where Field.name = :fieldName"; 

    List<?> list = getHibernateTemplate().findByNamedParam(query, new String[] {fieldName},new Object[] { name}); 

    return (Long) list.get(0); 

} 

public Long countSuperFieldByName(String name) { 

    String query = "select count(*) from SuperFiled SuperField where SuperField.name = :superFieldName"; 

    List<?> list = getHibernateTemplate().findByNamedParam(query, new String[] {"superFieldName"},new Object[] { name}); 

    return (Long) list.get(0); 

} 

Das Problem ist, dass countFiledByName in Funktion Liste zwei Elemente in Folge hat

  • 0 - Zählen von Superfeld
  • 1 - Naturally COUNT von Feld

dies sieht aus wie Hibernate, führen Sie die Anweisung für Klassenhierarchie aus, auch wenn die Zuordnungen nicht verwandt sind.

Weiß jemand, was dieses Verhalten sperren und nur Objekte aus einer Tabelle laden?

PS.

Gleiches Verhalten gilt für Kriterien, aber dann Ergebnis invertiert wird

  • 0 - Graf von Feld
  • 1 - Graf von Superfeld

Antwort

1

Interessante Verhalten.

Die Ursache scheint dies (10.1.6. Table per concrete class using implicit polymorphism) zu sein:

Der Nachteil dieses Ansatzes ist, dass Hibernate nicht SQL UNIONs generiert, wenn polymorphe Abfragen durchführen.

Sieht aus wie Sie dieses Problem, indem swithing explizite table-pre-concrete-class inheritance strategy lösen kann, obwohl ich nicht sicher bin, was mit verschiedenen ID-Generatoren zu tun:

<hibernate-mapping> 
    <class name="org.stackoveflow.Field" table="FILEDS" schema="STACK"> 
     <id name="id" type="java.lang.Long"> 
      <column name="FILED_ID" precision="22" scale="0" /> 
      <generator class="sequence"> 
       <param name="sequence">STACK.FIELDS_SEQ</param> 
      </generator> 
     </id> 
     <property name="name" type="string" column="NAME" /> 
     <union-subclass name = "org.stackoveflow.SuperField" table = "SUPER_FILEDS" schema = "STACK"> 
      <property name="role" type="string" column="ROLE"/> 
     </union-subclass> 
    </class> 
</hibernate-mapping> 
+0

Danke für Antwort, Sie haben wahrscheinlich recht mit, dass Hauptursache, leider ist die Vereinigung pro konkreter Klasse in meinem Fall nicht möglich, da die Klasse, die beispielsweise SuperField in der Tabelle ist, nicht über Feldfeld verfügt, weshalb diese Lösung nicht verwendet wurde. In diesem Fall sollte die Vererbung auf einige Schnittstellen verschoben werden und stattdessen die Klasse in Code verwenden. –