Hibernate is an excellent Object Relational Mapper. Using just xml files, we are able to describe the relationship between all of our tables and our domain (POJO) objects (like Patient.java, Concept.java, etc). Looking at the concept domain in the datamodel, we see that it consists of tables named concept, concept_answer, concept_set, concept_name. It would be very difficult to keep up with where to store each part of the concept object and the relations between them. Using Hibernate, we only need to concern ourselves with the Concept object, not the tables behind the object. The concept.hbm.xml mapping file does the hard work of knowing that the Concept object contains a collection of ConceptSet objects, a collection of ConceptName objects, etc. To add a new name to a concept:
ConceptService conceptService = Context.getConceptService();
Concept concept = conceptService.getConcept(1234);
ConceptName newConceptName = new ConceptName("some name", "some locale");
Hibernate knows what has changed and what needs to be saved into the database. (The long and short of it is that Hibernate wraps the Concept object in its own object and keeps track of what has been added, removed, etc).
Hibernate will not load all associated objects until they are needed – this is called lazy loading. The concept object above never dove into the concept_answer table to get the list of answers for concept 1234. If we had called concept.getConceptAnswers() Hibernate at that point would have made a call to the database to retrieve the answers for us. For this reason, you must either fetch/save/manipulate your object in the same session (between one open/closeSession) or you must hydrate all object collections in the object by calling the getters (getConceptAnswers, getConceptNames, getSynonyms, etc).