2012-01-03 12 views
1

私は2つの単純なmapingsありますのHibernateのcreateCriteriaとの関連やcreateAlias

<class name="org.testing.Person" table="PERSON"> 
     <id name="personId" type="long" column="PERSON_ID"> 
      <generator class="native"/> 
     </id> 
     <property name="personName" type="string" not-null="true" column="PERSON_NAME"/> 
     <many-to-one name="personAddress" class="org.testing.Address" column="PERSON_ADDRESS" not-null="true" cascade="all" unique="true"/> 
</class> 

<class name="org.testing.Address" table="ADDRESS"> 
    <id name="addressId" type="long" column="ADDRESS_ID"> 
     <generator class="native" /> 
    </id> 
    <property name="street" column="ADDRESS_STREET" type="string" /> 
    <property name="city" column="ADDRESS_CITY" type="string" /> 
    <property name="state" column="ADDRESS_STATE" type="string" /> 
</class> 

は、私はこのような人のアドレスのプロパティを取得しよう:

session.createCriteria(Person.class) 
        .add(Restrictions.eq("personName", "Frodo")) 
        .createAlias("personAddress", "pa") 
        .setProjection(Projections.property("pa.street")) 
        .list(); 

とできます。このようなより :

session.createCriteria(Person.class) 
        .add(Restrictions.eq("personName", "Frodo")) 
        .createCriteria("personAddress") 
        .setProjection(Projections.property("street")) 
        .list(); 

は、それがスロー:org.hibernate.QueryException: could not resolve property: street of: org.testing.Person。私は両方とも同じ結果を与えるべきだと思います。どこが間違っていますか? ありがとうございます!

+0

なぜ2番目のクエリで** createCriteria( "personAddress")**を使用していますか? – ManuPK

+0

** Person **クラスに** personAddress **という名前のプロパティがあり、** Address **クラスへの関連の一端です – catdog

答えて

9

.setProjection(Projections.property("street"))は常にルート基準で動作します。結合されたアイテムをプロジェクトするには、投稿した最初のバージョンを使用する必要があります。

9

休止状態3.3.2;

私たちは、コードのソースを見てみましょう:

public Criteria createAlias(String associationPath, String alias, int joinType) { 
    new Subcriteria(this, associationPath, alias, joinType); 
    return this; 
} 


public Criteria createCriteria(String associationPath, int joinType) { 
    return new Subcriteria(this, associationPath, joinType); 
} 

のcreateCriteriaは、サブ基準を返すので、すべての操作は、サブ基準です。 ですが、createAliasは副基準を作成する基準を返します。

例1 広告manyToone adgroup;それらのすべては、「名前 『プロパティ

 Criteria criteria1 = s.createCriteria(Ad.class, "ad").add(Restrictions.eq("ad.id", Long.valueOf(343909))) ; 
    Criteria criteria2 = criteria1.createCriteria("adGroup") 
        .setProjection(Projections.property("name")) 
     List list = criteria2.list(); 


    List list = s.createCriteria(Ad.class, "ad").add(Restrictions.eq("ad.id", Long.valueOf(343909))) 
        .createAlias("adGroup", "adGroup") 
        .setProjection(Projections.property("name")) 
        .list(); 

を持っている広告の名前は最初の文で「BBBB」 で、結果の「名前」の値は、広告グループのエンティティからである 私たちは広告グループの名前が』 AAAA」であるとしましょう= "aaaa"第2ステートメントの は、結果の「名前」値は広告エンティティ「bbbb」からのものです。

ps1:広告グループエンティティではなく、広告エンティティ内に「名前」のプロパティがない場合、最初のステートメントは例外をスローします:org.hibernate.QueryException:プロパティ:name:AdGroup; しかし、uは「.setProjection(Projections.property(」ad.name「))」に変更した場合、それは

PS2広告の名前の値を返す罰金になります:、criteria2で)最初の文のコールリスト(ただし、 hibernateはルートcriteria = criteria1から処理します。最終的なSQLはcriteria1から "where ad.id = 343909"を含みます。

例2

enter image description here

教師oneToMany学生 学生oneToMany学生

List list1 = s.createCriteria(Teacher.class, "teacher").add(Restrictions.eq("teacher.id", Long.valueOf(343909))) 
        .createCriteria("students").createCriteria("books") 
        .list(); 



List list2 = s.createCriteria(Teacher.class, "teacher").add(Restrictions.eq("teacher.id", Long.valueOf(343909))) 
        .createAlias("students").createCriteria("books").setProjection(Projections.property("name")) 
        .list(); 

2番目のステートメントは、例外がスローされます:org.hibernateを。QueryException:プロパティを解決できませんでした:books of:Teacher;書籍が学生の財産であるため、 は、createCriteriaとcreateAliasの違いです。

関連する問題