Hibernate在SpringBoot中不能在同一个事务中持久化所有实体。

huangapple go评论121阅读模式
英文:

Hibernate in SpringBoot does not persist all Entities in same transaction

问题

我使用的是Hibernate版本5.4.22.Final,SpringBoot版本为2.3.5.RELEASE,并且使用以下代码:

控制器(CONTROLLER):

  1. @PostMapping("/insert/{id}")
  2. public MyReposneEntitiy insertAutoAndSendNotification(@PathVariable("id") int id, @Valid @RequestBody Auto auto) {
  3. MyReposneEntitiy e = service.insertAuto(auto, id);
  4. service.sendNotification(id);
  5. return e;
  6. }

服务(SERVICE):

  1. @Transactional
  2. public MyReposneEntitiy insertAuto(Auto auto, int id) {
  3. InfoForAuto info = infoRepo.findById(id).get();
  4. entityManager.detach(info);
  5. // 这个字段用@Version注解标记,
  6. // 如果实体在持久化上下文中,它不能被更改
  7. // 这就是为什么我首先要将其分离,然后再保存
  8. info.setVersion(auto.getVersion());
  9. infoRepo.save(info);
  10. Person person = personService.createPerson(auto.getPerson());
  11. Eng eng = engService.createEng(auto.getEng(), person.getId());
  12. info.setMSDNumber(auto.getMSDNumber());
  13. info.setStatus(Constants.OK);
  14. MyReposneEntitiy response = new MyReposneEntitiy ();
  15. response.setStatus(Constants.OK);
  16. return response;
  17. }
  18. public void sendNotification(int id){
  19. // 一些代码...
  20. }

被调用的服务方法(CALLED SERVICE METHOD):

  1. @Transactional
  2. public PersonResponse createPerson(PersonInput pesronInput) {...}
  3. @Transactional
  4. public EngResponse createEng(EngInput engInput, Integer personId) {...}

现在的问题是,当insertAuto()方法结束并且我处于sendNotification()方法的第一行(在调试模式下),我检查数据库发现,“person”和“eng”已经在数据库中创建,但“info”实体没有被更新。但我需要在调用sendNotification方法之前更新它,我无法弄清楚为什么?它们不都在同一个事务中吗?Hibernate应该要么保存所有实体,要么不保存任何实体吧?

英文:

I'm using Hibernate version 5.4.22.Final, with SpringBoot 2.3.5.RELEASE, and using this code:

CONTROLLER:

  1. @PostMapping("/insert/{id}")
  2. public MyReposneEntitiy insertAutoAndSendNotification(@PathVariable("id") int id, @Valid @RequestBody Auto auto) {
  3. MyReposneEntitiy e = service.insertAuto(auto, id);
  4. service.sendNotification(id);
  5. return e;
  6. }

SERVICE:

  1. @Transactional
  2. public MyReposneEntitiy insertAuto(Auto auto, int id) {
  3. InfoForAuto info = infoRepo.findById(id).get();
  4. entityManager.detach(info);
  5. //this is annotated with @Version,
  6. //and it can not be changed if the entity is in Persistence Contexxt
  7. //that's why I'm detaching first and then save
  8. info.setVersion(auto.getVersion());
  9. infoRepo.save(info);
  10. Person person = personService.createPerson(auto.getPerson());
  11. Eng eng = engService.createEng(auto.getEng(), person.getId());
  12. info.setMSDNumber(auto.getMSDNumber());
  13. info.setStatus(Constants.OK);
  14. MyReposneEntitiy response = new MyReposneEntitiy ();
  15. response.setStatus(Constants.OK);
  16. return response;
  17. }
  18. public void sendNotification(int id){
  19. //some code...
  20. }

CALLED SERVICE METHOD:

  1. @Transactional
  2. public PersonResponse createPerson(PersonInput pesronInput) {...}
  3. @Transactional
  4. public EngResponse createEng(EngInput engInput, Integer personId) {...}

Now, the problem is, when insertAuto() method ends, and I'm in the first line in sendNotification() method (in debugging mode) I check the database and the "person" and "eng" are created in the database but the info entity is not updated, but I need it to be updated before I call sendNotification method, and I cant figure out why? Aren't they in the same transaction, and hibernate should either save all entities or save none?

答案1

得分: 1

当我调用 "infoRepo.save(info);" 时,save() 方法作为返回对象具有在Persistence Context中持久化的实体,所以我只需要执行 info = infoRepo.save(info);,现在它按预期工作。

英文:

OK, so I found what the problem was.

When I call "infoRepo.save(info);" the save() method as a return object have the entity that is persisted in Pestistence Context, so all I had to do is info = infoRepo.save(info); and now it works as it should.

huangapple
  • 本文由 发表于 2023年7月17日 16:45:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76702787.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定