2

I have Rest @GetMapping method :

@GetMapping(value = "/getAdmin",produces = "application/json")
public List<Users> listOfUsers(){
   return userService.findAllUsers();
}

findAllUsers function looks like :

@Override
@Transactional
public List<Users> findAllUsers() {
   String hqlRequest = "from Users U JOIN FETCH U.roles";
   Query query = sessionFactory.getCurrentSession().createQuery(hqlRequest);
}

That is, JOIN FETCH works fine if i just call:

List<Users> users = userService.findAllUsers();
System.out.println(users);

but when a request is sent to the listOfUsers method, I get an error: Could not write JSON: failed to lazily initialize a collection of role

I have read solutions to this problem and there it is advised to add the @Transaction annotation or use joint fetch in the request, but I have both, but I still get an error.Can someone explain how to get rid of this error and?

Users

package com.example.securityWithHibernate.Model;

import org.hibernate.validator.constraints.Length;

import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import java.util.Set;

@Entity
@Table(name = "users")
public class Users {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "name")
    @Length(min = 5, message = "*Your user name must have at least 5 characters")
    @NotEmpty(message = "*Please provide a user name")
    private String name;

    @Column(name = "first_name")
    @NotEmpty(message = "*Please provide your name")
    private String firstName;

    @Column(name = "last_name")
    @NotEmpty(message = "*Please provide your last name")
    private String lastName;

    @Column(name = "email")
    @Email(message = "*Please provide a valid Email")
    @NotEmpty(message = "*Please provide an email")
    private String email;

    @Column(name = "user_password")
    @Length(min = 5, message = "*Your password must have at least 5 characters")
    @NotEmpty(message = "*Please provide your password")
    private String userPassword;

    public Set<Roles> getRoles() {
        return roles;
    }

    public void setRoles(Set<Roles> roles) {
        this.roles = roles;
    }

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "user_roles",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id")
    )
    private Set<Roles> roles;


    public Users(Long id, String name, String firstName, String lastName, String email, String userPassword) {
        this.id = id;
        this.name = name;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.userPassword = userPassword;
    }

    /*public Users( String name, String firstName, String lastName, String email, String userPassword) {

        this.name = name;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.userPassword = userPassword;
    }*/

    public Users() {

    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    @Override
    public String toString() {
        return "Users{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", userPassword='" + userPassword + '\'' +
                ", roles=" + roles +
                '}';
    }
}

Roles

package com.example.securityWithHibernate.Model;

import javax.persistence.*;
import java.util.Set;

@Entity
@Table(name = "roles")
public class Roles {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    public Roles(Long id, String role) {
        this.id = id;
        this.role = role;
    }

    public Roles() {

    }

    @Column(name = "role_name")
    private String role;

    @ManyToMany(mappedBy = "roles")
    private Set<Users> users;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public Set<Users> getUsers() {
        return users;
    }

    public void setUsers(Set<Users> users) {
        this.users = users;
    }

    @Override
    public String toString() {
        return "Roles{" +
                "id=" + id +
                ", role='" + role + '\'' +
                '}';
    }
}

Alpharius
  • 489
  • 5
  • 12
  • @xerx593 Could you explain points a and b a little more? – Alpharius Nov 14 '21 at 20:25
  • I think [this](https://stackoverflow.com/q/48117059/592355) is the same problem/question. The accepted answer also cares about (next) "cyclic reference" problem. – xerx593 Nov 14 '21 at 20:33
  • Have you tried removing `@ManyToMany(fetch = FetchType.LAZY)` from `roles` property in `Users` class? I am not really sure if it is simply ignored even if your query includes `JOIN FETCH`. – João Dias Nov 14 '21 at 22:38

0 Answers0