2012-01-23 74 views
3

我在hibernate中有多对多的关系。 DB表是:hibernate中的多对多关系删除连接表数据?

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实施.equals和hashCode方法和Speaker.java

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

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

+2

问题是什么? – Pace

+0

一个事件可以有多个发言者,一个发言者可以有很多事件。 所以我不得不每次都在连接表中插入一个新行,它与新事件正常工作,但是如果我想向现有事件添加新的扬声器,行将从连接表中删除并插入新扬声器。 我想插入新行删除现有的联接表 –

回答

0

它在我看来像你的扬声器是平等的。我想探讨

event.getSpeakers().add(speaker2); 

我的猜测布尔返回值将是扬声器的ID是空的(对象仍然是短暂的)被检查的除了一套平等的时候。由于这个原因,使用生成的id进行平等是很危险的。

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

问题:对于多对多集合,加载单个实体时会冒着加载整个数据库的风险。如果你加载一个扬声器,它将获取所有扬声器的事件,而这又将获取所有这些事件的扬声器......扬声器。即使您将收藏标记为延迟加载,也会为使用这些收藏的人制作雷区。

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

+0

所以我怎么能做到这一点... –

相关问题