我有一个Book实体和Author实体,它们之间有多对多的关系。我有一本书是这样的:(作者A在数据库中的id=1,我使用@GeneratedValue(策略= GenerationType.IDENTITY),所以我不想添加id)
{
"id": 1,
"name": "Spring Boot 1"
"authors": [
{
"name": "A"
}
]
}
然后我再创作一本这样的书
{
"id": 2,
"name": "Spring Boot 2"
"authors": [
{
"name": "A"
},
{
"name": "B"
}
]
}
问题是Spring JPA将在数据库中创建另一个id=2的作者“A”和id=3的作者“B”。
我想要的是JPA使用现有作者“A”并创建一个作者“B”,id = 2。
书本
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@Column
private double price;
@ManyToMany(
cascade = CascadeType.ALL,
fetch = FetchType.LAZY
)
@JoinTable(
name = "book_author",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "author_id")
)
@JsonIgnoreProperties("books")
private List<Author> authors = new ArrayList<>();
}
图书服务
@Service
public class BookService {
@Autowired
BookRepository bookRepository;
public List<Book> getAllBook() {
return bookRepository.findAll();
}
public Book saveBook (Book book) {
return bookRepository.save(book);
}
public void deleteBook(Long id) {
bookRepository.deleteBookById(id);
}
}
图书管理员
@RestController
@RequestMapping("/book")
public class BookController {
@Autowired
BookService bookService;
@GetMapping
public ResponseEntity<List<Book>> getAllBook() {
return new ResponseEntity<List<Book>>(bookService.getAllBook(), HttpStatus.OK);
}
@PostMapping
public ResponseEntity<Book> saveBook(@RequestBody Book book) {
return new ResponseEntity<Book>(bookService.saveBook(book), HttpStatus.CREATED);
}
}
作者
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "author")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@ManyToMany(mappedBy = "authors", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JsonIgnoreProperties("authors")
private List<Book> books = new ArrayList<>();
}
AuthorService和AuthorController类似于书本
是否有任何注解或查询可用于修复此问题??或者最有效的方法是什么?
我不想使用下面的解决方案,因为我认为JPA中有一个解决方案比这个更短、更高效,但我不知道
我使用ChatGPT演示了此方法
public ResponseEntity<Book> createBook(@RequestBody Book book) {
for (Author author : book.getAuthors()) {
Optional<Author> existingAuthor = authorRepository.findOne(
Example.of(author, ExampleMatcher.matching().withIgnorePaths("id"))
);
if (existingAuthor.isPresent()) {
book.addAuthor(existingAuthor.get());
}
}
Book savedBook = bookService.save(book);
return ResponseEntity.created(URI.create("/books/" + savedBook.getId())).body(savedBook);
}
1条答案
按热度按时间gz5pxeao1#
JPA如何知道是否有两个作者同名?它不能。
如果你想“重用”一个现有的作者,那么你必须自己找到并设置它。
一个小提示,不要将数据库模型中的类用于DTO。