我在休眠状态下与联接表中的额外列有许多关系。当我保存主实体而不影响两个表(联接表)之间的关系时,将删除并创建联接表中的记录,而不是对其进行更新。怎知道如何避免这种情况?
我知道可以使用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)
如何避免这种情况?我将不胜感激。
答案 0 :(得分:0)
如您所说,将列表更改为设置将解决此问题。
要实现此目的,只需将private List<ApplicationOpening> openings;
更改为private Set<ApplicationOpening> openings;
,而无需其他更改。
这背后的原因是,如果我们在休眠中使用List作为没有索引列的映射属性,则休眠会将其视为Bag。由于Hibernate将列表作为袋处理(具有非唯一值的无序集合。袋的最佳功能是您可以通过API使用列表获取对象的出现次数,因此,如果没有迭代,就无法做到这一点。整个列表中。),只要我们在此集合中删除并添加元素即可。 Hibernate发出了一条SQL,该SQL首先从联接表中删除所有不应删除的元素,然后从Bag中重新插入所有元素。
请参阅此article,以获取更多信息。