Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to fix failed to lazily initialize a collection

When i try to get data from db about user, i get the following error:

Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed
    to lazily initialize a collection of role: com.hramyko.finalapp.entity.CommonUser.comments, could not initialize
    proxy - no Session

I know that happened bcs my session is closed, but i don’t want to use eager fetch. What methods are there to solve my problem? I read the solution to my problem on stackoverflow, but it does not help me.

My CommonUser class:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

package com.hramyko.finalapp.entity;

import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Entity
@Table(name = "common_users")
public class CommonUser extends User {

@OneToMany(mappedBy = "author")
private List<Comment> comments;

public CommonUser() {
}

public CommonUser(User user) {
    super(user.getEmail(), user.getPassword(), user.getFirstName(), user.getLastName(),
            user.getCreatedAt(), user.getRole(), user.getStatus());
    this.id = user.getId();
}

public CommonUser(String email, String password, String firstName,
              String lastName, Date createdAt, Role role, Status status, List<Comment> comments) {
    super(email, password, firstName, lastName, createdAt, role, status);
    this.comments = comments;
}

public List<Comment> getComments() {
    return comments;
}

public void setComments(List<Comment> comments) {
    this.comments = comments;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    if (!super.equals(o)) return false;
    CommonUser that = (CommonUser) o;
    return Objects.equals(comments, that.comments);
}

@Override
public int hashCode() {
    return Objects.hash(super.hashCode(), comments);
}

@Override
public String toString() {
    return "CommonUser{" +
            "id=" + id +
            ", email='" + email + '\'' +
            ", firstName='" + firstName + '\'' +
            ", lastName='" + lastName + '\'' +
            ", comments=" + comments +
            ", createdAt=" + createdAt +
            ", role=" + role +
            '}';
}

}

Service:

@Transactional
@Override
public User currentUser() {
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    String username;
    if (principal instanceof UserDetails) {
        username = ((UserDetails) principal).getUsername();
    } else {
        username = principal.toString();
    }
    return userRepository.findUserByEmail(username);
}

@Transactional
@Override
public User findUserByEmail(String email) {
    userValidator.validateEmail(email);
    return userRepository.findUserByEmail(email);
}

Controller:

@PreAuthorize("hasAnyAuthority('user.read', 'user.write', 'user.delete')")
@GetMapping("my_account")
public String show() {
    return userService.currentUser().toString();
}

>Solution :

It is because you are accessing comments in User ‘s toString() but the comments are not initialised yet and the transaction that load the user is already closed .

Typically two ways to solve it :

  1. Use fetch join to also fetch the comments when loading this user

  2. Increase the transaction boundary to cover the controller ‘s show() method such that when you access user.toString() in it , the transaction that load the user is still active and not closed yet :

@Transactional
public String show() {
    return userService.currentUser().toString();
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading