如何在java spring boot(jpa hibernate)中保存(分离的)对象的关系

bsxbgnwa  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(579)

我想用特定的元素保存两个或更多人之间的关系。一个人用它的技能和一个特定的地址应该互相联系。通常我创建一个表来保存每个元素的id,并在表中创建一行(在普通mysql和php中)。
如何在javaspringboot(jpa-hibernate-mysql)中解决这个问题?
当我从每个元素的存储库中创建(或者更好地请求)一个“对象”(分离)并希望将其保存在一个新的“存储库”(数据库)中时,就出现了一个错误。
PartnerConnectionService实现(.java)

  1. @Service
  2. public class PartnerConnectionServiceImpl implements PartnerConnectionService {
  3. @Autowired
  4. private PartnerConnectionRepository partnerConnectionRepository;
  5. @Autowired
  6. private DanceSkillServiceImpl danceSkillDatabaseService;
  7. @Autowired
  8. private AddressLocationServiceImpl addressLocationDatabaseService;
  9. @Autowired
  10. private UserProfileServiceImpl userProfileDatabaseService;
  11. @Override
  12. public Optional<PartnerConnection> connectPartnersWithDanceSkillAndAddressLocation(long userIdPartner1, long danceSkillIdPartner1, long addressLocationIdPartner1, long userIdPartner2, long danceSkillIdPartner2, long addressLocationIdPartner2) {
  13. Optional<UserProfile> userProfile1 = this.userProfileDatabaseService.getUserById(userIdPartner1);
  14. Optional<UserProfile> userProfile2 = this.userProfileDatabaseService.getUserById(userIdPartner2);
  15. Optional<DanceSkill> danceSkill1 = this.danceSkillDatabaseService.getDanceSkillById(danceSkillIdPartner1);
  16. Optional<DanceSkill> danceSkill2 = this.danceSkillDatabaseService.getDanceSkillById(danceSkillIdPartner2);
  17. Optional<AddressLocation> addressLocation1 = this.addressLocationDatabaseService.getAddressLocationById(addressLocationIdPartner1);
  18. Optional<AddressLocation> addressLocation2 = this.addressLocationDatabaseService.getAddressLocationById(addressLocationIdPartner2);
  19. if (
  20. (userProfile1.isPresent()) && (userProfile2.isPresent())
  21. ){
  22. Optional<PartnerConnection> theConnection = getPartnerConnectionOfPartners(
  23. userProfile1.get(),
  24. userProfile2.get());
  25. if (theConnection.isPresent()) {
  26. return theConnection;
  27. }
  28. }
  29. if (
  30. (userProfile1.isPresent()) && (userProfile2.isPresent()) &&
  31. (danceSkill1.isPresent()) && (danceSkill2.isPresent()) &&
  32. (addressLocation1.isPresent()) && (addressLocation2.isPresent())
  33. ) {
  34. PartnerConnection newPartnerConnection = new PartnerConnection(
  35. null,
  36. userProfile1.get(),
  37. danceSkill1.get(),
  38. addressLocation1.get(),
  39. userProfile2.get(),
  40. danceSkill2.get(),
  41. addressLocation2.get()
  42. );
  43. this.partnerConnectionRepository.save(newPartnerConnection);
  44. return Optional.of(newPartnerConnection);
  45. }
  46. return Optional.empty();
  47. }
  48. ...

partnerconnection(.java)

  1. // indicates the connecitons between partners/ users
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. @Data
  5. @Entity
  6. @Table(name = "partner_connection")
  7. public class PartnerConnection {
  8. @Id
  9. @GeneratedValue(strategy = GenerationType.IDENTITY)
  10. private long id;
  11. @OneToOne(
  12. fetch = FetchType.LAZY,
  13. cascade = CascadeType.ALL
  14. )
  15. @JoinColumn(
  16. name = "firstmessage_fk", // foreign key
  17. nullable = true
  18. )
  19. private UserMessage firstMessage;
  20. @ManyToOne(
  21. fetch = FetchType.LAZY,
  22. cascade = CascadeType.ALL
  23. )
  24. @JoinColumn(name = "onepartner_fk", // foreign key
  25. nullable = false)
  26. private UserProfile firstPartner;
  27. @OneToOne(
  28. fetch = FetchType.LAZY,
  29. cascade = CascadeType.ALL
  30. )
  31. @JoinColumn(
  32. name = "firstpartnerdanceskill_fk", // foreign key
  33. nullable = false
  34. )
  35. private DanceSkill firstPartnerDanceSkill;
  36. @OneToOne(fetch = FetchType.LAZY,
  37. cascade = CascadeType.ALL)
  38. @JoinColumn(name = "firstpartneraddresslocation_fk", // foreign key
  39. nullable = false)
  40. private AddressLocation firstPartnerAddressLocation;
  41. @ManyToOne(fetch = FetchType.LAZY,
  42. cascade = CascadeType.ALL)
  43. @JoinColumn(name = "secondpartner_fk", // foreign key
  44. nullable = false)
  45. private UserProfile secondPartner;
  46. @OneToOne(fetch = FetchType.LAZY,
  47. cascade = CascadeType.ALL)
  48. @JoinColumn(name = "secondpartnerdanceskill_fk", // foreign key
  49. nullable = false)
  50. private DanceSkill secondPartnerDanceSkill;
  51. @OneToOne(fetch = FetchType.LAZY,
  52. cascade = CascadeType.ALL)
  53. @JoinColumn(name = "secondpartneraddresslocation_fk", // foreign key
  54. nullable = false)
  55. private AddressLocation secondPartnerAddressLocation;
  56. public PartnerConnection(UserMessage firstMessage, UserProfile firstPartner, DanceSkill firstPartnerDanceSkill, AddressLocation firstPartnerAddressLocation, UserProfile secondPartner, DanceSkill secondPartnerDanceSkill, AddressLocation secondPartnerAddressLocation) {
  57. this.firstMessage = firstMessage;
  58. this.firstPartner = firstPartner;
  59. this.firstPartnerDanceSkill = firstPartnerDanceSkill;
  60. this.firstPartnerAddressLocation = firstPartnerAddressLocation;
  61. this.secondPartner = secondPartner;
  62. this.secondPartnerDanceSkill = secondPartnerDanceSkill;
  63. this.secondPartnerAddressLocation = secondPartnerAddressLocation;
  64. }
  65. }

错误 org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: ... nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: ... 出现在 this.partnerConnectionRepository.save(newPartnerConnection); 你有什么简单易懂的建议吗?

00jrzges

00jrzges1#

我认为你的方法应该包含@transactional注解。您已经将所有关系都标记为惰性,因此如果要获取它们,需要一个事务将它们从分离的关系加载到托管状态,然后可以将其附加到要保存的对象

相关问题