这些是以下类:
@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,因为没有打开的 session
我知道将获取类型更改为 EAGER 或在 QuestionRepository 中的函数定义上方使用 JPQL 查询可能会解决此问题,但我的应用程序中的某些部分无济于事,我需要延迟获取。
如何使 getQuestion() 函数中的整个代码使用单个 session /事务,甚至更好地使我的整个请求发生在单个 session /事务中?
最佳答案
来自 Spring Data JPA reference documentation
4.7.1. Transactional query methods
To allow your query methods to be transactional simply use
@Transactional
at the repository interface you define.Example 100. Using @Transactional at query methods
@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(); }
Typically you will want the
readOnly
flag set totrue
as most of the query methods will only read data. In contrast to thatdeleteInactiveUsers()
makes use of the@Modifying
annotation and overrides the transaction configuration. Thus the method will be executed withreadOnly
flag set tofalse
.
因此只需将@Transactional 注释添加到您的存储库接口(interface)即可。
关于spring - Play Framework + Spring Data JPA : LazyInitializationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27468713/