I am developing a web project with spring boot using jpa, I have a problem using swagger and testing an api of mine named getAppointmentById, I tried using @JsonIgnore, @JsonManagedReference, @JsonBackReference but none of them worked.Here are the details:
Swagger not responding
enter image description here
Logs:
2024-07-13T01:49:20.963+07:00 WARN 940 — [petcaresystem] [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Ignoring exception, response committed already: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError)
2024-07-13T01:49:20.963+07:00 WARN 940 — [petcaresystem] [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError)]
Appointment.java
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "Appointment")
public class Appointment implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "appointment_id")
private Long appointmentId;
@ManyToMany
// @JsonManagedReference
@JsonIgnore
@JoinTable(
name = "doctor_booked",
joinColumns = @JoinColumn(name = "appointment_id"),
inverseJoinColumns = @JoinColumn(name = "doctor_id"))
private Collection<Doctor> bookedDoctor;
@ManyToOne
@JoinColumn(name = "pet_id")
@EqualsAndHashCode.Exclude
@ToString.Exclude
private Pet pet;
@Enumerated(EnumType.STRING)
@Column(name = "status")
private Status status;
@Column(name = "create_date")
private LocalDate create_date;
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
@Column(name = "startTime", nullable = false)
private LocalDateTime startTime;
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
@Column(name = "endTime", nullable = true)
private LocalDateTime endTime;
@ManyToMany
// @JsonManagedReference
@JsonIgnore
@JoinTable(
name = "service_booked",
joinColumns = @JoinColumn(name = "service_id"),
inverseJoinColumns = @JoinColumn(name = "appointment_id"))
private Collection<Services> bookedService;
@OneToOne
// @MapsId
@JoinColumn(name = "userOrder_id", nullable = true)
@JsonIgnore
// @OneToOne(mappedBy = "appointment")
private UserOrder userOrder;
// @MapsId
@OneToOne
@JoinColumn(name = "boardingAppointment_id", nullable = true)
@JsonIgnore
// @OneToOne(mappedBy = "appointment")
private BoardingAppointment boardingAppointment;
// @MapsId
@OneToOne
@JoinColumn(name = "review_id", nullable = true)
// @OneToOne(mappedBy = "appointment")
@JsonIgnore
private Review review;
}
Doctor.java
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "Doctor")
public class Doctor implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "doctor_id")
private Long doctorId;
@OneToOne
@JsonIgnore
@JoinColumn(name = "user_id", nullable = false)
private AuthenUser user;
@ManyToOne
@JoinColumn(name = "department_id")
@EqualsAndHashCode.Exclude
@ToString.Exclude
private Departments department;
@ManyToMany(mappedBy = "bookedDoctor")
@JsonIgnore
// @JsonBackReference
private Collection<Appointment> appointment;
// @MapsId
@JoinColumn(name = "schedule_id", nullable = true)
@OneToOne
@JsonIgnore
private Schedule schedule;
}
Services.java
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "Services")
public class Services {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "service_id")
private Long serviceId;
@Column(name = "service_name", nullable = false)
private String serviceName;
@Column(name = "description", nullable = false)
private String description;
@ManyToMany
@JoinTable(
name = "type_service",
joinColumns = @JoinColumn(name = "service_id"),
inverseJoinColumns = @JoinColumn(name = "serviceType_id"))
private Collection<ServiceType> typeOfService;
@Column(name = "price", nullable = false)
private float price;
@Column(name = "discount_percent", nullable = true)
private int discountPercent;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false)
private Status status;
@ManyToMany(mappedBy = "bookedService")
@JsonIgnore
// @JsonBackReference
private Collection<Appointment> appointment;
@ManyToMany(mappedBy = "services")
@JsonIgnore
private Collection<Combo> serviceCombo;
}
Controller
@GetMapping("/getAppointment/{appointmentId}")
@CrossOrigin
public AppointmentResponseDTO getAppointmentById(@PathVariable Long appointmentId) {
AppointmentResponseDTO appointmentResponseDTO = appointmentService.findAppointmentById(appointmentId);
return appointmentResponseDTO;
}
Service
public AppointmentResponseDTO findAppointmentById(Long appointmentId) {
LocalDateTime localDateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format_pattern);
String timeStamp = localDateTime.format(formatter);
String message = "Create new appointment successfully";
int statusCode = HttpStatus.OK.value();
HttpStatus statusValue = HttpStatus.OK;
AppointmentResponseInfor infor = new AppointmentResponseInfor();
AppointmentResponseData data = new AppointmentResponseData();
Appointment appointment = new Appointment();
try{
appointment = appointmentRepository.findByAppointmentId(appointmentId);
if(appointment == null){
message = "Appointment not found!";
statusCode = HttpStatus.NOT_FOUND.value();
statusValue = HttpStatus.NOT_FOUND;
infor.setMessage(message);
infor.setStatusCode(statusCode);
infor.setStatusValue(statusValue);
return new AppointmentResponseDTO(infor, data);
}
// status
data.setStatus(appointment.getStatus());
// create date
data.setCreate_date(appointment.getCreate_date());
// start time
data.setStartTime(appointment.getStartTime());
// end time
data.setEndTime(appointment.getEndTime());
// find booked doctor
Collection<Doctor> bookedDoctors = appointment.getBookedDoctor();
List<Doctor> doctorList = new ArrayList<>(bookedDoctors);
for (Doctor doctor : doctorList) {
data.setBookedDoctor(doctor);
}
// find booked service
Collection<Services> bookedServices = appointment.getBookedService();
List<Services> serviceList = new ArrayList<>(bookedServices);
for (Services service : serviceList) {
data.setBookedService(service);
}
// find pet
Pet pet = petRepository.findByPetId(appointment.getPet().getPetId());
data.setPet(pet);
// user order
UserOrder userOrder = ordersRepository.findByUserOrderId(appointment.getUserOrder().getUserOrderId());
data.setUserOrder(userOrder);
// review
Review review = reviewRepository.findByReviewId(appointment.getReview().getReviewId());
data.setReview(review);
// boarding appointment
BoardingAppointment boardingAppointment = boardingRepository.findByBoardingId(appointment.getBoardingAppointment().getBoardingId());
data.setBoardingAppointment(boardingAppointment);
}catch (Exception e){
message = "Something went wrong, server error!";
statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
statusValue = HttpStatus.INTERNAL_SERVER_ERROR;
infor.setMessage(message);
infor.setStatusCode(statusCode);
infor.setStatusValue(statusValue);
}
infor.setTimeStamp(timeStamp);
return new AppointmentResponseDTO(infor, data);
}
I tried using @JsonIgnore, @JsonManagedReference, @JsonBackReference but the result is still the same.
Nguyen Le Hoang Chinh Chinh is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.