Hi there,
I have a dilemma I'm trying to solve. I'll start by descibing a part of my small application.
I have a hierarchy of classes like so:
abstract User
|
|__ Administrator extends User
|__ Instructor extends User
|__ Student extends User
In addition, I have a class named ScheduledCourse. It looks like so with a collection of instructors:
Code:
@Entity
@Table(name = "SCHEDULED_COURSES")
public class ScheduledCourse implements Serializable
{
...
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@org.hibernate.annotations.CollectionOfElements
@JoinTable(name = "SCHEDULED_INSTRUCTORS", joinColumns = {@JoinColumn(name = "SCHEDULED_COURSE_ID")}, inverseJoinColumns ={@JoinColumn(name = "USER_ID")})
private Collection<Instructor> INSTRUCTORS_SCHEDULED = new ArrayList<Instructor>();
...
}
As you can see, there is an interim Table being created here that contains pointers to both the ScheduledCourse
and the instructor. This is named: SCHEDULED_INSTRUCTORS.
I'm not even sure the relationship should be OneToMany or ManyToMany. The logic is this: A ScheduledCourse
can have more than one instructor teaching the course. By the same token, an instructor can teach more
than one ScheduledCourse.
Therefore, the instructor class also has a collection of type ScheduledCourse. So, what is this really?
OneToMany or ManyToMany? I'm inclined to think it's the latter, isn't it?
The instructor class is the opposite end of this relationship with a collection of ScheduledCourses:
Code:
@Entity
@Table(name = "INSTRUCTORS")
public class Instructor extends User implements Serializable
{
...
@OneToMany(mappedBy = "INSTRUCTORS_SCHEDULED")
private Collection<ScheduledCourse> ASSIGNED_SCHEDULED_COURSES = new ArrayList<ScheduledCourse>();
...
}
What I want to do is test the EntityManager.remove(Object o) method and its cascading affect on an instance of ScheduledCourse. Assume the collection of instructors in ScheduledCourse has only one instructor in it. This is my test code:
EntityManager em4 = emf.createEntityManager();
EntityTransaction tx4 = em4.getTransaction();
tx4.begin();
ScheduledCourse sc = em2.find(ScheduledCourse.class, new Long(1));
em4.remove(sc);
tx4.commit();
em4.close();
When hibernate starts the deletions it certainly clears the SCHEDULED_INSTRUCTORS table, which is what I want, but it doesn't stop there! This is not good. It actually continues a cascade deletion of the instructor from the INSTRUCTORS table and USERS table. I don't want it to do that! Could someone please explain what it is I need to do to get the appropriate behaviour I want?
Here's what I'm getting from my SQL log from the database:
SET AUTOCOMMIT TRUE
/*C19*/SET AUTOCOMMIT FALSE
DELETE FROM SCHEDULED_INSTRUCTORS WHERE SCHEDULED_COURSE_ID=1 AND USER_ID=3 //fine
DELETE FROM INSTRUCTORS WHERE USER_ID=3 //not good
DELETE FROM USERS WHERE USER_ID=3 //not good
DELETE FROM SCHEDULED_COURSES WHERE SCHEDULED_COURSE_ID=1 //fine
COMMIT
SET AUTOCOMMIT TRUE
/*C20*/SET AUTOCOMMIT FALSE
Please advise,
Alan