I'm developing a new Java web application and I'm exploring new ways (new for me!) to persist the data. I mostly have experience with JPA & Hibernate but, except for simple cases, I think this kind of full ORM can become quite complex. Plus, I don't like working with them that much. I'm looking for a new solution, probably closer to SQL.
The solutions I'm currently investigating :
But there are two use cases I'm worrying about with those solutions, compared to Hibernate. I'd like to know what are the recommended patterns for those use cases.
Use Case 1 - Fetching an entity and accessing some of its associated children and grandchildren entities.
- Let's say I have a
Person
entity.- This
Person
has an associatedAddress
entity.- This
Address
has an associatedCity
entity.- This
City
entity has aname
property.
- This
- This
- This
The full path to access the name of the city, starting from the person entity, would be :
person.address.city.name
Now, let's say I load the Person entity from a PersonService
, with this method :
public Person findPersonById(long id)
{
// ...
}
Using Hibernate, the entities associated to the Person
could be lazily loaded, on demand, so it would be possible to access person.address.city.name
and be sure I have access to this property (as long as all the entities in that chain are not nullable).
But using anyone of the 3 solutions I'm investigating, it's more complicated. With those solutions, what are the recommended patterns to take care of this use case? Upfront, I see 3 possible patterns:
All the required associated children and grandchildren entities could be eagerly loaded by the SQL query used.
But the issue I see with this solution is that there may be some other code that needs to access other entities/properties paths from the
Person
entity. For example, maybe some code will need access toperson.job.salary.currency
. If I want to reuse thefindPersonById()
method I already have, the SQL query will then need to load more information! Not only the associatedaddress->city
entity but also the associatedjob->salary
entity.Now what if there are 10 other places that need to access other information starting from the person entity? Should I always eagerly load all the potentially required information? Or maybe have 12 different service methods to load a person entity? :
findPersonById_simple(long id) findPersonById_withAdressCity(long id) findPersonById_withJob(long id) findPersonById_withAdressCityAndJob(long id) ...
But then everytime I would use a
Person
entity, I would have to know what has been loaded with it and what hasn't... It could be quite cumbersome, right?In the
getAddress()
getter method of thePerson
entity, could there be a check to see if the address has already been loaded and, if not, lazily load it? It this a frequently used pattern in real life applications?Are there other patterns that can be used to make sure I can access the entities/properties I need from a loaded Model?
Use Case 2 - Saving an entity and making sure its associated and modified entities are also saved.
I want to be able to save a Person
entity using this PersonService
's method :
public void savePerson(Person person)
{
// ...
}
If I have a Person
entity and I change person.address.city.name
to something else, how can I make sure the City
entity modifications will be persisted when I save the Person
? Using Hibernate, it can be easy to cascade the save operation to the associated entities. What about the solutions I'm investigating?
Should I use some kind of dirty flag to know what associated entities also have to be saved when I save the person?
Are there any other known patterns useful to deal with this use case?
Update : There is a discussion about this question on the JOOQ forum.