2012-03-18 112 views
2

在基本的Hibernate 3.6.10實現中遇到問題。刪除一對多關係中的兒童

我有兩個類,時間表和事件。要完成一個活動的唯一方法是按計劃進行,所以我已經將模型與一個具有多個活動的時間表進行了一對多的關係。

這裏是時間表:

/** 
* 
*/ 
package com.heavyweightsoftware.leal.model.schedule; 

import java.util.Collection; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.NamedQueries; 
import javax.persistence.NamedQuery; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 

import com.heavyweightsoftware.leal.helper.DateHelper; 
import com.heavyweightsoftware.leal.model.Pojo; 

/** 
* A particular collection of events that can be shared 
* @author Thom 
*/ 
@Entity 
@Table(name = "SCHEDULE") 
@NamedQueries({ 
    @NamedQuery(name = Schedule.COUNT_SCHED_ID,  query = "SELECT COUNT(*) " + 
                   "FROM Schedule s " + 
                   "WHERE s.scheduleId = :scheduleId"), 
    @NamedQuery(name = Schedule.COUNT_SCHED_NAME, query = "SELECT COUNT(*) " + 
                   "FROM ScheduleRole r, Schedule s, SystemUser u " + 
                   "WHERE u.email = :email " + 
                   " AND u.id = r.systemUserId " + 
                   " AND r.scheduleId = s.id " + 
                   " AND s.name = :scheduleName "), 
    @NamedQuery(name = Schedule.QUERY_EVENTS_BY_USER, query = "SELECT r.roleType, s " + 
                   "FROM Schedule s, ScheduleRole r, SystemUser u " + 
                   "WHERE u.email = :email " + 
                   " AND u.id = r.systemUserId " + 
                   " AND r.scheduleId = s.id " + 
                   " ") 
    } 
) 
public class Schedule extends Pojo { 

    public static final int  LENGTH_SCHEDULE_ID  = 32; 
    public static final String  COUNT_SCHED_ID   = "countScheduleId"; 
    public static final String  COUNT_SCHED_NAME   = "countScheduleName"; 
    public static final String  QUERY_EVENTS_BY_USER  = "findEventsByUser"; 

    @Column(name = "ID", nullable=false) 
    @Id @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer  id; 

    @Column(name = "NAME", nullable=false) 
    private String  name; 

    @Column(name = "SCHEDULE_ID", nullable=false, unique=true, length=LENGTH_SCHEDULE_ID) 
    private String  scheduleId; 

    @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER) 
    private Collection<Event> events; 

    /* (non-Javadoc) 
    * @see com.heavyweightsoftware.leal.model.Pojo#toString() 
    */ 
    @Override 
    public String toString() { 
     StringBuilder sb = new StringBuilder(super.toString()); 
     sb.append('|'); 
     sb.append(getName()); 
     sb.append('|'); 
     sb.append(getScheduleId()); 
     return sb.toString(); 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = super.hashCode(); 
     result = prime * result + ((id == null) ? 0 : id.hashCode()); 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     result = prime * result 
       + ((scheduleId == null) ? 0 : scheduleId.hashCode()); 
     return result; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (!super.equals(obj)) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Schedule other = (Schedule) obj; 
     if (id == null) { 
      if (other.id != null) 
       return false; 
     } else if (!id.equals(other.id)) 
      return false; 
     if (name == null) { 
      if (other.name != null) 
       return false; 
     } else if (!name.equals(other.name)) 
      return false; 
     if (scheduleId == null) { 
      if (other.scheduleId != null) 
       return false; 
     } else if (!scheduleId.equals(other.scheduleId)) 
      return false; 
     return true; 
    } 

    /** 
    * @return the id 
    */ 
    public final Integer getId() { 
     return id; 
    } 

    /** 
    * @param id the id to set 
    */ 
    public final void setId(Integer id) { 
     this.id = id; 
    } 

    /** 
    * @return the name 
    */ 
    public final String getName() { 
     return name; 
    } 

    /** 
    * @param name the name to set 
    */ 
    public final void setName(String name) { 
     this.name = name; 
    } 

    /** 
    * @return 
    */ 
    public String getScheduleId() { 
     return scheduleId == null?scheduleId = DateHelper.getUniqueID():scheduleId; 
    } 

    /** 
    * @param scheduleId 
    */ 
    public void setScheduleId(String scheduleId) { 
     this.scheduleId = scheduleId; 
    } 

    /** 
    * @return the events 
    */ 
    public Collection<Event> getEvents() { 
     return events; 
    } 

    /** 
    * @param events the events to set 
    */ 
    public void setEvents(Collection<Event> events) { 
     this.events = events; 
    } 
} 

