【问题标题】:how to override hibernate fetching strategy at runtime如何在运行时覆盖休眠获取策略
【发布时间】:2011-07-23 01:27:38
【问题描述】:

我在“hibernate in action”一书中看到了以下陈述。任何人都可以告诉我如何在运行时覆盖策略。你可以采取相反的方式,即我将延迟获取策略设置为 false,而我想将其设置为 true?

“延迟获取让您决定首先加载多少对象图 数据库命中以及哪些关联只应在首次加载时加载 访问。延迟获取是对象持久性和 达到可接受性能的第一步。 我们建议,首先,将所有关联配置为惰性(或者也许 批量延迟)在映射文件中获取。 然后可能会覆盖此策略 在运行时通过强制进行急切获取的查询。”

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    如果您使用 HQL 进行查询,您可以使用“fetch”关键字指定您的渴望获取,如下所示:

    from Cat as cat
        inner join fetch cat.mate
        left join fetch cat.kittens child
        left join fetch child.kittens
    

    如果您使用 Criteria Query API,您可以使用 setFetchMode 指定获取模式

    List cats = sess.createCriteria(Cat.class)
        .add( Restrictions.like("name", "Fritz%") )
        .setFetchMode("mate", FetchMode.EAGER)
        .setFetchMode("kittens", FetchMode.EAGER)
        .list();
    

    【讨论】:

    • Hibernate 似乎对添加“左连接提取”不满意,除非在使用 JPA2 标准时目标实体出现在选择列表中。如果添加 root.fetch("someChildProperty") 以请求左连接提取,则会产生错误“查询指定的连接提取,但提取的关联的所有者不在选择列表中”。想法? JPA2 似乎很难说“大部分时间都懒惰地获取这个,但在这种情况下急切地获取”。
    • 非常感谢!非常感谢,安德鲁!
    【解决方案2】:

    【讨论】:

    • 看来您可以使用 fetch 配置文件来用“join”覆盖“select”,但反之则不行。
    【解决方案3】:

    对于 eager 查询,您可以使用 LINQ 提供程序编写如下内容:

    List<Customer> customers = session.Query<Customer>().Fetch(c => c.Orders).ToList();
    

    这会在一个 SQL 查询中为所有获取的客户填写所有订单:

    select
        customer0_.CustomerId   as CustomerId0_0_,
        customer0_.ContactName  as ContactN3_0_0_,
        orders1_.CustomerId     as CustomerId0__,
        orders1_.OrderId        as OrderId0__
        orders1_.OrderDate      as OrderDate3_1_,
    from   Customers customer0_
       left outer join Orders orders1_
         on customer0_.CustomerId = orders1_.CustomerId
    

    您也可以获取孙子集合(请参阅here)。

    【讨论】:

    • 这是关于 Java,而不是 C#
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 2011-03-14
    • 1970-01-01
    相关资源
    最近更新 更多