【问题标题】:LazyInitializationException Within a @Transactional Method@Transactional 方法中的 LazyInitializationException
【发布时间】:2012-02-16 19:54:12
【问题描述】:

当我在执行以下操作时尝试访问延迟加载的异常时遇到了org.hibernate.LazyInitializationException 错误:

@Transactional
public void displayAddresses()
{
     Person person = getPersonByID(1234);
     List<Address> addresses = person.getAddresses(); // Exception Thrown Here

     for(Address address : addresses)
          System.out.println(address.getFullAddress());
}

我的实体如下所示:

@Entity
@Table("PERSON_TBL")
public class Person
{
     ...

     @OneToMany(cascade=CascadeType.ALL, targetEntity=Address.class, mappedBy="person")
     private List<Address> addresses;

     ...
}

@Entity
@Table("ADDRESS_TBL")
public class Address
{
     ...

     @ManyToOne(targetEntity=Person.class)
     @JoinColumn(name="PERSON_ID", referencedColumnName="PERSON_ID")
     Person person;

     ...
}

我的印象是,通过在我的 displayAddresses() 方法中使用 @Transactional 注释,它会保持会话活动直到方法完成,从而允许我访问延迟加载的地址集合。

我错过了什么吗?

编辑

按照 Tomasz 的建议:在我的displayAddresses() 方法中,TransactionSynchronizationManager.isActualTransactionActive(), 的状态竟然是false

这确实缩小了问题的范围,但为什么我的交易此时不会处于活动状态?

【问题讨论】:

  • 你能打电话给TransactionSynchronizationManager.isActualTransactionActive()吗?它应该返回true。否则@Transasctional 不起作用。
  • @TomaszNurkiewicz 我根据您的建议编辑了我的原始帖子以包含更多信息。
  • 您的配置中有&lt;tx:annotation-driven/&gt; 吗?您的 displayAddresses() 方法是否在 Spring 管理的 bean 中?您是从外部调用此方法还是从其他事务方法调用此方法?
  • 如何调用 displayAddresses() 方法 - 从同一个 bean 的方法中?

标签: hibernate spring transactional


【解决方案1】:

这已经回答了,但只是想发布一个替代答案,在类似的情况下对我有用 - 为后代;)

在我的情况下,问题是由于包含延迟加载集合的实例已被手动驱逐(都在事务边界内)这一事实引起的。

【讨论】:

  • 在我的情况下不是这样,但它让我开始思考 - 事实证明,有一次实体被缓存(使用 ehcache)而不是 dto - 确保你不是要么这样做
【解决方案2】:

在我的配置文件中包含&lt;tx:annotation-driven /&gt; 并使用我的服务类的 Spring 管理版本(调用 displayAddresses() 方法)就可以了。

【讨论】:

    猜你喜欢
    • 2015-10-03
    • 2017-02-23
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    相关资源
    最近更新 更多