When working simply with Hibernate, you end up coding to concrete classes. This violates the idea that you should program to a type, not an implementation. It also means that various things you tend to do with Hibernate (like writing getters and setters) end up “polluting” your domain classes.
There is a way to get Hibernate to give you back interfaces instead of concrete classes. It’s called a Hibernate proxy. When Hibernate uses lazy-loading (on by default in HIbernate 3), it gives you back proxies, rather than direct instances of the class. These proxies are dynamically generated subclasses of the nominated “proxy class”. This proxy class, by default, is the actual mapped class, but it does not have to be – it can be an interface, as long as the mapped class implements the interface.
This means that you can put on the various Hibernate hooks that you may need, make them public if you want (e.g. for testing), but not have to worry about your production code getting at them. And the proxy is a real proxy – you would not be able to cast it to the mapped class, as there is no inheritance chain back to it.