Expressing Many-to-Many Relationships in Hibernate
As humans, we tend to think of the world in objects. For instance, my car has four tires and my body has a pair of arms and legs. Since everything around us is thought of as objects, then why would we want to write code that stores data relationally? The short answer is; we are forced to based on the way traditional databases store data.
Let’s say for instance we have a group of Students that wish to enroll in several University Courses. Storing the Students and Courses in a relational database is trivial, however, how do we express Students that are enrolled in Courses? This is a typical many-to-many relationship where any number of students can be enrolled in any number of courses.
In the world of databases, a single table is created for Students and another for Courses. Then, a third table is created that holds the students that are enrolled in each course. The Enrolled table is called a cross-reference table.
This poses a problem for object oriented languages such as Java, C#, and Ruby because, while we don’t mind creating separate Student and Course objects, creating a third Enrolled object is poor OO design and will create unnecessary complexities in our code.
This is a more programmer-friendly way to store Students, Courses, and the Enrollment of Students in Courses.
Now, when we need to perform an action on a Course all of the Student objects associated with that Course are passed along with it. This is a much better way of handling the issue of enrollment, but how does this data get stored back to the database? After all, it’s great that we can write code at the level of objects, but at the end of the day, all application data still needs to be stored back in a relational model.
By using an Object-Relational Mapping (ORM) tool such as Hibernate, programmers can continue to write code in terms of objects and the ORM tool will worry about how to store the data in a relational model. In Hibernate, this can be achieved by creating mapping files that teach Hibernate how to store the data in an object.
Using Mapping Files
Continuing our Students->Courses example, let’s create the mapping files necessary to teach Hibernate how to store each object’s data.
See how the many-to-many relationship in the Course mapping file is expressed? This tells hibernate that a relationship exists between Courses and Students and also gives specifics on what the relationship is and how (and where) to store the relationship in the database.
Now, we can treat our objects as objects and teach our ORM tool how to persist the data back to the database.
Did you notice that I didn’t even start talking about Hibernate until the latter half of this article? ORM tools allow us to write code and not worry about how to store our application’s data back to the database.