_____________ __________________
| | | | _____________
| EVENTS | | PERSON_EVENT | | |
|_____________| |__________________| | PERSON |
| | | | |_____________|
| *EVENT_ID | <--> | *EVENT_ID | | |
| EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
| TITLE | |__________________| | AGE |
|_____________| | FIRSTNAME |
| LASTNAME |
|_____________|
1.3.3. Working the association
Let's bring some people and events together in a new method in EventManager:
private void addPersonToEvent(Long personId, Long eventId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person aPerson = (Person) session.load(Person.class, personId);
Event anEvent = (Event) session.load(Event.class, eventId);
aPerson.getEvents().add(anEvent);
session.getTransaction().commit();
}
After loading a Person and an Event, simply modify the collection using the normal collection methods. As
you can see, there is no explicit call to update() or save(), Hibernate automatically detects that the collection
has been modified and needs to be updated. This is called automatic dirty checking, and you can also try it by
modifying the name or the date property of any of your objects. As long as they are in persistent state, that is,
bound to a particular Hibernate Session (i.e. they have been just loaded or saved in a unit of work), Hibernate
monitors any changes and executes SQL in a write-behind fashion. The process of synchronizing the memory
state with the database, usually only at the end of a unit of work, is called flushing. In our code, the unit of work
ends with a commit (or rollback) of the database transaction - as defined by the thread configuration option for
the CurrentSessionContext class.
You might of course load person and event in different units of work. Or you modify an object outside of a
Session, when it is not in persistent state (if it was persistent before, we call this state detached). You can even
modify a collection when it is detached:
private void addPersonToEvent(Long personId, Long eventId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person aPerson = (Person) session
.createQuery("select p from Person p left join fetch p.events where p.id = :pid")
.setParameter("pid", personId)
.uniqueResult(); // Eager fetch the collection so we can use it detached
Event anEvent = (Event) session.load(Event.class, eventId);
session.getTransaction().commit();
// End of first unit of work
aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
Introduction to Hibernate
Hibernate 3.1.1 12