2011-01-31 5 views
1

こんにちは私は以前のSQLベースのクエリフレームワークをHibernate Criteriaベースに移行しようとしていますが、現在私はHibernateバージョン3.2を使用しています。 and mysql v 5.0.54hibernateの条件contains/containsは要素のセットに制限を含んでいません

私の質問が含まれていないすべてのBeanを返す条件を記述したいのですが、に含まれる要素の値に値があります。

豆のHibernate設定ファイルの概要は次のとおりです。私はが持っていないすべてのエージェントを取得したいと思います

public class Agent { 
    ... 
    public Set<Option> getAgentOptions() { 
     return agentOptions; 
    } 
    public void setAgentOptions(Set<Option> _agentOptions) { 
     this.agentOptions = _agentOptions; 
    } 

    public enum Option { 
     WEB_SITE_SYNDICATE ("web-site-syndicate"), 
     RECEIVE_PREMIUM_ENQUIRIES ("receive-premium-enquiries"), 
     DO_NOT_SYNDICATE_ADS_TO_THIRD_PARTIES ("do-not-syndicate-ads-to-third-parties") 
    } 
} 

<hibernate-mapping package="com.mydomain.beans"> 

     <typedef class="com.mydomain.dao.util.HibernateAgentOptionType" name="agent-option"/> 

     <class name="Agent" table="agent"> 
      ... 
      <set name="agentOptions" table="agent_options" fetch="join" lazy="true"> 
       <key column="agt_id"/> 
       <element column="identifier" type="agent-option"/> 
      </set> 
     </class> 
    </hibernate-mapping> 

クラスファイルは次のようです agentOptionsのオプション "DO_NOT_SYNDICATE_ADS_TO_THIRD_PARTIES"

この前に使用していたSQLずるいのようなものだった:

... 
    crit.createAlias("agentOptions", "agentOption"); 
    crit.add(Restrictions.not(Restrictions.in("agentOption", options))); 
    ... 

:私も、このエイリアスを使用して試したの悪いSQLを吐き出す

... 
    Criteria crit = getHibernateSession().createCriteria(Agent.class); 
    crit.addRestriction(Restriction.not(Restriction.in("agentOptions", noSyndicatedAds))); 
    ... 

SELECT agt.id 
FROM agent agt 
WHERE agt.id NOT IN (
    SELECT sub_agt.id FROM agent sub_agt 
    JOIN agent_options AS agt_options ON agt_options.agt_id = sub_agt.id 
    WHERE agt_options.identifier = 'do_not_syndicate_ads_to_third_parties' 
) 

私はこれを試してみました例外をスローする:

org.hibernate.MappingException:コレクションは関連ありませんでした:

... 
    crit.add(Restrictions.sqlRestriction(" {alias}.id not in " + 
       "(select agt_sub.id " + 
       "from agent agt_sub " + 
       "join agent_options as agent_options_sub on agent_options_sub.agt_id = agt_sub.id " + 
       "where agent_options_sub.identifier in (?)) ", 
       Agent.Option.DO_NOT_SYNDICATE_ADS_TO_THIRD_PARTIES.getIdentifier(), 
       new org.hibernate.type.StringType() 
     )); 
    ... 

働いたが、少し醜いようだ:Agent.agentOptions

は、最後に私は、ブルートSQL基準をしようとすることを決めました。

SQLに頼らずにstd Criteria APIを使用する方法があるかどうかは知りません。

ご迷惑をおかけして申し訳ございません。より新しいバージョンのHibernateにアップグレードする必要がある場合でも。

乾杯 サイモン

+0

私はまた知りたいです。私は "記述"フィールドを持つ子のセットを持つ親エンティティを持っています。子どもの説明が(ilikeのようなものを使って)いくつかの検索テキストと一致するすべての親を戻すDAO関数を作成しようとしています。私はそれを "働く"ことができましたが、マッピングによって追加されます。私は実際にはすでに発生している結合に制限を加えたいだけだと思います。 – spaaarky21

答えて

0

構造は、あなたのDetachedCriteriaとしてサブクエリ、その後はあなたのネストされたRestrictionsNOT IN達成するために使用します。あなたの場合:

DetachedCriteria subquery = DetachedCriteria.forClass(Agent.class); 
subquery.createAlias("agentOptions", "agentOption"); 
subbquery.add(Restrictions.eq("identifier", Agent.Option.DO_NOT_SYNDICATE_ADS_TO_THIRD_PARTIES.getIdentifier()); 
subquery.setProjection(Projections.property("agt_id")); // only return one field 
crit.add(Restrictions.not(Restrictions.in("agt_id", subquery))); 
関連する問題