Spring Data Jpa Sping Boot @OneToMany关系我无法创建新数据

9lowa7mx  于 2023-11-19  发布在  Spring
关注(0)|答案(1)|浏览(174)

我正在做一个新的简单的抽认卡项目。总结:一个用户可以有多个抽认卡,所以用户和抽认卡之间的关系是oneToMany。当我尝试创建一个新的抽认卡时,我得到以下错误:

  1. 2023-08-27T09:03:14.399+02:00 WARN 31571 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Failure while trying to resolve exception [org.springframework.http.converter.HttpMessageNotWritableException]
  2. java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
  3. at org.apache.catalina.connector.ResponseFacade.checkCommitted(ResponseFacade.java:503) ~[tomcat-embed-core-10.1.11.jar:10.1.11]
  4. at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:347) ~[tomcat-embed-core-10.1.11.jar:10.1.11]
  5. .
  6. .
  7. .

字符串
我的Java类如下:
User.class:

  1. @Data
  2. @Entity
  3. public class User {
  4. @Id
  5. @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "userId_generator")
  6. private Integer id;
  7. private String username;
  8. private String firstName;
  9. private String lastName;
  10. private String password;
  11. @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
  12. private List<Flashcard> flashcards;
  13. @CreationTimestamp
  14. private Instant createdOn;
  15. @UpdateTimestamp
  16. private Instant updatedOn;
  17. }


Flashcard.class:

  1. @Entity
  2. @Data
  3. public class Flashcard {
  4. @Id
  5. @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "flashcardId_generator")
  6. private int id;
  7. private String name;
  8. private String description;
  9. @ManyToOne( fetch = FetchType.LAZY, optional = false)
  10. @JoinColumn(name = "user_id", nullable = false)
  11. @OnDelete(action = OnDeleteAction.CASCADE)
  12. private User user;
  13. }


FlashcardController.class:

  1. @RestController
  2. public class FlashcardController {
  3. @Autowired
  4. FlashcardRepository flashcardRepository;
  5. @Autowired
  6. UserRepository userRepository;
  7. ...some code with get method
  8. @PostMapping("/users/{id}/flashcards")
  9. public ResponseEntity<Flashcard> createFlashcard(@PathVariable("id") int userId, @RequestBody Flashcard flashcard) {
  10. Flashcard _flashcard = userRepository.findById(userId).map(user -> {
  11. flashcard.setUser(user);
  12. return flashcardRepository.save(flashcard);
  13. }).get();
  14. return new ResponseEntity<>(_flashcard, HttpStatus.CREATED);
  15. }
  16. }


当我删除

  1. @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
  2. private List<Flashcard> flashcards;


从User.class,我可以创建新的抽认卡。然而,当我发送一个带有userId的get请求时,我想看到所有属于他的抽认卡。

nfg76nw0

nfg76nw01#

在你的代码中有两个问题,我可以看到:
1.在控制器调用周围没有事务,因此,您试图持久化引用分离的UserFlashcard实体
1.关联的任何一端都没有标记为@JsonIgnore,所以JSON序列化失败,如果spring.jpa.open-in-viewtrue,则为StackOverflowError,否则为LazyInitializationException(这可能是核心问题,但我不能确定,因为根本原因没有包含在您提供的堆栈跟踪中)
一个简单的方法来做你想做的事情是:

  1. @Transactional
  2. @ResponseStatus(CREATED)
  3. @PostMapping("/users/{id}/flashcards")
  4. public Flashcard createFlashcard(@PathVariable("id") int userId, @RequestBody Flashcard flashcard) {
  5. flashcard.setUser(userRepository.getReferenceById(userId));
  6. return flashcardRepository.save(flashcard);
  7. }

字符串
加上

  1. @Data
  2. @Entity
  3. public class User {
  4. @JsonIgnore
  5. @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
  6. private List<Flashcard> flashcards;
  7. }


由于您将两边都标记为lazy,因此两边可能都需要@JsonIgnore
顺便说一句,Flashcard.user上的@OnDelete(action = OnDeleteAction.CASCADE)并没有真正的意义(它说的是'当用户的一个闪存卡被删除时,请删除整个用户',我很确定这不是你的意图)

展开查看全部

相关问题