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.

+3


source to share


1 answer


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 to true

, as most of the request methods will only read data. In contrast, it deleteInactiveUsers()

uses annotation @Modifying

and overrides the transaction configuration. Thus, the method will be executed with the flag readOnly

set to false

.



So, just add @Transactional annotation to your repository interfaces.

+2


source







All Articles