我有一个简单的Spring Boot应用程序用于Spring Data Rest实现。
这是主要课程:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
我有两个简单的实体:书和作者。 彼此之间的关系是1作者 - > N书
这是Author.class:
@Entity
@Table
public class Author {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(columnDefinition = "BINARY(16)", length = 16)
private UUID id;
@Column
private String name;
@OneToMany(fetch = FetchType.LAZY, targetEntity = Book.class, mappedBy = "author")
private List<Book> books;
// getters and setters
}
这是Book.class:
@Entity
@Table
public class Book {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(columnDefinition = "BINARY(16)", length = 16)
private UUID id;
@Column
private String title;
@Column
private String language;
@ManyToOne(fetch = FetchType.EAGER, targetEntity = Author.class)
private Author author;
// getters and setters
}
这是&#34; AuthorRepository&#34;:
@RestResource(path = "authors", rel = "authors")
public interface AuthorRepository extends JpaRepository<Author, UUID> {
}
这是&#34; BookRepository&#34;:
@RestResource(path = "books", rel = "books")
public interface BookRepository extends JpaRepository<Book, UUID> {
}
应用程序运行完美,在网址http://localhost:8080/我有此回复页面:
{
"_links" : {
"authors" : {
"href" : "http://localhost:8080/authors{?page,size,sort}",
"templated" : true
},
"books" : {
"href" : "http://localhost:8080/books{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile"
}
}
}
网址http://localhost:8080/authors会返回此页面:
{
"_embedded" : {
"authors" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/authors"
},
"profile" : {
"href" : "http://localhost:8080/profile/authors"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}
网址http://localhost:8080/books返回此页面:
{
"_embedded" : {
"books" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/books"
},
"profile" : {
"href" : "http://localhost:8080/profile/books"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}
我试图通过Book类开始一些HTTP POST。
HTTP POST
url: http://localhost:8080/books
header: Content-Type:application/json
payload: { "title": "Book Title" }
Status: 201: Created
Location: http://localhost:8080/books/61311c9b-b33a-463c-9e6e-8e5efc0a7ad1
实际上,网址http://localhost:8080/books/61311c9b-b33a-463c-9e6e-8e5efc0a7ad1会返回此页面:
{
"title" : "Book Title",
"language" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/books/61311c9b-b33a-463c-9e6e-8e5efc0a7ad1"
},
"book" : {
"href" : "http://localhost:8080/books/61311c9b-b33a-463c-9e6e-8e5efc0a7ad1"
},
"author" : {
"href" : "http://localhost:8080/books/61311c9b-b33a-463c-9e6e-8e5efc0a7ad1/author"
}
}
}
我为作者做了同样的事情。
HTTP POST
url: http://localhost:8080/authors
header: Content-Type:application/json
payload: { "name": "Author Name" }
Status: 201: Created
Location: http://localhost:8080/authors/634d3bd8-abe6-472b-97cd-04a455bdfb11
这是该网址的响应页面:
{
"name" : "Author Name",
"_links" : {
"self" : {
"href" : "http://localhost:8080/authors/634d3bd8-abe6-472b-97cd-04a455bdfb11"
},
"author" : {
"href" : "http://localhost:8080/authors/634d3bd8-abe6-472b-97cd-04a455bdfb11"
},
"books" : {
"href" : "http://localhost:8080/authors/634d3bd8-abe6-472b-97cd-04a455bdfb11/books"
}
}
}
请注意,作者和书籍之间的关系尚不存在,因此我尝试发送PUT请求。
HTTP PUT
url: http://localhost:8080/authors/634d3bd8-abe6-472b-97cd-04a455bdfb11
header: Content-Type:application/json
payload: { "books": ["http://localhost:8080/books/61311c9b-b33a-463c-9e6e-8e5efc0a7ad1"] }
Status: 204: No Content
Location: http://localhost:8080/authors/634d3bd8-abe6-472b-97cd-04a455bdfb11
我的响应代码是HTTP 204(无内容)。 如果我转到网址http://localhost:8080/authors/634d3bd8-abe6-472b-97cd-04a455bdfb11/books我会期待这本书,但我有这个结果:
{
"_embedded" : {
"books" : [ ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/authors/634d3bd8-abe6-472b-97cd-04a455bdfb11/books"
}
}
}
&#34;书籍&#34;财产仍然是空的。为什么呢?
此外,此网址返回空白页面:http://localhost:8080/books/61311c9b-b33a-463c-9e6e-8e5efc0a7ad1/author
该关系尚未按我的预期处理。
如果我在插入书籍之前从作者开始进行相同的处理,则存在关系。
如何从Book实体开始保存两个实体之间的关系?
由于
答案 0 :(得分:0)
为了使这种情况发生逆转,你的@OneToMany(fetch = FetchType.LAZY,targetEntity = Book.class,mappedBy =&#34; author&#34;)中应该有级联选项来实际保留书中的更改实体。
试试这个:
@OneToMany(fetch = FetchType.LAZY,targetEntity = Book.class,mappedBy =&#34; author&#34;,cascade = CascadeType.ALL)
答案 1 :(得分:0)
您正在使用双向 OneToMany ,因此您必须使用“实用程序方法”,无论何时添加或删除子元素,都会同步两端(请参阅manual )。
但你可以做几乎相同的修改books
setter,就像这样:
@Entity
public class Author {
//...
@OneToMany(mappedBy = "author")
private List<Book> books;
public void setBooks(List<Book> books) {
books.forEach(book -> book.setAuthor(this));
this.books = books;
}
//...
}
查看我的example。
P.S。如果您的实体是独立的,请不要使用cascade = CascadeType.ALL
,而是使用cascade = {CascadeType.PERSIST, CascadeType.MERGE}
(或根本不使用级联)。