Tô tentando salvar um objeto Reservation no banco, no json ele recebe o id de um User que já tá cadastrado, mas ta dando esse erro:
org.hibernate.PersistentObjectException: detached entity passed to persist: com.topgun.airline.domain.user.User
segue as classes:
@Entity
@Table(name = "tb_reservation")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Reservation {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id_reservation")
private Long id;
@JoinColumn(name = "id_user")
@ManyToOne(cascade = CascadeType.ALL)
private User user;
@JoinColumn(name = "id_flight")
@OneToOne
private Flight flight;
@Column(name = "reservation_available_seats", nullable = false, precision = 4)
private Integer numberOfSeats;
@JoinColumn(name = "id_payment", nullable = false)
@JsonManagedReference
@OneToOne(cascade = CascadeType.ALL)
private Payment payment;
@Column(name="reservation_date")
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
private LocalDateTime reservationDate;
@Column(name = "reservation_active", columnDefinition = "BIT(1) DEFAULT 1")
private Boolean active = true;
public Reservation(ReservationDTO data) {
this.user = new User(data.userId());
this.flight = new Flight(data.flightId());
this.numberOfSeats = data.numberOfSeats();
this.payment = new Payment(data.payment());
}
public Reservation(ReservationUpdateDTO data){
this.numberOfSeats = data.numberOfSeats();
}
public Reservation(Long reservationId) {
this.id = reservationId;
}
public void deactivateReservation(){
this.active = false;
}
@PrePersist
protected void prePersist() {
reservationDate = LocalDateTime.now();
}
}
public record ReservationDTO(Long flightId, Long userId, Integer numberOfSeats, PaymentDTO payment) {
}
@Service
public class ReservationService {
@Autowired
ReservationRepository reservationRepository;
public Reservation saveReservation(Reservation newReservation){
return reservationRepository.save(newReservation);
}
}
@RestController
public class ReservationController {
@Autowired
private ReservationService reservationService;
@Autowired
private UserService userService;
@Autowired
private FlightService flightService;
@Transactional
@PostMapping("/reservation")
public ResponseEntity<Reservation> save(@RequestBody ReservationDTO data) {
User user = userService.findUserById(data.userId());
if (user == null) {
throw new IllegalArgumentException("User not found");
}
Flight flight = flightService.findFlightById(data.flightId());
if (flight == null) {
throw new IllegalArgumentException("Flight not found");
}
Reservation reservation = new Reservation(data);
reservation.setUser(user);
reservation.setFlight(flight);
Reservation savedReservation = reservationService.saveReservation(reservation);
return ResponseEntity.ok(savedReservation);
}
}
@Entity(name = "User")
@Table(name = "tb_usuario")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "cd_user")
private Long id;
@Column(name = "nm_user", nullable = false, length = 70)
private String name;
@JsonManagedReference
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "cd_adress")
private Adress adress;
@Column(name="lg_email", nullable = false, unique = true)
private String email;
@Column(name="ps_password")
private String password;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<Reservation> reservations;
@Column(name = "bl_active", columnDefinition = "BIT(1) DEFAULT 1")
private Boolean active = true;
public User(Long userId) {
this.id = userId;
}
public User(UserDTO data) {
this.name = (data.name() != null) ? data.name() : this.name;
this.adress = (data.adress() != null) ? new Adress(data.adress()) : this.adress;
this.email = (data.email() != null) ? data.email() : this.email;
this.password = (data.password() != null) ? data.password() : this.password;
}
public record UserDTO(String name, AdressDTO adress, String email, String password) {
}
o código completo tá no github: https://github.com/trcosta97/top-gun-airline