【问题标题】:Join Table records are being deleted and created (ORM)正在删除和创建联接表记录 (ORM)
【发布时间】:2019-08-23 18:52:51
【问题描述】:

我在休眠中有一个多对多关系,连接表中有额外的列。当我保存主实体而不影响两个表(连接表)之间的关系时,连接表中的记录被删除并创建而不是更新。多么想知道如何避免这种情况?

我知道这个问题可以通过使用 Set 集合而不是 List 在 @ManyToMany 关系中解决。不知道如何在这里实现。

我的桌子是

APPLICATIONS
  ID                  NUMBER NOT NULL,
  USER_ID             NUMBER(1),
  STATUS              VARCHAR2(10)

APPLICATION_OPENINGS
  ID                  NUMBER NOT NULL,
  OPENING_ID          NUMBER NOT NULL,
  APPLICATION_ID      NUMBER NOT NULL,
  PRIORITY            NUMBER NOT NULL

OPENINGS
  ID                  NUMBER NOT NULL,
  NAME                VARCHAR2(512) NOT NULL,
  LOCATION_ID         NUMBER

我的实体关系定义为

Application.java

@OneToMany(fetch = FetchType.LAZY,cascade = {CascadeType.ALL}, mappedBy = "application")
    private List<ApplicationOpening> openings;

ApplicationOpening.java

    @ManyToOne
    @JoinColumn(name = "APPLICATION_ID")
    private Application application;

    @ManyToOne
    @JoinColumn(name="OPENING_ID")
    private Opening opening;

Opening.java

    No reference to the Join Entity ApplicationOpening

DAO 服务

    applicationDAO.save(application);

对于在应用程序 DAO 上执行保存而不修改任何内容的情况,例如(因此对关系没有影响),连接表 APPLICATION_OPENING 中的记录将被删除并再次创建,如下所示。

delete from APPLICATION_OPENINGS where id=?|delete from APPLICATION_OPENINGS where id=388
delete from APPLICATION_OPENINGS where id=?|delete from APPLICATION_OPENINGS where id=387

insert into APPLICATION_OPENINGS (APPLICATION_ID, PRIORITY, OPENING_ID, id) values (55, 1, 28, 412)
insert into APPLICATION_OPENINGS (APPLICATION_ID, PRIORITY, OPENING_ID, id) values (55, 2, 26, 413)

我怎样才能避免这种情况?非常感谢您的帮助。

【问题讨论】:

    标签: java hibernate spring-data-jpa jointable


    【解决方案1】:

    正如你所说,将列表更改为 set 将解决此问题。

    为了实现这一点,只需将private List&lt;ApplicationOpening&gt; openings; 更改为private Set&lt;ApplicationOpening&gt; openings;,无需进行其他更改。

    这背后的原因是,如果我们在 hibernate 中使用 List 作为映射属性而没有索引列,则 hibernate 将其视为 Bag。由于 Hibernate 将 List 处理为 Bag(具有非唯一值的无序集合。bag 的最大特点是可以通过 API 获取对象的出现次数) 有了列表,没有迭代就没有办法做到这一点通过整个列表。)只要我们在这个集合中删除和添加一个元素。 Hibernate 发出一条 SQL,首先从连接表中删除所有不应该删除的元素,然后从 Bag 中重新插入所有元素。

    请参阅此article 了解更多信息。

    【讨论】:

    • 感谢 Alien,当您说“休眠中没有索引的映射属性”时,您是什么意思。在我的情况下,连接表实体有自己的 Id 映射(见下文)。 ` @Id @SequenceGenerator(name = "OPENING_ID_GEN", sequenceName = "SQ_CFC_VACANCIES", allocationSize = 1) @GeneratedValue(strategy = SEQUENCE, generator = "OPENING_ID_GEN") private Long id;`
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多