连接表记录正在被删除和创建(ORM)

时间:2019-08-23 18:52:51

标签: java hibernate spring-data-jpa jointable

我在休眠状态下与联接表中的额外列有许多关系。当我保存主实体而不影响两个表(联接表)之间的关系时,将删除并创建联接表中的记录,而不是对其进行更新。怎知道如何避免这种情况?

我知道可以使用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);

对于在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)

如何避免这种情况?我将不胜感激。

1 个答案:

答案 0 :(得分:0)

如您所说,将列表更改为设置将解决此问题。

要实现此目的,只需将private List<ApplicationOpening> openings;更改为private Set<ApplicationOpening> openings;,而无需其他更改。

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

请参阅此article,以获取更多信息。