【问题标题】:Spring data rest POSTing a new item with ManyToMany relationshipSpring数据休息发布具有ManyToMany关系的新项目
【发布时间】:2016-12-27 16:40:32
【问题描述】:

我有两个实体:演员和电影。这两者之间存在ManyToMany 关系(因为Actor 可以加入多个Movie 并且在Movie 中您可以看到多个Actor)。在我的 Spring Data Rest API 上,我有以下端点:

http://host:port/movies
http://host:port/actors

现在假设我会从电影页面创建一个新演员。我的客户将提交一个(单个)POST 请求,其中包含演员信息以及与电影的关系。我尝试了类似以下的内容(id 为 1 的电影的新演员):

{ 
  "name": "Leonardo Di Caprio",
  "movies": [ "http://host:port/movies/1" ]
}

Spring API 以 201 Created 回复,因此格式和电影 URI 都很好。当我查询演员的 API 或 DB 时,我发现演员已经创建,但关系不存在。

我已经知道您应该为与 Spring 数据休息的多对多关系发出两个请求(一个创建参与者,一个创建关系)。我在这里询问是否有一种方法可以通过单个请求创建两者(例如 OneToMany/ManyToOne 或 OneToOne 关系。

演员类

@Entity
public class Actor {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String name;

    @ManyToMany(mappedBy = "actors")
    private List<Movie> movies;

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Movie> getMovies() {
        return movies;
    }

    public void setMovies(List<Movie> movies) {
        this.movies = movies;
    }
}

电影课

@Entity
public class Movie {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected long id;

    protected String title;

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    protected List<Actor> actors;

    public long getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<Actor> getActors() {
        return actors;
    }

    public void setActors(List<Actor> actors) {
        this.actors = actors;
    }

}

对于这两个实体,我都有标准存储库:

@Repository
public interface ActorRepository extends PagingAndSortingRepository<Actor, Long> {
}

更新

我所面临的行为是由于 JPA 处理多对多关系的方式。在这个thread 中有一个关于如何处理与 JPA 和 REST 的双向关联的巧妙解释。

我可以通过以下两个选项之一解决我的问题:

A - 执行两个 POST 请求,一个在

http://host:port/actors 

持久化新的 Actor 和一个

http://host:port/movies/{id}/actors 

如下:

...                                              |
Content-Type: text/uri-list                      | headers
...                                              |

http://host:port/actors/{id-of-the-new-actor}    | body

保持新演员和电影之间的关联。

B - 在

上只执行一个 POST 请求
http://host:port/actors 

(正如我在问题开头所述)但修改了 Actor 类中的 setMovies 方法(如我引用的线程中所述)。

【问题讨论】:

  • 发布相关电影似乎是一种奇怪的方式。你的 rest 控制器中的方法方法是什么样的?
  • 我将只发布一部相关的电影。在电影页面上,您可以为正在观看的电影添加演员,所以我认为只做一个请求是最好的方法。告诉我是否发送两个请求(一个用于新的 Actor,另一个用于 Movie 和 Actor 之间的新关系)会是更好的选择。
  • 一个没有答案的好问题:/
  • setMovies 方法的代码在哪里,应该更改哪行代码

标签: java spring rest api many-to-many


【解决方案1】:

首先创建资源: 创建演员资源:

curl -i -X POST -H "Content-Type:application/json"
    -d "{\"name\":\"Leonardo Di Caprio\"}" http://host:port/actors

然后创建电影:

curl -i -X POST -H "Content-Type:application/json"
  -d "{\"title\":\"Titanic\"}" http://host:port/movies

最后创建关联(假设 http://host:port/actors/1 是 dicaprio uri):

curl -i -X PUT -H "Content-Type:text/uri-list"
  --data-binary @movies.txt http://host:port/actors/1/movies

movies.txt 包含电影的 uri,每行单独一行:

http://host:por/movies/1
http://host:por/movies/2

关注这个有用的link

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 2017-03-13
    • 2017-08-28
    相关资源
    最近更新 更多