AbrahamDaniel
AbrahamDaniel

Reputation: 569

Play Framework + Spring Data JPA : 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 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

Answers (1)

mavarazy
mavarazy

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 to true as most of the query methods will only read data. In contrast to that deleteInactiveUsers() makes use of the @Modifying annotation and overrides the transaction configuration. Thus the method will be executed with readOnly flag set to false.

So just add @Transactional annotation to your repository interfaces.

Upvotes: 2

Related Questions