休眠多对多关系查询实体而不查询其集合元素



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

我的实体:

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

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

当你的实体被序列化为 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关于使用ModelMapper的教程

一个不错的选择(Mapstruct(

最新更新