我在两个实体之间有简单的关系
One-Reservation - >许多座位
实体
@Entity
public class Reservation implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long reservationId;
private String reservationDate;
private static final long serialVersionUID = 1L;
@OneToMany(mappedBy = "reservation", fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@Fetch(value = FetchMode.SUBSELECT)
private List<Seat> seats = new CopyOnWriteArrayList<Seat>();
// omitting get()s and set()s
}
和
@Entity
public class Seat implements Serializable {
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private Long seatId;
private Integer seatNumber;
private static final long serialVersionUID = 1L;
@JsonIgnore
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "reservationId")
private Reservation reservation;
// omitting get()s and set()s
}
首先,我保存预订信息,然后在控制器中保存座位信息
@RequestMapping(value = "/proceed", method = RequestMethod.POST)
public String checkOut(@ModelAttribute("passenger")Passenger passenger,
@RequestParam("bus_id") String busId,
@RequestParam("seats")List<Seat> seats) {
passengerService.save(passenger);
try {
System.out.println("List size is " + seats.size());
Bus selectedBus = busService.getById(Long.valueOf(busId));
Reservation reservation = new Reservation();
reservation.setBus(selectedBus);
reservation.setPassenger(passenger);
reservation.setReservationDate(new Date().toString());
// Saving reservation info here
reservationService.save(reservation);
passenger.setReservation(reservation);
passenger.setBus(selectedBus);
passengerService.update(passenger);
for (Seat seat : seats) {
seat.setBus(selectedBus);
seat.setReservation(reservation);// Here it gives weird results see details bellow
seatService.save(seat);
}
} catch (Exception e) {
System.out.println("Error is " + e.getMessage());
System.out.println("Cause is " + e.getCause());
e.printStackTrace();
}
return "reservation";
}
以下代码
for (Seat seat : seats) {
seat.setBus(selectedBus);
seat.setReservation(reservation);
seatService.save(seat);
}
SeatService save()是
@Override
public void save(Seat e) {
entityManager.merge(e);
}
它在保留表中保存seats.size()
次预订对象的相同信息在使用reservationService.save(reservation);
之前保存了相同的信息,我发现导致此结果的行
@JsonIgnore
@ManyToOne(cascade=CascadeType.ALL)// this line causes that weird behavior
@JoinColumn(name = "reservationId")
private Reservation reservation;
如果我删除cascade=CascadeType.ALL
,我会
org.hibernate.PersistentObjectException: detached entity passed to persist:
我还尝试将cascade=CascadeType.ALL
更改为cascade=CascadeType.PERSIST
,仍然得到相同的结果(即它仍然可以在预订表中节省seats.size()
倍的预订对象。)
请解决此问题。
答案 0 :(得分:0)
请不要使用merge来保存新实体。 来自here:
将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与会话关联的持久性实例,则将加载该实例。返回持久化实例。 如果给定实例未保存,请保存副本并将其作为新的持久实例返回。给定的实例不会与会话关联。如果关联是使用cascade =&#34; merge&#34;映射的,则此操作会级联到关联的实例。
这意味着你的实例reservation
不是持久的,每次在级联时,hibernate会自动插入它。
请尝试entityManager.persist
,或者你必须做出类似的事情:
ReservationService:
@Override
public Reservation save(Seat e) {
return entityManager.merge(e);
}
和控制器:
@RequestMapping(value = "/proceed", method = RequestMethod.POST)
public String checkOut(...) {
...
Reservation reservation = new Reservation();
...
reservation = reservationService.save(reservation);
...
}