【问题标题】:How do I use hibernate to query for a list of some entity based on its many-to-many property without filtering out items on the many-to-many property?如何使用hibernate根据其多对多属性查询某个实体的列表,而不过滤掉多对多属性上的项目?
【发布时间】:2012-09-10 22:39:23
【问题描述】:

我有一个实体类 FooBar 具有多对多关系

...
<class name="Foo">
    ...
    <set name="bars" table="FooBar" lazy="true" batch-size="100" fetch="select">
        <key column="FooID" />
        <many-to-many column="BarID" class="Bar" />
    </set>
    ...
</class>
...

我正在尝试制作一个搜索屏幕,允许用户搜索附加到特定Bar 的所有Foos。附加到每个Foo 的所有Bars 都应显示在搜索结果中。

所以我尝试了这段代码:

criteria.createAlias("bars", "bar", CriteriaSpecification.LEFT_JOIN);
criteria.add(Restrictions.eq("bar.id", barID));

这过滤了Foo 记录就好了。但它也会过滤 bars 属性。所以我添加了这一行:

criteria.setFetchMode("bars", FetchMode.SELECT)

但这并没有做任何事情。

我在休眠会话的 Bar 上没有任何休眠过滤器。谁能帮帮我?

【问题讨论】:

    标签: hibernate many-to-many criteria


    【解决方案1】:

    当您对集合项有过滤器时,集合不会被初始化,并且稍后会在访问时懒惰地获取。也许 Hibernate 无法匹配 bar 和 barId。试试

    criteria.createAlias("bars", "bar", CriteriaSpecification.LEFT_JOIN);
    criteria.add(Restrictions.eq("bar.id", barID));
    

    【讨论】:

      【解决方案2】:

      Tom,由于您想返回附加到特定 BarFoos,因此您不需要使用左连接。您可以使用内部连接,然后将通过 N+1 个选择获取 Bars(1 个选择以获取过滤后的 Foos,然后每个 Foo 选择一个以获取其 Bars) .

      我的代码与您上面的代码非常相似,我注意到左连接会强制从初始结果集中加载 Bars 集合,而内连接将使用 N+1 选择。我还尝试指定获取模式无效。就我而言,我不能使用内连接,因为我使用需要左连接的过滤器。例如:

      criteria.add(Restrictions.not(Restrictions.ilike("bar.name", "FizzBuzz")));
      

      在这种情况下,应该返回一个没有BarFoo,因为它没有名为“FizzBu​​zz”的Bar,但是使用内连接会消除所有没有Bars 的Foo .如果其他人可以为 Tom 的问题提供仍然使用左连接的替代答案,将不胜感激!

      编辑:我发现了一个 Hibernate 错误报告,其中指出“如果你将它与 createCriteria 结合以添加限制,criteria.setFetchMode 将被忽略”:

      https://hibernate.onjira.com/browse/HHH-3524

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-22
        • 2014-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-27
        相关资源
        最近更新 更多