Play Framework + Spring Data JPA:LazyInitializationException

时间:2014-12-14 11:10:42

标签: spring jpa playframework spring-data

以下是这些课程:

@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);
}

在Controller文件中,我有以下文件

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

list.size()会抛出一个LazyInitializationException,因为没有打开的会话

我知道将获取类型更改为EAGER或在QuestionRepository中使用函数定义上方的JPQL查询可能会解决它,但我的应用程序中有一部分不会有帮助,我会要求延迟获取。

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

1 个答案:

答案 0 :(得分:2)

来自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注释添加到存储库界面。