2012-03-19 11 views
3

これは、私が私の関係を管理するためにHibernateを使用しなくなった理由です。新しい灰色の毛が多すぎます。外部キーの親エラーなし

休止3.6.10

OK、私は2つのクラス、スケジュールやイベントを持っています。スケジュールには多くのイベントがありますが、イベントには1つのスケジュールしかありません。

スケジュール:

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

import java.util.ArrayList; 
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.JoinColumn; 
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, orphanRemoval=true) 
    @JoinColumn(name="ID") 
    private Collection<Event> events; 

    /** 
    * Copy all members from one to the other 
    * @param from the from 
    * @param to the to 
    * @param copySubMembers if true, copy sub members like entity 
    */ 
    public static void copy(Schedule from, Schedule to, boolean copySubMembers){ 
     to.setId(from.getId()); 
     to.setName(from.getName()); 
     to.setScheduleId(from.getScheduleId()); 
     if(copySubMembers){ 
      to.setEvents(from.getEvents()); 
     } 
    } 

    /** 
    * no-arg constructor 
    */ 
    public Schedule() { 
    } 

    /** 
    * copy constructor 
    */ 
    public Schedule(Schedule schedule) { 
     copy(schedule, this, true); 
    } 

    /* (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()); 
     sb.append('|'); 
     sb.append(getEvents()); 
     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==null?events = new ArrayList<>():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.JoinColumn; 
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) 
    @JoinColumn(name="SCHEDULE_ID") 
    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(); 
     sb.append(super.toString()); 
     sb.append('|'); 
     sb.append(getEventName()); 
     sb.append('|'); 
     sb.append(getTimestamp(getStart())); 
     sb.append('-'); 
     sb.append(getTimestamp(getEnd())); 
     sb.append("|scheduleId="); 
     Schedule schedule = getSchedule(); 
     sb.append(schedule==null?"null":schedule.getId()); 
     sb.append('|'); 
     sb.append(getLocation()); 
     sb.append('|'); 
     sb.append(getEventId()); 
     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; 
    } 
} 

は今、私は例外を取得してい時点で、私はスケジュールを作成した後、スケジュールに4つのイベントを追加し、更新を呼び出しています私のスケジュールDAOでイベントを保存してください。私の現在のコードは次のとおりです:

public Schedule update(Schedule schedule) { 
    //first save the events 
    for(Event event:schedule.getEvents()){ 
     getHibernateTemplate().saveOrUpdate(event); //<-Fails here 
    } 
    Schedule schedule2 = getHibernateTemplate().get(Schedule.class, schedule.getId()); 
    Schedule.copy(schedule, schedule2, false); 
    System.err.println(schedule2.toString()); 
    getHibernateTemplate().saveOrUpdate(schedule2); 
    return retrieveById(schedule2.getId()); 
} 

私のイベントのすべてのフィールドには、自動生成されたID以外のデータが入力されています。ここに例外があります:

org.springframework.dao.DataIntegrityViolationException: could not insert: [com.heavyweightsoftware.leal.model.schedule.Event]; SQL [insert into EVENT (ID, END_TIME, EVENT_ID, EVENT_NAME, LOCATION, SCHEDULE_ID, START_TIME) values (default, ?, ?, ?, ?, ?, ?)]; constraint [FK3F47A7AA91E64F]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [com.heavyweightsoftware.leal.model.schedule.Event] 
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:637) 
    at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412) 
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411) 
    at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) 
    at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:737) 
    at com.heavyweightsoftware.leal.dao.hibernate.schedule.ScheduleHibernateDAO.update(ScheduleHibernateDAO.java:71) 
    at com.heavyweightsoftware.leal.dao.hibernate.schedule.ScheduleHibernateDAO.update(ScheduleHibernateDAO.java:1) 
    at com.heavyweightsoftware.leal.service.calendar.impl.CalendarServiceImpl.update(CalendarServiceImpl.java:168) 
    at com.heavyweightsoftware.leal.service.calendar.impl.CalendarServiceImplTest.testGetCalendars(CalendarServiceImplTest.java:230) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [com.heavyweightsoftware.leal.model.schedule.Event] 
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96) 
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) 
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:63) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2346) 
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2853) 
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71) 
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) 
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:320) 
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203) 
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129) 
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210) 
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195) 
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117) 
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93) 
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685) 
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677) 
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673) 
    at org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:740) 
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406) 
    ... 30 more 
Caused by: java.sql.SQLException: integrity constraint violation: foreign key no parent; FK3F47A7AA91E64F table: EVENT 
    at org.hsqldb.jdbc.Util.sqlException(Util.java:215) 
    at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(JDBCPreparedStatement.java:4617) 
    at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(JDBCPreparedStatement.java:308) 
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:93) 
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:56) 
    ... 46 more 
Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no parent; FK3F47A7AA91E64F table: EVENT 
    at org.hsqldb.error.Error.error(Error.java:131) 
    at org.hsqldb.Constraint.getException(Constraint.java:898) 
    at org.hsqldb.Constraint.checkInsert(Constraint.java:816) 
    at org.hsqldb.StatementDML.performIntegrityChecks(StatementDML.java:1318) 
    at org.hsqldb.StatementDML.insertRowSet(StatementDML.java:795) 
    at org.hsqldb.StatementInsert.getResult(StatementInsert.java:139) 
    at org.hsqldb.StatementDMQL.execute(StatementDMQL.java:190) 
    at org.hsqldb.Session.executeCompiledStatement(Session.java:1294) 
    at org.hsqldb.Session.execute(Session.java:956) 
    at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(JDBCPreparedStatement.java:4609) 
    ... 49 more 

ありがとう!レキシントンの悲嘆 :)

答えて

7

あなたの問題は、その方向には外部キー関係が存在しないときに、あなたのEventエンティティにごScheduleエンティティから結合を実行しようとしているということです。上記のコードでは

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

あなたはスケジュールのid列がEventから主キーと一致するすべてのイベントを取得するためにあなたのJPAプロバイダを指示しています。私はこれがあなたが意図したものではないと確信しています。あなたはEventマッピングを定義し、Scheduleからということを参照できるようにする必要があります。

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

また、エンティティに複数のアソシエーション(袋)を格納する際、Hibernateは、既知の問題を持っているので、私は、あなたのコレクションを格納するSetsを使用することをお勧めしますあなたがしなければ。

関連する問題