2016-06-10 80 views
1

怪異的行爲

單保留兩個實體之間簡單的關係 - >多對一座位

實體是

@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節省()被

@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.ALLcascade=CascadeType.PERSIST,仍然得到同樣的結果(即它仍然保存在預留表seats.size()倍以上的預約對象)。

任何解決方案,請這。

回答

0

請不要使用合併來保存新實體。 從here

將給定對象的狀態複製到具有相同標識符的持久對象上。如果當前沒有與會話關聯的持久實例,則會加載它。返回持久化實例。 如果給定實例未保存,請保存副本並將其作爲新持久實例返回。給定的實例不會與會話關聯。如果關聯映射爲cascade =「merge」,則此操作級聯到關聯的實例。

這意味着您的實例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); 
    ... 
}