Reputation: 463
I have what I think is a fairly simple problem, but after many hours of searching can find the solution, and I'm relatively new to Spring so please excuse any incorrect terminology or obvious errors.
I have an event object, which has a one-to-many relationship to a booking object as shown below
Event:
@Entity
public class Event {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long eventId;
private Date start;
private Date end;
private String title;
@OneToMany(mappedBy="event")
private Set<Booking> Bookings;
protected Event() {
// for JPA
}
// Getters and setters omitted for brevity
}
Booking:
@Entity
public class Booking {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long bookingId;
private String title;
private String contact;
@ManyToOne
@JoinColumn(name="event_id", nullable=false)
private Event event;
public DiveBooking() {
// for JPA
}
// Getters and setters omitted for brevity
}
EventRepository:
public interface DiveEventRepository extends JpaRepository<Event, Long> {
List<Event> findByStartBetweenOrEndBetween(
@Param("start") Date startStartTime,
@Param("end") Date startEndTime,
@Param("start") Date endStartTime,
@Param("end") Date endEndTime);
}
BookingRepository
public interface BookingRepository extends JpaRepository<Booking, Long>{
}
These expose the endpoints:
/rest/events /rest/bookings
An instance of an event as:
/rest/events/1
with its bookings:
/rest/events/1/bookings
What I'm trying to achieve, is to create a new booking and have it associated with an event. My data model has event_id as a required field (as a booking is meaningless without an event), and every fibre in my being says that I should be able to post a new booking object to /rest/events/1/bookings and have it create a new booking object that is associated with event with id 1. However, whenever I try and post to that URI, I get the message:
Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
When inspecting the headers for the endpoint /rest/events/1/bookings I can see that post is allowed:
Access-Control-Allow-Methods:POST, GET, OPTIONS, DELETE
So now I'm completely confused and at a loss. It feels like I should be able to create a booking this way, and I really don't want to go down the route of having to create an orphaned booking then associate it with the event as it would break my data model (having to make event_id null in booking), and there is no way to do those to operations inside a transaction (is there?). I've tried doing similar operations on other collections in my model, and they have post denied too, so I'm guessing it's something to do with my spring data rest configuration, but I don't know what.
Thanks in advance for any help or pointers on this.
Upvotes: 3
Views: 2887
Reputation: 4738
Post your new booking to: /rest/bookings
{
"title": "my booking title",
"contact": "my contact",
"event": "http:localhost:8080/rest/events/1"
}
As others have already answered, you CAN create a booking and then associate it to an event by doing a PUT (text/uri-list) to /rest/events/1/bookings, but I think the above method is much more sensible.
Upvotes: 2
Reputation: 26858
/rest/events/1/bookings
is an association resource. It can only handle URIs.
If you want to create a new Booking
then it's somewhat logical to post to /rest/bookings
. The event
field should contain the URI of the associated event, e.g. /rest/events/1
.
Btw: Access-Control-Allow-Methods
is not necessarily an indication of what methods the API supports. It's only relevant for cross domain browser requests and it's value is most likely the same for every URL.
Upvotes: 1
Reputation: 2314
This is not a problem with your spring rest configuration as follows from the following thread. My understanding is the way you are trying to do is not supported by Spring rest
As given here, You have to use the following to update a resource which means that you have to update your model.
curl -v -X PUT -H "Content-Type: text/uri-list" -d "http://localhost:8080/events/1" http://localhost:8080/bookings/1/event
Upvotes: 0