gpt4 book ai didi

java - hibernate 中删除连接表数据的多对多关系?

转载 作者:行者123 更新时间:2023-12-03 20:21:13 26 4
gpt4 key购买 nike

我在 hibernate 中有很多对多的关系。数据库表是:

events(event_id,name)
speaker(speaker_id,name)
event_speaker(event_id,speaker_id)

事件.hbm.xml

<set name="speakers" table="event_speakers" cascade="save-update">
<key column="event_id"/>
<many-to-many class="com.manytomany.model.Speaker"/>
</set>

扬声器.hbm.xml

<set name="events" table="event_speakers" cascade="save-update">
<key column="speaker_id"/>
<many-to-many class="com.manytomany.model.Event"/>
</set>

我已经在 Event.java 和 Speaker.java 中实现了 .equals 和 hashcode 方法

事件.java

@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
Event event = (Event)obj;
return this.id == event.id;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return (int)id;
}

扬声器.java

@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
Speaker speaker = (Speaker)obj;
return this.id == speaker.id;
}

@Override
public int hashCode() {
// TODO Auto-generated method stub
return (int)id;
}

这是我的逻辑

        session.beginTransaction();
Event event = (Event) session.createCriteria(Event.class).add(Restrictions.eq("id", 1L)).uniqueResult();
event.setSpeakers(new HashSet());
Speaker speaker = new Speaker();
speaker.setName("11");
Speaker speaker2 = new Speaker();
speaker2.setName("12");

event.getSpeakers().add(speaker);
event.getSpeakers().add(speaker2);
session.save(event);
session.getTransaction().commit();

当我运行上面的代码时,hibernate 是这样执行的

Hibernate: select this_.event_id as event1_0_0_, this_.event_name as event2_0_0_ from events this_ where this_.event_id=?
Hibernate: select max(speaker_id) from speakers
Hibernate: insert into speakers (speaker_name, speaker_id) values (?, ?)
Hibernate: delete from event_speakers where event_id=?
Hibernate: insert into event_speakers (event_id, elt) values (?, ?)

为什么要从连接表中删除,我想插入新行而不是在连接表中删除。

最佳答案

在我看来你们的扬声器是平等的。我会调查

的 boolean 返回值
event.getSpeakers().add(speaker2);

我的猜测是,在添加到集合中检查是否相等时,您的扬声器的 id 为空(对象仍然是 transient 的)。出于这个原因,使用生成的 id 来实现平等是危险的。

一个解决方法:去掉 Event 和 Speaker 上的 equals() 和 hashcode() 方法。

问题:对于多对多集合,加载单个实体时可能会加载整个数据库。如果您加载一个 Speaker,它将获取所有该 Speaker 的 Events,而这又将获取所有这些 Event 的 Speakers……哎呀。即使您将集合标记为延迟加载,也会为使用它们的人制造雷区。

另一种方法:您可以使用组合并围绕 event_speaker 表创建一个 EventSpeaker 实体。然后,您将创建 DAO 和服务层,为您提供所需的方法,例如获取演讲者所有事件的能力,反之亦然。如果证明有必要,它还允许您添加 SpeakerEvent 组合独有的属性。

关于java - hibernate 中删除连接表数据的多对多关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8977745/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com