以下是这些课程:
@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()函数中的整个代码使用单个会话/事务,甚至更好地将我的整个请求发生在单个会话/事务中?
答案 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注释添加到存储库界面。