【问题标题】:Hibernate many-to-many collection filteringHibernate 多对多集合过滤
【发布时间】:2011-01-20 21:48:12
【问题描述】:

我有以下 POJO,里面有一个 Set:

class Word {
    private Long id;
    private String word;
    private int type = WordListFactory.TYPE_DEFAULT;

    private Set<Word> refs = new HashSet<Word>();
...
}

这是映射 XML:

  <class name="kw.word.Word" table="word">
        <id name="id" column="id"  unsaved-value="null">
            <generator class="native"/>
        </id>

        <property name="word"
                  unique="true"
                  not-null="true"/>
        <property name="type"/>

        <set name="refs"
             table="word_key"
             cascade="save-update">

            <key column="word_id"/>
            <many-to-many class="kw.word.Word" 
                   column="word_ref_id"
                   fetch="join">                         
            </many-to-many>                            
        </set>


    </class>

有两个表:wordword_key。后者将 word-parents 链接到 word-children。

我正在尝试在从数据库中获取数据时实现设置项过滤。生成的对象集必须仅包含具有特定类型的项目。

我尝试了各种方法:

  • 在映射中使用过滤(抱歉,缺少括号)
    
      many-to-many class="kw.word.Word"
                  column="word_ref_id"
                  fetch="join">
         filter name="word_type" condition="type=:type"          
     many-to-many

在获取数据的代码中,我启用了过滤器并设置了参数。根据日志,hibernate 似乎忽略了这个特定的过滤器,因为它在生成的 SQL 查询中没有条件。

  • 在标准中使用附加条件

      Word result = null;
    
    session.beginTransaction();
    
    Criteria crit = session.createCriteria(Word.class);       
    
    crit.add(Restrictions.like("word", key))
         .createAlias("refs", "r")
         .add(Restrictions.eq("r.type", getType()));//added alias and restriction for type
    
     List list = crit.list();
    
     if(!list.isEmpty())
         result = list.get(0);   
    
     session.getTransaction().commit();

现在生成的 SQL 似乎没问题

   select
        this_.id as id0_1_,
        this_.word as word0_1_,
        this_.type as type0_1_,
        refs3_.word_id as word1_,
        r1_.id as word2_,
        r1_.id as id0_0_,
        r1_.word as word0_0_,
        r1_.type as type0_0_ 
    from
        word this_ 
    inner join
        word_key refs3_ 
            on this_.id=refs3_.word_id 
    inner join
        word r1_ 
            on refs3_.word_ref_id=r1_.id 
    where
        this_.word like ? 
        and r1_.type=?

但是在这个查询之后还有另一个获取所有项目

 select
        refs0_.word_id as word1_1_,
        refs0_.word_ref_id as word2_1_,
        word1_.id as id0_0_,
        word1_.word as word0_0_,
        word1_.type as type0_0_ 
    from
        word_key refs0_ 
    left outer join
        word word1_ 
            on refs0_.word_ref_id=word1_.id 
    where
        refs0_.word_id=?

也许我做错了什么?

【问题讨论】:

    标签: java hibernate filter many-to-many


    【解决方案1】:

    从你给定的代码 sn-p 几点来看:

    • 如果是多对多关系,则需要 3 个表、两个实体表和一个连接表。但是由于您拥有相同的实体 -Word ,我认为给定的表结构和映射似乎很好。
    • 尝试使用 HQL 并指定“LEFT JOIN FETCH”来指定您需要在初始 sql SELECT 中检索哪些关联。

    查看此链接与多对多关系相关,但他们使用条件查询。

    Querying ManyToMany relationship with Hibernate Criteria

    【讨论】:

    • 所以 HQL join like session.createQuery("from Word as w join fetch w.refs as r where w.word like :ww and r.type=:tt") .setString("ww" , 键) .setInteger("tt", getType()).uniqueResult();确实有帮助。为什么限制和过滤器没有正确完成它们的工作仍然是一个谜。无论如何,谢谢你的提示。
    猜你喜欢
    • 2011-08-21
    • 2015-12-30
    • 1970-01-01
    • 2012-09-26
    • 2018-07-22
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多