java [Spring][JPA] ManyToMany时自动保存

ctehm74n  于 2024-01-05  发布在  Java
关注(0)|答案(1)|浏览(180)

我有两个Oracle表INDEXUSER,它们之间有关系表INDEX_USER(INDEX_ID NUMBER(8), USER_ID NUMBER(8), IN_CHARGE NUMBER(1), BACKUP NUMBER(1))
我在Java代码中这样表示INDEX表:

  1. @Entity
  2. @Data
  3. public class Index {
  4. //others attributs
  5. @ManyToMany(fetch = FetchType.EAGER)
  6. @JoinTable(name="INDEX_USER", joinColumns = @JoinColumn(name="INDEX_ID"), joinColumns = @JoinColumn(name="USER_ID"))
  7. @WhereJoinTable(clause = "IN_CHARGE = 1")
  8. private Set<User> inCharges;
  9. @ManyToMany(fetch = FetchType.EAGER)
  10. @JoinTable(name="INDEX_USER", joinColumns = @JoinColumn(name="INDEX_ID"), joinColumns = @JoinColumn(name="USER_ID"))
  11. @WhereJoinTable(clause = "BACKUP = 1")
  12. private Set<User> backups;
  13. }

字符串
注意:B:INDEX_ID和USER_ID是关系表的主键
当我尝试用repository.save(index); spring保存一个新的Index时,我也尝试在关系表中保存我的Set,但我不想这样。
因为:

  • 它存储它们,而不带IN_CHARGE & PACKUP标志
  • 我可以有相同的用户负责和备份的索引,所以它的创建一个主键违规

我试着添加CascadeType.MERGE,但没有为我工作。
我不想使用@OneToMany关系并为我的关系表创建实体。我发现这样对我来说更清楚。

**编辑:**根据@kaqqao的提议,我修改了代码,使其具有@OneToMany关系:

  1. public class IndexUser {
  2. @EmbeddedId
  3. private IndexUserPK id;
  4. @Basic
  5. @Column(name = "IN_CHARGE")
  6. private Boolean inCharge;
  7. @Basic
  8. @Column(name = "BACK_UP")
  9. private Boolean backUp;
  10. @ManyToOne(fetch = FetchType.LAZY)
  11. @JoinColumn(name = "INDEX_ID", referencedColumnName = "ID", insertable = false, updatable = false)
  12. private Index index;
  13. @ManyToOne(fetch = FetchType.LAZY)
  14. @JoinColumn(name = "USER_ID", referencedColumnName = "ID", insertable = false, updatable = false)
  15. private User user;
  16. }


在我的Index类中添加一个新方法:

  1. public void addUser(User user, boolean inCharge, boolean backup){
  2. IndexUserPK pk = new IndexUserPK(user.getId(), this.getId());
  3. IndexUser indexUser= new IndexUser(pk, inCharge, backup, this, user);
  4. this.getIndexUsers().add(indexUser);
  5. }


但是,当我尝试使用IndexUser对象列表保存新Index时,会出现此异常:

  1. Caused by: oracle.jdbc.OracleDatabaseException: ORA-02291: violation de contrainte d'intégrité (SCHEMA.PK_INDEX_USER_FK) - clé parent introuvable


如果有人有任何关于如何解决这个问题的想法。谢谢

ve7v8dk2

ve7v8dk21#

如果关系表中的列不是外键(它是一个聚合),那么它应该被建模为一个实体本身。在您的情况下,这意味着引入一个实体,如:

  1. @Entity
  2. plublic class IndexUser {
  3. @EmbeddedId
  4. IndexUserId id;
  5. @ManyToOne
  6. @MapsId("indexId")
  7. Index index;
  8. @ManyToOne
  9. @MapsId("userId")
  10. User user;
  11. @Column
  12. boolean backup;
  13. @Column(name = "in_charge")
  14. boolean inCharge;
  15. ...
  16. }
  17. @Embeddable
  18. public class IndexUserId
  19. implements Serializable {
  20. @Column(name = "index_id")
  21. Long indexId;
  22. @Column(name = "user_id")
  23. Long userId;
  24. ...
  25. }

字符串
然后从UserIndex实体到IndexUser具有@OneToMany关系。

  1. @Entity
  2. public class Index {
  3. ...
  4. @OneToMany(mappedBy = "index")
  5. @WhereJoinTable(clause = "...")
  6. Set<IndexUser> backups;
  7. ...
  8. }


查看此帖子以获取更多信息:https://vladmihalcea.com/the-best-way-to-map-a-many-to-many-association-with-extra-columns-when-using-jpa-and-hibernate/
或者this one,如果你觉得弗拉德的经典文章有点多的话。
但是,如果你最终发现所有的JPA(和ORM)有点多,看看这个:https://blog.jooq.org/the-second-best-way-to-fetch-a-spring-data-jpa-dto-projection/。我希望你能像我一样大开眼界。

展开查看全部

相关问题