Hi,
I have a class named ScheduledCourse, it contains a collection of Enroll objects. The Enroll class represents a Join Table in the database but is also a Java entity class. I used the example as presented in the book Java Persistence with Hibernate Chapter 7 page 304, regarding "Mapping the join table to an intermediate entity".
I'm trying to test the deletion of an instance of ScheduledCourse which also includes this collection of Enroll objects, like so:
Code:
@Entity
@Table(name = "SCHEDULED_COURSES")
public class ScheduledCourse implements Serializable
{
...
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, mappedBy="scheduled_course")
//@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@org.hibernate.annotations.CollectionOfElements
@JoinTable(name = "ENROLL", joinColumns = @JoinColumn(name = "ENROLL_ID"))
private Collection<Enroll> ENROLLED = new ArrayList<Enroll>();
...
}
The Student class has the same at its end:
Code:
@Entity
@Table(name = "STUDENTS")
public class Student extends User implements Serializable
{
...
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, mappedBy="student")
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@org.hibernate.annotations.CollectionOfElements
private Collection<Enroll> ENROLLED = new ArrayList<Enroll>();
...
}
The Enroll class looks like so:
Code:
@Entity
@Table(name = "ENROLL")
public class Enroll
{
@Embeddable
public static class Id implements Serializable
{
@Column(name = "USER_ID")
private Long userID;
@Column(name = "SCHEDULED_COURSE_ID")
private Long scheduled_course_id;
public Id(){}
public Id(Long userid, Long scheduled_course_id)
{
this.userID = userid;
this.scheduled_course_id = scheduled_course_id;
}
public boolean equals(Object o)
{
if(o != null && o instanceof Id)
{
Id that = (Id)o;
return this.userID.equals(that.userID) && this.scheduled_course_id.equals(that.scheduled_course_id);
}
else
{
return false;
}
}
public int hashCode()
{
return userID.hashCode() + scheduled_course_id.hashCode();
}
}//end of inner class Id
@EmbeddedId
private Id id = new Id();
...
@ManyToOne
@JoinColumn(name = "USER_ID", insertable = false, updatable = false)
private Student student; //This represents the student enrolling in a scheduled course
@ManyToOne
@JoinColumn(name = "SCHEDULED_COURSE", insertable = false, updatable = false)
private ScheduledCourse scheduled_course;
//Constructors
public Enroll(){}
public Enroll(Company company, Administrator admin, Student student, ScheduledCourse sc)
{
this.company = company;
this.admin = admin;
this.student = student;
this.scheduled_course = sc;
//Set identifier values
this.id.scheduled_course_id = sc.getId();
this.id.userID = student.getId();
//Guarantee referential integrity
sc.getEnrolled().add(this);
student.getEnrolled().add(this);
}
...
}
So, imagine if you will, that I've enrolled three students into the ScheduledCourse instance. This means the Enroll table has these three records in it tying in the students with the ScheduledCourse.
When I call this in my test app:
EntityManager em = ...;
ScheduledCourse sc = em.find(ScheduledCourse.class, new Long(1));
em.remove(sc);
Naturally, one would expect that those records in the Enroll table to disappear along with the one record kept in the SCHEDULED_COURSES table. But they don't. I tried eliminating the cascading options altogether, but anything I do has no affect.
Can someone explain what needs to be done in this scenario to make it work?
Alan