2012-03-18 16 views
2

かなり基本的なHibernate 3.6.10実装に問題があります。1対多の関係で子を削除する

私は2つのクラス、スケジュールとイベントを持っています。イベントに行く唯一の方法はスケジュール通りなので、私は多くのイベントを持つスケジュールとの1対1の関係としてモデル化しました。ここで

は、スケジュールです:

/** 
* 
*/ 
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); 
} 

ありがとう:

は、ここで私が書いたdeleteメソッドです。

答えて

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

また、お使いのDBMSでこの動作を明示的にするために、データベース・スキーマにON DELETE CASCADEを追加することを検討してください。

+0

アドバイスありがとうございます。上記のコメント。 – Thom

関連する問題