It seems that one of Hibernate's primary design goals has been transparency of the persistence service. And this goal has been reached quite well - you do not need to access your objects in any special way to enable Hibernate to persist them. However, it seems to me that by using Hibernate's advanced features you can actually make the persistence service less transparent. By this I mean that using the full power of Hibernate still keeps _Hibernate_ transparent to your business code, but _persistence layer_ is not transparent to your business code anymore. Your business code relies on Hibernate's persistence service to do things that will not be possible using some other persistence mechanism. You cannot replace Hibernate with another persistence engine, so it is not actually transparent anymore.
For example: "record" and "artist" objects, with 1:n relationship. We use DAO pattern to insulate persistence layer from business layer. With Hibernate, we can implement our business objects and DAOs as follows:
Code:
class Artist {
private String firstName;
private String lastName;
private Date birthDate;
private Collection records;
public static Artist loadByID() {
return ArtistDAO.loadByID();
}
}
The point is that we do not need load the records collection. Hibernate will do it for us, using it's own magic collections and lazy loading when we access that collection. If we were to replace Hibernate with, say, our own persistence layer that stored the data to LDAP, this would be much harder to accomplish. And the more complex the relations between objects get, and the more we rely on Hibernate's advanced features, the more difficult (or in some cases, impossible, I believe) it will be to accomplish the same thing with alternative technologies.
To me it seems that there are two choices: a) I use the full feature set of Hibernate and compromise on portability. I get a nice design and a working solution, but to me it feels really fishy to use DAO pattern to decouple your business logic classes from persistence details - and then implement it with a technology that negates the pattern's benefits. Or, b) use Hibernate but use it in a way that it will be replaceable with another persistence technology. This means that you will not be using the "full power" of Hibernate and that there will be some extra ugliness (to enable portability that you will most likely not need).
I am not sure which one would I pick - what is your choice? Or do you disagree with my assumptions or reasoning?
Of course, one argument would be that "you will not need alternatives to relational database persistence, and will not need to change from Hibernate". That might be the case, but if you are using DAO object pattern, it seems like a lame excuse.