We are going to proceed with our example to see this working, but instead of working on the relation
between the 'Course' and the 'Lecturer', we will use the new entity 'Teaching Assistant', where a
Course can have many TAs, while the TA is assisting in one course.
-
At the Database level: a TA has a foreign key 'CourseID'.
-
Create the table TA; you can use this query:
Create Table TA( ID int, FirstName nvarchar(50), LastName nvarchar(50),
CourseID int, Primary Key (ID), Foreign Key (CourseID) References Course)
-
Insert some records in the Table
-
At the application level
We are going to repeat the steps we did for the course, with some little changes. Since this
time the relation is reflected on the Course, so the List of TAs will be added to Course.java
and its Mapping will be added to the Course mapping.
-
Create the Class 'TeachingAssistant' in hibernate_Classes package
with the instant variables:
And their getters and setters.
-
Add the TAs list to Course.java,
-
Add the instant variable
private List TAs;
-
Create its getter and setter methods
-
Create the Mapping
Again, you can either create a new mapping file 'TeachingAssistant.hbm.xml'
for example, or complete working on a previously created mapping file.
Add the mappings for the 'ID' , 'firstName' and 'lastName' normally like
we did before.
-
Add the TAs list mapping
This time the relation is One-to-Many (a Course can have many TAs), so we
will be using the element 'one-to-many' , and since we are going to
represent the TAs by a List, we will also be using the element bag , this way:
<bag name="TAs" >
<key column="CourseID" />
<one-to-many class = "TeachingAssistant"/>
</bag>
It can be read:
The variable of name "TAs" , is representing a one-to-many relation
with the table represented by the class "TeachingAssistant" , where
the foreign key column is CourseID .
Colloectiona can also be represented using a 'set' or 'map' or 'array' ... etc,
this depends on the type of collection you are using (in our case, we used a
List). Read about these different
Types of Collections
from a tutorial by Gary
Mak, in this pdf (pages 4-6) he explains each of them separatly. You can also
read about
Collection Mapping
from JBoss community documentation.
-
Add it to Hibernate configurations
Do like what you have done when mapping the Course.
Run SimpleTest.java, to check for errors.
Now, let's use it...
Getting all Courses and their TAs will look the same like Getting the Courses and their Lecturers, you
can test it yourself using this HQL:
Select crs From Course crs left join fetch crs.TAs
What may look different is Adding a TA to a Course or Removing a TA from a course, so we will try
these.
Since the TA-Course relation is represented in the TAs list of the Course Class, So working on this
relation means working on that List (i.e. Adding and Removing a TA from a Course is Adding and
Removing from the List of that Course's TAs).
We will create a method that given a certain TA's ID and a Course's ID, adds the CourseID to the TA by
adding this TA to the List of the Course's TAs. So in the method, we will first get the TA with that ID,
then add him to the list. // We will complete working on CoursesHandler, since we are still dealing with
Courses.:
-
The method:
public void AddTAToCourse (int CourseID, int TAID)
{
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = session.beginTransaction();
String query
= "Select crs From Course crs left join fetch crs.TAs where crs.ID = '"+ CourseID + "' ";
Course c1 = (Course)(session.createQuery(query).list().get(0));
TeachingAssistant t1 = (TeachingAssistant)session.load(TeachingAssistant.class, TAID);
c1.getTAs().add(t1);
tx.commit();
}
-
Test it in the main method:
handler.AddTAToCourse(1, 1);
// make sure you have TAs and Courses in your database.
Removing a TA from a course will look the same except for
c1.getTAs().add(t1)
, it will be instead
c1.getTAs().remove(t1)
Before moving to the Many-To-Many relation, there is a point to be mentioned here.
In our example we used 'join fetch', this means that our 'fetch' is with type 'join'. In the 'join' fetch,
Hibernate gets the related objects (the TAs objects to be loaded to the TAs list) in one Outer Join
Select statement.
Select ... From Course crs left outer join TA tas on crs.ID = tas.CourseID
There is another type for fetch which is 'Select', Where Hibernate retrieves those related objects one
by one, each in a separate Select statement.
Select … From Course
Select … From TA Where TA.CourseID = ...
Select … From TA Where TA.CourseID = ...
Select … From TA Where TA.CourseID = ...
Also fetching the collection (the TAs list in our example) can take place either when the collection is
accessed or without the collection being accessed. This has to do with the so called 'Lazy' property.
We will not go into these details to keep it simple, and you can read about the 'Lazy' property and
'fetching' strategies in details from
this
presentation pdf by Sang Shin, or have an overview from
hibernate.org.
Now we are moving to the last part in our tutorial, which is the Many-To-Many relation.