clé étrangère aucun parent d'erreur

C'est vraiment pourquoi j'ai quitté l'utilisation d'Hibernate pour gérer mes relations pour moi. Trop de poils gris.

Hibernate 3.6.10

OK, j'ai deux classes, de la Planification et de l'Événement. L'annexe a de nombreux événements, mais un événement a qu'un seul programme.

Horaire:

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

Événement:

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

Maintenant au point où j'en suis de l'exception, j'ai créé un calendrier et ensuite ajouté 4 épreuves à l'horaire et je suis d'appel de mise à jour sur mon calendrier de DAO pour enregistrer les événements. Voici mon code actuel:

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());
}

Tous les champs de mon événement sont peuplées à l'exception de l'IDENTIFIANT est généré automatiquement. Voici l'exception:

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

Merci!
Le cœur brisé à Lexington:)

OriginalL'auteur Thom | 2012-03-19