這裏是事件:除了刪除

/** 
* 
*/ 
package com.heavyweightsoftware.leal.model.schedule; 

import java.util.Calendar; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.ManyToOne; 
import javax.persistence.NamedQueries; 
import javax.persistence.Table; 
import javax.persistence.Temporal; 
import javax.persistence.TemporalType; 

import com.heavyweightsoftware.leal.model.Pojo; 

/** 
* A particular event entry in a calendar 
* @author Thom 
*/ 
@Entity 
@Table(name = "EVENT") 
@NamedQueries({ 
    } 
) 
public class Event extends Pojo { 

    /** 
    * Length of the randomly generated event ID 
    */ 
    private static final int   LENGTH_EVENT_ID    = 32; 

    @Column(name = "ID", nullable=false) 
    @Id @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer  id; 

    @Column(name = "START_TIME") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Calendar start; 

    @Column(name = "END_TIME") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Calendar end; 

    @Column(name = "EVENT_NAME", nullable=false) 
    private String  eventName; 

    @Column(name = "EVENT_ID", nullable=false, unique=true, length=LENGTH_EVENT_ID) 
    private String  eventId; 

    @ManyToOne(fetch=FetchType.EAGER) 
    private Schedule schedule; 

    @Column(name = "LOCATION") 
    private String  location; 

