Spring Data Rest发布到集合端点

3

我认为我的问题非常简单,但经过多个小时的搜索仍然找不到解决方案,而且我对Spring相对较新,因此请原谅任何术语不准确或明显错误。

我有一个事件对象,它与一个预订对象存在一对多关系,如下所示:

事件:

@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
}

预订:

@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
}

事件仓库:

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>{

}

这些是端点的公开方式:
/rest/events /rest/bookings
一个事件实例如下:
/rest/events/1
它的预订如下:
/rest/events/1/bookings
我想要实现的是创建一个新的预订并将其与事件关联。我的数据模型需要event_id作为必填字段(因为没有事件,预订就没有意义),而我的每个纤维都表明我应该能够将新的预订对象发布到/rest/events/1/bookings并创建一个与id为1的事件相关联的新的预订对象。然而,每当我尝试发布到该URI时,我都会收到以下消息:
"Failed to load resource: the server responded with a status of 405 (Method Not Allowed)"
检查/rest/events/1/bookings端点的标头时,我可以看到允许发布:
Access-Control-Allow-Methods:POST, GET, OPTIONS, DELETE
所以现在我完全困惑和失落。感觉我应该可以这样创建预订,我真的不想走创建孤立预订然后将其与事件关联的路线,因为这会破坏我的数据模型(需要在预订中使event_id为null),而且没有办法在事务内执行这两个操作(有吗?)。我已经尝试在我的模型的其他集合上执行类似的操作,它们也被拒绝了,所以我猜这与我的spring data rest配置有关,但我不知道是什么。感谢您提前的任何帮助或指针。

一个类似于你的问题的链接:https://dev59.com/dV8e5IYBdhLWcg3w2NRR - ArunM
3个回答

2

将您的新预订发布到:/rest/bookings

{
  "title": "my booking title",
  "contact": "my contact",
  "event": "http:localhost:8080/rest/events/1"
}

正如其他人已经回答的那样,您可以通过对/rest/events/1/bookings进行PUT(text/uri-list)来创建预订并将其与事件关联,但我认为上述方法更加合理。


非常感谢您给出 "text/uri-list" 的提示。虽然当前的Spring文档表示应该发送 Content-Type: "application/json"。但它没有指定要发送的JSON格式。 - Robert

1

/rest/events/1/bookings是一个关联资源。它只能处理URI。

如果您想创建一个新的Booking,那么将其发布到/rest/bookings是比较合理的。 event字段应该包含关联事件的URI,例如/rest/events/1

顺便说一下:Access-Control-Allow-Methods并不一定表示API支持哪些方法。它仅与跨域浏览器请求相关,并且其值很可能对于每个URL都相同。


谢谢,我觉得我已经尝试了所有的方法,但在发布/rest/bookings时还是没成功,包括将事件对象放在事件字段中,并将事件URI放在预订链接上。 - Drew

0

这不是您的Spring Rest配置问题,正如此线程所述。我的理解是,您尝试的方式不受Spring Rest支持。

根据此处提供的信息,您必须使用以下内容来更新资源,这意味着您必须更新您的模型。

curl -v -X PUT -H "Content-Type: text/uri-list" -d "http://localhost:8080/events/1" http://localhost:8080/bookings/1/event

我认为海报想要在单个事务中创建一个新的预订并将其链接到现有事件。使用更新资源机制需要先创建预订,然后再进行链接,这是两个事务。 - Jason
从我链接的答案讨论中,我的理解是无法完成问题所要求的操作。 - ArunM
我已经看过提到的线程,但它并没有真正回答我想做的事情。正如Jay所评论的,我希望能够在一个事务中完成所有信息的提交(包括引用ID)。此外,还有一个问题,即尽管响应头中显示允许POST请求,但为什么我会收到POST不允许的消息。 - Drew
据我所知,您正在尝试做一些不受支持的事情。就POST而言,我认为这是需要在框架中进行更改,但他们还没有开始做。 - ArunM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接