【问题标题】:Play Framework + Spring Data JPA : LazyInitializationExceptionPlay Framework + Spring Data JPA:LazyInitializationException
【发布时间】:2014-12-14 11:10:42
【问题描述】:

这些是以下类:

@Entity
public class Question {
   @Id
   public Long id;
   public String name;

   @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
   @JoinColumn(name = "OWNER_ID", referencedColumnName = "QUES_ID")
   public List<Choice> choices = new ArrayList<>();
}

@Named
@Singleton
public interface QuestionRepository extends CrudRepository<Question , Long> {
    Question findByName(String name);
}

在控制器文件中我有以下文件

@Transactional
public Result getQuestion() {
    List<Choices> list = this.questionRepository.findByName("name").choices;
    list.size();
    return ok();
}

getQuestion() 中的 list.size() 向我抛出 LazyInitializationException,因为没有打开的会话

我知道将 fetch 类型更改为 EAGER 或在 QuestionRepository 中的函数定义上方使用 JPQL 查询可能会解决这个问题,但在我的应用程序中有些部分没有帮助,我需要延迟 fetch。

如何让 getQuestion() 函数中的整个代码使用单个会话/事务,甚至更好地让我的整个请求在单个会话/事务中进行?

【问题讨论】:

  • 我认为 Spring 无法在 getQuestion 中开始交易,而您只是在使用 Spring Data 的跨链交易。
  • 所有Repository 实现默认都是事务性的。当你调用findByName 时,spring 开始一个事务,当方法返回时,事务提交并且由于你的会话关闭,list.size() 抛出LazyInitializationException。检查播放/弹簧集成..

标签: spring jpa playframework spring-data


【解决方案1】:

来自Spring Data JPA reference documentation

4.7.1。事务查询方法

要让您的查询方法具有事务性,只需在存储库接口使用@Transactional 你定义。

示例 100. 在查询方法中使用 @Transactional

@Transactional(readOnly = true)
public interface UserRepository extends JpaRepository<User, Long> {

    List<User> findByLastname(String lastname);

    @Modifying 
    @Transactional
    @Query("delete from User u where u.active = false")  
    void deleteInactiveUsers();
}

通常您希望将readOnly 标志设置为true,因为大多数查询方法只会读取数据。相比之下,deleteInactiveUsers() 使用 @Modifying 注释并覆盖事务配置。因此,该方法将在 readOnly 标志设置为 false 的情况下执行。

因此,只需将 @Transactional 注释添加到您的存储库接口。

【讨论】:

  • 如前所述,我想要一个没有@Query 的解决方案,该解决方案使会话/事务在 UserRepository 之外可用。
  • 不需要查询,只需在接口中添加Transactional即可。
  • 添加事务性工作,getQuestion 是我的控制器类的成员,而不是存储库接口
  • 检查事务的传播,基本上你希望你在存储库和方法上的事务与 REQUIRED 传播。
  • docs.spring.io/spring/docs/current/spring-framework-reference/… 实际上 REQUIRED 是默认配置。检查您是否在 Spring 配置中启用了事务(@EnableTransactionManagement 或 存在)?在这两个地方都只保留@Transaction。
猜你喜欢
  • 2015-11-25
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多