Could someone please explain what's going on here. I have a class named ScheduledCourse. It contains a collection of type Enroll. The Student class is the same. The Enroll class is an entity class (creates the ENROLL table) that serves as an intermediate join table between tables SCHEDULED_COURSES and STUDENTS. When I enroll a student I simply create an instance of type Enroll. Its constructor automatically adds the instance to the collections in instances of ScheduledCourse and Student. When I run my test code for the first unit of work I load the collections. The println statements reveal the proper amounts. The instance of ScheduledCourse has three Enroll instances, while each of the Student instances have one.
So far, so good.
But wait, what's happening in the 2nd. unit of work? I use: sc2 = em2.find(ScheduledCourse.class, index); to bring the instance of ScheduledCourse back into the persistant context and use a println statement to have a look at the size of the collection of type Enroll. It's zero! This isn't good! Why is it zero? What happened to my instances of Enroll?
See test code below:
//First unit of work EntityManager em1 = emf.createEntityManager(); EntityTransaction tx1 = em1.getTransaction(); tx1.begin();
//Create a ScheduledCourse ScheduledCourse sc1 = new ScheduledCourse(...); em1.persist(sc1); Long index = sc1.getId(); //Enroll several students into the course //ScheduledCourse has a collection of type Enroll //The following automatically adds these to the collections //in ScheduledCourse and Student Enroll enroll1 = new Enroll(company, admin1, student1, scheduled_course); em1.persist(enroll1); Enroll enroll2 = new Enroll(company, admin1, student2, scheduled_course); em1.persist(enroll2); Enroll enroll3 = new Enroll(company, admin1, student3, scheduled_course); em1.persist(enroll3);
System.out.println("Adding students to the collections in scheduled course and students..."); System.out.println("scheduled_course.getEnrolled().size(): " + scheduled_course.getEnrolled().size()); //reveals 3 System.out.println("enroll1.getStudent().getEnrolled().size(): " + enroll1.getStudent().getEnrolled().size());//reveals 1 System.out.println("enroll2.getStudent().getEnrolled().size(): " + enroll2.getStudent().getEnrolled().size());//reveals 1 System.out.println("enroll3.getStudent().getEnrolled().size(): " + enroll3.getStudent().getEnrolled().size());//reveals 1
//Perform 2nd Unit of work EntityManager em2 = emf.createEntityManager(); EntityTransaction tx2 = em2.getTransaction(); tx2.begin();
Look like it is lazy loading the Collection, meaning your call to size() is calling an unitialized Collection. You can try to eager load them, or instead of calling size() loop through the collection printing them out one by one.
Also, what is most important to tell us what is going on is seeing your mapping files.
First We should rewrite the following code in session #1
Now the constructor in the Enroll class has to set both sides. Not just adding the Enroll into the scheduled_course object's Collection, but also setting the scheduled_course's reference in the Enroll object.
What is you mapping for Enroll?
Anyway, also add/change the following to your Mapping
Since the table name is "ENROLL" the same as the Class name, and the PK is "ENROLL_ID" you do not need the @JoinColumn and @JoinTable, you can use the defaults, which is "ENROLL" and "ENROLL_ID"