休眠的多对多关系查询没有其集合元素的实体

问题描述 投票:0回答:1

描述:我与用户和商店列表实体之间存在多对多关系。我正在制作一个REST API,当有人对/ users / {id}进行GET时,我只想查询User。如果我试图从数据库中获取用户,它说商店列表的集合没有被初始化,那正是我想要的,只有没有他的商店列表的用户。如果我得到用户的购物清单,则可以正常工作,但这不是我想要的。

我的实体:

User.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

Shoplist.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

Controller.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();
    }

}

目标:正如我之前所说,我想返回有关用户的信息,而没有他的所有商店清单。

java hibernate rest jax-rs
1个回答
0
投票

当您的实体序列化为JSON时,将调用所有getter(包括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's tutorial on this using ModelMapperA good alternative which is Mapstruct

© www.soinside.com 2019 - 2024. All rights reserved.