Reputation: 569
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 this 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 is not open sessions
I know that changing the fetch type to EAGER or using a JPQL query above the function definition in QuestionRepository might solve it, but there are part in my application where those wont help and I would require to lazy fetch.
How would make the entire code in getQuestion() function use a single session/transaction or even better my entire request to take place in an single session/transaction?
Upvotes: 3
Views: 276
Reputation: 7735
From 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
.
So just add @Transactional annotation to your repository interfaces.
Upvotes: 2