I have created a JPA object with a @ManyToOne
relationship with 2 other objects. But I'm having problems getting it to work. Especially regarding the JSON body. I have removed some annotations if they didn't seem important
public class Booking implements Serializable {
@Id
@ApiModelProperty(readOnly = true)
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
@NotNull
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
@JoinColumn(name = "customer_id")
private Customer customer;
@NotNull
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.DETACH)
@JoinColumn(name = "taxi_id")
private Taxi taxi;
@NotNull
@Future(message = "Bookings can not be in the past. Please choose one from the future")
@Column(name = "booking_date")
@Temporal(TemporalType.DATE)
private Date bookingDate;
}
public class Customer implements Serializable {
@Id
@ApiModelProperty(readOnly = true)
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
@OneToMany(mappedBy = "taxi", cascade = CascadeType.ALL)
@ApiModelProperty(hidden = true)
private List<Booking> bookings;
}
public class Taxi implements Serializable {
@Id
@ApiModelProperty(readOnly = true)
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
private String registration;
private String numberOfSeats;
@OneToMany(mappedBy = "taxi", cascade = CascadeType.ALL)
@ApiModelProperty(hidden = true)
private List<Booking> bookings;
}
The RestService
public Response createBooking(
@ApiParam(value = "Customer ID, Taxi ID and a booking date required to create a booking", required = true)
org.jboss.quickstarts.wfk.booking.Booking booking)
{
if (booking == null) {
throw new RestServiceException("Bad Request", Response.Status.BAD_REQUEST);
}
Response.ResponseBuilder builder;
try {
// Go add the new Booking.
service.create(booking);
builder = Response.status(Response.Status.CREATED).entity(booking);
} catch (ConstraintViolationException ce) {
//Handle bean validation issues
Map<String, String> responseObj = new HashMap<>();
for (ConstraintViolation<?> violation : ce.getConstraintViolations()) {
responseObj.put(violation.getPropertyPath().toString(), violation.getMessage());
}
throw new RestServiceException("Bad Request", responseObj, Response.Status.BAD_REQUEST, ce);
} catch (Exception e) {
// Handle generic exceptions
throw new RestServiceException(e);
}
log.info("createBooking completed. Booking = " + booking.toString());
return builder.build();
}
The service class where crud is the repository
@Inject
private BookingRepository crud;
Booking create(Booking booking) throws ConstraintViolationException, ValidationException, Exception {
log.info("BookingService Testing: " + booking.toString());
log.info("BookingService.create() - Creating " + booking.getCustomer().getId() + " " + booking.getTaxi().getId());
// Check to make sure the data fits with the parameters in the Booking model and passes validation.
//validator.validateBooking(booking);
// Write the booking to the database.
return crud.create(booking);
}
The repository class
@Inject
private EntityManager em;
Booking create(Booking booking) throws ConstraintViolationException, ValidationException, Exception {
log.info("BookingRepository.create() - Creating " + booking.getCustomer().getId() + " " + booking.getTaxi().getId());
// Write the booking to the database.
em.persist(booking);
return booking;
}
But when I look at my swagger documentation it shows this. But I don't want to create new objects. I want to access the objects with the id
{
"customer": {
"firstName": "string",
"lastName": "string",
"email": "string",
"phoneNumber": "string"
},
"taxi": {
"registration": "string",
"numberOfSeats": 0
},
"bookingDate": "2021-11-11T22:20:34.952Z"
}
So I would like to send this as body
{
"customer_id": 0,
"taxi_id": 0,
"bookingDate": "2021-11-11T22:20:34.952Z"
}
Does anybody have any solutions to this? Let me know if you need more code.
You need to change your RestService
to accept an instance of the following class instead of Booking
:
public class BookingCreationRequest {
@JsonProperty("customer_id")
private Long customerId;
@JsonProperty("taxi_id")
private Long taxiId;
private Date bookingDate;
}
So something like the following in your RestService
:
public Response createBooking(BookingCreationRequest bookingCreationRequest) {
(...)
service.create(bookingCreationRequest);
(...)
}
Now in your service class, you need to get both the Customer
and the Taxi
entities associated with the request, build the Booking
object and persist it in the database:
@Inject
private BookingRepository crud;
@Inject
private TaxiService taxiService;
@Inject
private CustomerService customerService;
Booking create(BookingCreationRequest bookingCreationRequest) throws ConstraintViolationException, ValidationException, Exception {
(...)
Taxi taxi = taxiService.getTaxiById(bookingCreationRequest.getTaxiId());
Customer customer = customerService.getCustomerById(bookingCreationRequest.getCustomerId());
Booking booking = new Booking();
booking.setTaxi(taxi);
booking.setCustomer(customer);
booking.setBookingDate(bookingCreationRequest.getBookingDate());
return crud.create(booking);
}