To have my code style validated I use Checkstyle. One of the rules Checkstyle can validate is DesignForExtension (
http://checkstyle.sourceforge.net/confi ... rExtension ). To comply with the rule, for my persistent domain model classes, I've initially just marked their methods as final.
Then I played little bit with persistent class caching, using ehcache. I've annotated a class with @Cache(usage = CacheConcurrencyStrategy.READ_ONLY). After inspecting Tomcat log file and Spring/Hibernate context initialization, I've found a warning "...read-only cache configured for mutable class...". Correct me if I'm wrong, I assume that ehcache analyzed my peristent domain model class, found it has public setters, and because of requested READ_ONLY cache strategy reported a warning.
Then I wanted to eliminate all the setters to make the READ_ONLY class immutable. To find out whether a persistent class must have setters or not I've consulted Chapter 4 of Hibernate reference documentation, it's paragraph 4.1.3. drew my attention, especially line "You should also avoid declaring public final methods on the non-final classes. If you want to use a class with a public final method, you must explicitly disable proxying by setting lazy="false".". According to this my solution with just methods being final was wrong, I had to mark persistent domain model class as final. Then I got confused by the other two lines in that same Chapter 4, 4.1.3 paragraph which state:
"A central feature of Hibernate, proxies, depends upon the persistent class being either non-final, or the implementation of an interface that declares all public methods.
You can persist final classes that do not implement an interface with Hibernate, but you won't be able to use proxies for lazy association fetching - which will limit your options for performance tuning. "
What confuses me is that after reading this it's not clear (to me at least) whether one can still use lazy association fetching if class is final but implements an interface. So if I define a IUser interface, and a User persistent domain class implementing that interface, same for a IRole/Role and a many-to-many relationship between Role and User, with User having reference to collection of Roles he/she has, and a Role having reference to collection of Users that have that Role, if both Role and User are made final, question is whether their associations can be lazily fetched or have to be eagerly fetched?
Thing about this solution with persistent domain model classes being final and requiring an interface to be defined for each of them, was something that me and my colleagues didn't like at first - instead of just a persistent class we have to worry about defining interface for it too. This is not that much of a problem, as we always strive to code to interfaces as much as possible, I'd just like to know if this practice (final + interface) is OK, and, if not, what would be the best practice?