【问题标题】:Many to many relationship in hibernate deleting the join table data?休眠中的多对多关系删除连接表数据?
【发布时间】:2012-02-17 03:55:07
【问题描述】:

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

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

event.hbm.xml

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

speaker.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 方法

Event.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;
}

Speaker.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: 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 (?, ?)

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

【问题讨论】:

  • 一个活动可以有多个演讲者,一个演讲者可以有多个活动。所以我每次都必须在连接表中插入一个新行,它可以很好地处理新事件,但是如果我想向现有事件添加新的发言者,行将从加入表中删除并插入新的发言者。我想插入新行而不删除连接表中的现有行
  • 你解决了@RameshKotha 的问题吗?

标签: java hibernate many-to-many hibernate-mapping


【解决方案1】:

在我看来,您的扬声器是平等的。我会调查

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

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

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

关注点:对于多对多集合,您在加载单个实体时冒着加载整个数据库的风险。如果您加载一个扬声器,它将获取该扬声器的所有事件,进而获取所有这些事件的扬声器......哎呀。即使您将集合标记为延迟加载,也会为使用它们的人设置雷区。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 2015-12-22
    相关资源
    最近更新 更多