【发布时间】:2021-07-19 09:18:43
【问题描述】:
我正在 JavaEE 中为处理管理房间预订的应用程序开发一个 REST API。 我遇到了以下问题:
我的应用有 3 个实体类:
@Entity
public class Reservation {
@GeneratedValue
@Id
private Integer id;
@ManyToOne
@JoinColumn(name="room_id")
private Room room;
private LocalDateTime reservationStart;
private LocalDateTime reservationEnd;
@ManyToOne
@JoinColumn(name="user_id")
private User user;
@Entity
public class Room {
@GeneratedValue
@Id
private Integer id;
private String description;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "room")
private List<Reservation> reservations;
}
@Entity
public class User {
@Id
@GeneratedValue
private Integer id;
private String firstName;
private String surname;
private UserRole role;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private List<Reservation> reservations;
}
我想在使用 JPA 的 DAO 中的一个查询中检索属于用户的所有数据: 个人数据、用户的预订以及每次预订的房间详情, 无需创建无限数量的嵌套对象:
{
"user": {
"id": "id",
"firstname": "name",
"lastname": "lastname",
"email": "email",
"Reservations": [
{
"id" : "1234",
"startdate": "S",
"stopdate": "date",
"room": {
"id": "id",
"description": "somedescription"
}
},
{
"id" : "2134",
"startdate": "S",
"stopdate": "date",
"room": {
"id": "id",
"description": "description"
}
}
]
}
}
天真的方法:
public User read(Integer id) {
return entityManager.find(User.class, id);
}
显然返回 LazyInitializationError,Reservations 作为 PersistentBag 返回,而不是 List,因为它们没有被初始化。
public User read(Integer id) {
User user = entityManager.find(User.class, id);
user.getReservations();
return user;
}
返回相同。
也是这样:
public User read(Integer id) {
Query query = entityManager.createQuery("select u from User u " +
"join fetch u.reservations r " +
"where u.id = :id");
query.setParameter("id", id);
Object singleResult = query.getSingleResult();
return (User) singleResult;
}
切换到 FetchType.Eager 以 RESTEASY008205 结束:JSON Binding 序列化错误 java.lang.StackOverflowError,我认为是因为 yasson 尝试执行无限深度嵌套的 JSON。
我不想在@ManyToOne 关系上使用@JsonbTransient 注释,因为我还希望能够检索,例如,属于一个房间的所有预订,比如按日期过滤,以及在这些预订中谁的信息保留它们,所以我需要这些字段。
我可以通过简单的 SQL 查询(在控制台)检索数据:
select * from User
LEFT JOIN Reservation as reservation on user_id = reservation.user_id
LEFT JOIN Room as room on reservation.room_id = room.id
WHERE User_id = 1
但 entityManager.createNativeQuery 返回
NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [id] during auto-discovery of a native-sql query
JAX-RS 端点被标记为事务性。它有一个直接注入的 DAO 对象,作为回报,它有一个注入的 EntityManager。 我正在使用 JBOSS 20.0.1FINAL、Hibernate 5.4.9、JAVAEE 8.0.1、Java 1.8。
可能这只是 JPQL 中一个很好的查询的问题,但到目前为止我已经花了 2 天多的时间,仍然无法让它工作(但学到了很多关于调试 Hibernate 的知识),所以任何帮助将不胜感激。
【问题讨论】: