当前位置: 首页 > 知识库问答 >
问题:

对象引用未保存的瞬态实例-在刷新之前保存瞬态实例:Spring Data JPA

寿丰
2023-03-14

我有以下3种型号:

模式1:预订

    @Entity
    public class Reservation  {
    
        public static final long NOT_FOUND = -1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        public Long id;
        
        @OneToMany(mappedBy = "reservation", cascade = CascadeType.ALL, orphanRemoval = true)
        public List<RoomReservation> roomReservations = new ArrayList<>();
}
 public class RoomReservation extends{
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        public Long id;
    
        @JsonIgnore
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "RESERVATION_ID")
        public Reservation reservation;
    
        @OneToMany(mappedBy = "roomReservation", cascade = CascadeType.ALL, orphanRemoval = true)
        public List<GuestDetails> guestDetails = new ArrayList<>();
    }
public class GuestDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    public Long guestId;

    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ROOM_RESERVATION_ID")
    public RoomReservation roomReservation;

    public Boolean isPrimary;

    @Transient
    public Guest guest;

}
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.model.GuestDetails.roomReservation -> com.model.RoomReservation
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1760)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:82)
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 73 common frames omitted

请让我知道我在做什么错误。谢谢

通过更改GuestDetails保存预订对象的代码:

Reservation existingReservation = reservationRepository.findOne(reservationId);
Reservation reservation = reservationParser.createFromJson(reservationNode);
existingReservation.roomReservations.forEach(roomReservation -> {
                    RoomReservation updatedRoomReservation = reservation.roomReservations.stream().filter(newRoomReservation -> Objects.equals(roomReservation.id, newRoomReservation.savedReservationId)).findFirst().orElse(null);
                    if(updatedRoomReservation != null){
                        roomReservation.guestDetails = updatedRoomReservation.guestDetails;
                    }
                });
reservationRepository.save(existingReservation);

共有1个答案

尹雅健
2023-03-14
... save the transient instance before flushing : 
    com.model.GuestDetails.roomReservation -> com.model.RoomReservation

此异常清楚地表明,GuestDetails中包含的RoomReservation在数据库中不存在(很可能是IDNULL)。

通常,您可以通过以下方法解决此异常:

>

  • 在保存客房详细信息之前保存RoomReservation实体

    public class RoomReservation{
    
        //..... other lines of code
    
        @OneToMany(mappedBy = "roomReservation", cascade = CascadeType.ALL, orphanRemoval = true)
        private List<GuestDetails> guestDetails = new ArrayList<>();
    
        public void setGuestDetails(List<GuestDetails> guestDetails) {
    
               this.guestDetails.clear();
    
               // Assuming that by passing null or empty arrays, means that you want to delete
               // all GuestDetails from this RoomReservation entity
               if (guestDetails == null || guestDetails.isEmpty()){
                   return;
               }
    
               guestDetails.forEach(g -> g.setRoomReservation(this));
               this.guestDetails.addAll(guestDetails);
        }
    
        public List<GuestDetails> getGuestDetails() {
            // Expose immutable collection to outside world  
            return Collections.unmodifiableList(guestDetails);
        }
    
        // You may add more methods to add/remove from [guestDetails] collection
    }
    
    Reservation existingReservation = reservationRepository.findOne(reservationId);
    Reservation reservation = reservationParser.createFromJson(reservationNode);
    existingReservation.roomReservations.forEach(roomReservation -> {
                        Optional<RoomReservation> updatedRoomReservation = reservation.roomReservations.stream().filter(newRoomReservation -> Objects.equals(roomReservation.id, newRoomReservation.savedReservationId)).findFirst();
                        if(updatedRoomReservation.isPresent()){
                            // roomReservation already exists in the database, so we don't need to save it or use `Cascade` property
                            roomReservation.setGuestDetails( updatedRoomReservation.get().getGuestDetails());
                        }
                    });
    reservationRepository.save(existingReservation);
    

    希望有帮助!

  •  类似资料: