Hibernate отношения "многие ко многим" запрашивают объект без элементов коллекции - PullRequest
0 голосов
/ 26 мая 2020

Описание: У меня есть отношения "многие ко многим" между пользователем и объектом Shoplist. Я делаю rest api и хочу запрашивать только пользователя, когда кто-то делает GET для / users / {id}. Если я пытаюсь получить пользователя из БД, он говорит, что коллекция списков магазинов не инициализирована, но это именно то, что я хочу, только пользователь без его списков магазинов. Если я получаю список покупок пользователя, он работает нормально, но это не то, что я хочу.

Мои объекты:

Пользователь. java

@Entity
public class User implements Serializable {
@Id
@GeneratedValue
private int id;

private String name;

private String lastname;

@Column(nullable = false)
private String email;

private String password;

@Column(nullable = true) //maybe set @ColumnDefault()
private URL avatar;


@JsonIgnoreProperties("users")
@JoinTable(
        name = "User_Shoplist",
        joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(name = "shoplist_id", referencedColumnName = "id")
)
@ManyToMany
private Set<Shoplist> shoplists = new HashSet<>();

// getters and setter

Список магазинов. java

@Entity
public class Shoplist implements Serializable {
@Id
@GeneratedValue
private int id;
private String name;


@JsonIgnoreProperties("shoplists")
@ManyToMany(mappedBy = "shoplists")
private Set<User> users = new HashSet<>();

// getters and setter

Контроллер. java

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response index() {
    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();

    try {
        session.beginTransaction();
        User u1 = session.get(User.class, 1);
        session.getTransaction().commit();
        session.close();

        return Response.status(200).entity(u1).build();
    } catch(Exception e) {
        session.getTransaction().rollback();
        return Response.status(Response.Status.BAD_REQUEST).build();
    }

}

Цель : как I Ранее было сказано, я хочу вернуть информацию о Пользователе без всех его магазинов.

1 Ответ

0 голосов
/ 27 мая 2020

Когда ваша сущность сериализуется в JSON, вызываются все геттеры (включая getShoplists), и, поскольку это происходит вне транзакции, вы получаете LazyInitializationException. Это одна из причин, по которой объекты сущностей никогда не должны покидать службу.

Вам нужно создать DTO (объект передачи данных), назначить только те значения, которые вам нужно отправить (все это все еще в транзакции), и отправьте dto вместо объекта.

Например

public class UserDto {
  private int id;
  private String name;
  private String lastname;
  private String email;
  // btw, this is probably not a good idea to send user password to the client
  // ...
  // getters and setters
}
  session.beginTransaction();
  User u1 = session.get(User.class, 1);

  UserDto dto = new UserDto();
  dto.setName(u1.getName());
  // map other values

  session.getTransaction().commit();
  session.close();

  return Response.status(200).body(dto).build();

Учебник Baeldung по этому вопросу с использованием ModelMapper

Хорошая альтернатива (Mapstruct)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...