【发布时间】:2018-07-06 09:40:12
【问题描述】:
我是 spring 和 java 的新手,如果这很明显,请道歉。
TLDR 当我发送带有嵌套资源的 JSON 时,它会创建子资源。即使它已经存在并导致持久性问题,您如何在 Spring 中阻止它?
我有两个实体,书和书架。一个书架可以有多本书,但一本书只能在一个书架上。所以书架 (1) (*) 书。
@Entity
public class Book {
@Id
@GenericGenerator(name = "uuid-gen", strategy = "uuid2")
@GeneratedValue(generator = "uuid-gen")
@Type(type = "pg-uuid")
private UUID id;
@Column(nullable = false)
private String name;
private String description;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(foreignKey = @ForeignKey(name = "shelf_id"))
private Shelf shelf;
public Book() {
}
public Book(UUID id, String name, String description, Shelf shelf) {
this.id = id;
this.name = name;
this.description = description;
this.shelf = shelf;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setShelf(Shelf shelf) {
this.shelf = shelf;
}
}
货架
@Entity
public class Shelf {
@Id
@GenericGenerator(name = "uuid-gen", strategy = "uuid2")
@GeneratedValue(generator = "uuid-gen")
@Type(type = "pg-uuid")
private UUID id;
@Column(nullable = false)
private String name;
private String description;
@OneToMany(fetch=FetchType.LAZY, mappedBy = "shelf", cascade = CascadeType.ALL)
private Set<Book> books;
public Dashboard() {
}
public Dashboard(UUID id, String name, String description, Set<Book> books) {
this.id = id;
this.name = name;
this.description = description;
this.book = book;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setBooks() {
for (Book book : books)
book.setShelf(this);
}
public Set<Book> getBooks() {
return books;
}
}
我有一个扩展 JpaRepository 的 ShelfRepository。
当我向正文提出请求时
{"name":"ShelfName", "books": [{"name": "bookName"}]}
它将返回创建资源书和书架,但不会链接它们,因为书是首先创建的,书架没有参考。所以需要调用 setBooks on the Shelf。不理想,但我想不出另一种方法。
创建一本书并使用 id 作为 books 数组中的引用(这是我希望在我的 API 中使用的),如下所示:
{"name":"otherShelfName", "books": [{"id": "7d9c81c2-ac25-46ab-bc4d-5e43c595eee3"}]}
这会导致持久性问题,因为这本书已经存在
org.hibernate.PersistentObjectException: 分离的实体传递给持久化
有没有办法在 Spring 中拥有像上面这样的嵌套资源并且能够在没有持久性问题的情况下进行关联?
-------- 服务
@Service
public class BookService {
@Autowired
private BookRepository bookRepository;
public List<Book> findAll() {
return bookRepository.findAll();
}
public Book create(Book book) {
return bookRepository.save(book);
}
}
@Service
public class ShelfService {
@Autowired
private ShelfRepository shelfRepository;
public List<Shelf> findAll() {
return shelfRepository.findAll();
}
public Book create(Book book) {
Shelf newShelf = shelfRepository.save(shelf);
shelf.setBooks();
return newShelf;
}
}
【问题讨论】:
标签: java json spring hibernate spring-data-jpa