【问题标题】:Hibernate Lazyloading not working on @Transactional methodHibernate Lazyloading 不适用于@Transactional 方法
【发布时间】:2019-05-10 13:31:24
【问题描述】:

我正面临着如此多的讨论“”

我正在使用 hibernate 开发一个 spring boot 应用程序。

据我所知,如果一个实体的属性被标记为 FetchType.LAZY,需要有一个 Hibernate 会话才能触发相应的查询来带来相关的实体。

以下是从父实体检索实体列表的方法:

@Transactional
public List<Portfolio> getSharedPortfolios(String userName){
    User user = userService.getUserActive(userName);
    List<Portfolio> sharedPortfolios = user.getSharedPortfolios();
    //logger.debug("Number of Shared Portfolios: " + sharedPortfolios.size());  <======
    return sharedPortfolios;
}

getSharedPortfolios 方法正在从控制器调用并获取“org.hibernate.LazyInitializationException”,然后尝试访问此列表(PersistentBag)

作为使用@Transactional 注释注释的getSharedPortfolios 方法,我期待在执行 user.getSharedPortfolios()(sharedPortfolios 是一个惰性获取列表)时,会初始化相应的列表。但并没有发生这种情况。

谁能给我解释一下为什么?为什么如果我取消注释打印该 PersistentBag 大小的日志行,则不会引发异常?

在这种情况下我是否需要使用 EntityManager 显式初始化它?

非常感谢。

【问题讨论】:

    标签: spring hibernate


    【解决方案1】:

    当您调用List&lt;Portfolio&gt; sharedPortfolios = user.getSharedPortfolios(); 时,分配给sharedPortfolios 的值是一个惰性代理。

    如果您只是返回 sharedPortfolios 并在您的 @Transactional 方法之外访问它,您会得到 LazyInitializationException

    另一方面,如果您在@Transactional 方法中访问sharedPortfolios,则会发生初始化,并返回已初始化的数据。

    恕我直言,您所描述的是预期行为。

    有多种方法可以强制获取:

    • 实体图
    • jpql(获取)
    • 条件查询(获取)
    • 手动访问变量(如您的示例所示)

    或者,检查设置 spring.jpa.open-in-view=true

    【讨论】:

      【解决方案2】:

      我不确定这是什么意思

      “正在从控制器调用 getSharedPortfolios 方法”

      所以这可能不是您的情况,但如果您从同一类中的另一个方法调用 getSharedPortfolios 方法,@Transactional 注释将不起作用。

      【讨论】:

        猜你喜欢
        • 2011-01-22
        • 2019-11-18
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-30
        • 2021-05-04
        • 2018-10-28
        相关资源
        最近更新 更多