Play Framwork + Spring JPA Data: LazyInitializationException
These are the following classes:
@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);
}
And in the Controller file I have the following file
@Transactional
public Result getQuestion() {
List<Choices> list = this.questionRepository.findByName("name").choices;
list.size();
return ok();
}
list.size () in getQuestion () throws me a LazyInitializationException because there are no open sessions
I know that changing the fetch type to EAGER or using a JPQL query over the function definition in QuestionRepositor might solve the problem, but there is a part in my application where they won't help and I need lazy fetching.
How would I make all the code in the getQuestion () function a single session / transaction, or even better so that my entire request takes place in one session / transaction? I've been stuck with this for months, please help.
source to share
From Spring Data JPA Reference Documentation
4.7.1. Transactional Query Methods
To enable your transactions to process transactions, simply use
@Transactional
in the repository interface you define.Example 100. Using @Transactional in request 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(); }
Usually, you want the flag to be
readOnly
set totrue
, as most of the request methods will only read data. In contrast, itdeleteInactiveUsers()
uses annotation@Modifying
and overrides the transaction configuration. Thus, the method will be executed with the flagreadOnly
set tofalse
.
So, just add @Transactional annotation to your repository interfaces.
source to share