2016-05-27 192 views
2

我有一個簡單的Spring啓動應用程序用於Spring數據休息實現。如何在Spring Data Rest中的兩個實體之間POST和PUT關係@OneToMany/@ManyToOne?

這是主類:

​​

我有兩個簡單的實體:書和作者。 相互之間的關係是1個作者 - >Ñ圖書

這是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 

} 

這是「AuthorRepository 「:

@RestResource(path = "authors", rel = "authors") 
public interface AuthorRepository extends JpaRepository<Author, UUID> { 
} 

這就是」BookRepository「:

@RestResource(path = "books", rel = "books") 
public interface BookRepository extends JpaRepository<Book, UUID> { 
} 

應用程序運行完美,在URL 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" 
    } 
    } 
} 

的URL 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 
    } 
} 

和URL 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 
    } 
} 

我試圖讓一些HTTP POST由Book類開始。

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 

這是該URL的響應頁:

{ 
    "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(無內容)。 如果我去的URL 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" 
    } 
    } 
} 

的「書」屬性仍然是空的。爲什麼?

此外,該URL返回一個空頁:http://localhost:8080/books/61311c9b-b33a-463c-9e6e-8e5efc0a7ad1/author

我預期的關係尚未處理。

如果我在插入書籍之前先從作者開始進行相同的過程,則存在關係。

如何從Book實體開始保存兩個實體之間的關係?

感謝

+0

面對相同的問題,這裏描述https://stackoverflow.com/questions/39229472/how-to-create-a-reference-between-entities-in-spring-data-rest-application –

回答

0

要做到這一點相反的,你@OneToMany(取= FetchType.LAZY,targetEntity = Book.class,的mappedBy =「作者」)應該有級聯選項,它實際上堅持的變化書本實體。

試試這個:

@OneToMany(取= FetchType.LAZY,targetEntity = Book.class,的mappedBy = 「作者」,級聯= CascadeType.ALL)

0

您正在使用雙向一對多,所以每當添加或刪除子元素時都必須使用「實用程序方法」來同步兩端(請參閱manual)。

但你幾乎可以做同樣的修改只是二傳手books,像這樣:

@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}(或根本不使用級聯)。

相關問題