    /* (non-Javadoc) 
    * @see java.lang.Object#hashCode() 
    */ 
    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = super.hashCode(); 
     result = prime * result + ((end == null) ? 0 : end.hashCode()); 
     result = prime * result 
       + ((eventName == null) ? 0 : eventName.hashCode()); 
     result = prime * result + ((id == null) ? 0 : id.hashCode()); 
     result = prime * result 
       + ((location == null) ? 0 : location.hashCode()); 
     result = prime * result 
       + ((schedule == null) ? 0 : schedule.hashCode()); 
     result = prime * result + ((start == null) ? 0 : start.hashCode()); 
     return result; 
    } 

    /* (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (!super.equals(obj)) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Event other = (Event) obj; 
     if (end == null) { 
      if (other.end != null) 
       return false; 
     } else if (!end.equals(other.end)) 
      return false; 
     if (eventName == null) { 
      if (other.eventName != null) 
       return false; 
     } else if (!eventName.equals(other.eventName)) 
      return false; 
     if (id == null) { 
      if (other.id != null) 
       return false; 
     } else if (!id.equals(other.id)) 
      return false; 
     if (location == null) { 
      if (other.location != null) 
       return false; 
     } else if (!location.equals(other.location)) 
      return false; 
     if (schedule == null) { 
      if (other.schedule != null) 
       return false; 
     } else if (!schedule.equals(other.schedule)) 
      return false; 
     if (start == null) { 
      if (other.start != null) 
       return false; 
     } else if (!start.equals(other.start)) 
      return false; 
     return true; 
    } 

    /* (non-Javadoc) 
    * @see com.heavyweightsoftware.leal.model.Pojo#toString() 
    */ 
    @Override 
    public String toString() { 
     StringBuilder sb = new StringBuilder(super.toString()); 
     sb.append('|'); 
     sb.append(getEventName()); 
     sb.append('|'); 
     sb.append(getTimestamp(getStart())); 
     sb.append('-'); 
     sb.append(getTimestamp(getEnd())); 
     sb.append("|scheduleId="); 
     sb.append(getSchedule().toString()); 
     sb.append('|'); 
     sb.append(getLocation()); 
     return sb.toString(); 
    } 

    /** 
    * @return the id 
    */ 
    public final Integer getId() { 
     return id; 
    } 

    /** 
    * @param id the id to set 
    */ 
    public final void setId(Integer id) { 
     this.id = id; 
    } 

    /** 
    * The start date of the event in UTC 
    * @return the start 
    */ 
    public final Calendar getStart() { 
     return start; 
    } 

    /** 
    * The start date of the event in UTC 
    * @param start the start to set 
    */ 
    public final void setStart(Calendar start) { 
     this.start = start; 
    } 

    /** 
    * The end date of the event in UTC 
    * @return the end 
    */ 
    public final Calendar getEnd() { 
     return end; 
    } 

    /** 
    * The end date of the event in UTC 
    * @param end the end to set 
    */ 
    public final void setEnd(Calendar end) { 
     this.end = end; 
    } 

    /** 
    * @return the eventId 
    */ 
    public String getEventId() { 
     return eventId; 
    } 

    /** 
    * @param eventId the eventId to set 
    */ 
    public void setEventId(String eventId) { 
     this.eventId = eventId; 
    } 

    /** 
    * @return the eventName 
    */ 
    public final String getEventName() { 
     return eventName; 
    } 

    /** 
    * @param eventName the eventName to set 
    */ 
    public final void setEventName(String eventName) { 
     this.eventName = eventName; 
    } 

    /** 
    * @return the location 
    */ 
    public final String getLocation() { 
     return location; 
    } 

    /** 
    * @param location the location to set 
    */ 
    public final void setLocation(String location) { 
     this.location = location; 
    } 

    /** 
    * @return the schedule 
    */ 
    public Schedule getSchedule() { 
     return schedule; 
    } 

    /** 
    * @param schedule the schedule to set 
    */ 
    public void setSchedule(Schedule schedule) { 
     this.schedule = schedule; 
    } 
} 

一切工作正常。當我在春季實施我的DAO並嘗試刪除我的日程安排時,它會在事件中引發完整性約束。如果我首先嚐試刪除事件,它也不起作用。

getHibernateTemplate.delete(schedule); 

我該怎麼做?

我已閱讀Hibernate Delete Cascade但我不明白這是如何適用於我的情況。

這裏是我寫的刪除方法:

public void delete(Schedule sched) { 
    //grab the events 
    Collection<Event> events = sched.getEvents(); 
    //delete all children 
getHibernateTemplate().deleteAll(events); 
//flush the buffers 
    getHibernateTemplate().flush(); 
    //clear the collection 
    sched.getEvents().clear(); 
    //delete the schedule 
    super.delete(sched); 
} 

感謝。

回答

2

經過反覆試驗和研究,這裏就是我最終的目標。

@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval=true) 
private Collection<Event> events; 

然後事件:

@ManyToOne(fetch=FetchType.EAGER) 
private Schedule schedule; 

然後刪除方法。

public void delete(Schedule sched) 
     throws DataAccessException{ 
    //grab the events 
    Collection<Event> events = sched.getEvents(); 
    //clear the collection 
    events.clear(); 
    //flush the buffers 
    getHibernateTemplate().flush(); 
    //reload 
    sched = retrieve(sched); 
    //delete the schedule 
    super.delete(sched); 
} 

感謝您的幫助!

3

簡而言之,您試圖將刪除操作從父實體級聯到子級。這是一個非常普遍的問題。

這個問題提供你所尋求的答案: Hibernate Delete Cascade

此外,考慮增加ON DELETE CASCADE到您的數據庫架構,使其在你的DBMS這種行爲明確。

+0

感謝您的意見。以上評論。 – Thom 2012-03-18 22:33:40