Hibernation has the Session.setReadOnly(Object persited, boolean readOnly) , which allows you to mark a saved object as read-only.
Hibernate 3.5 also has Session.setDefaultReadOnly(boolean) , which can be used to set all objects received by a read-only session.
The challenge is to find a way to set this property in Session instances created by SessionFactory . I believe that AOP can be used for the LocalSessionFactoryBean proxy to intercept the created SessionFacotory instances, delegating most of the methods to the original instance, but intercepting the openSession(...) methods. But I am not familiar with spring AOP, and IMO it can quickly become quite difficult to understand. Here's a direct approach:
First wrap the LocalSessionFactoryBean in a custom implementation:
<bean name="sessionFactory" class="ReadOnlySessionFactoryBean"> <constructor-arg> <bean class="LocalSessionFactoryBean"> </bean> </constructor-arg> </bean>
Then add this class to your codebase. (Even with AOP, you need to enter some kind of user code.)
public class ReadOnlySessionFactoryBean extends AbstractFactoryBean { private AbstractSessionFactoryBean sessionFactoryBean; public ReadOnlySessionFactoryBean(AbstractSessionFactoryBean sessionFactoryBean) { this.sessionFactoryBean = sessionFactoryBean; } @Override public Class getObjectType() { return sessionFactoryBean.getObjectType(); } @Override protected Object createInstance() throws Exception { SessionFactory factory = sessionFactoryBean.getObject(); return new WrapSessionFactory(factory); } static class WrapSessionFactory implements SessionFactory { private Sessionfactory delegate; WrapSessionFactory(SessionFactory delegate) { this.delegate = delegate; }
With this change, the rest of your code can work unchanged and will receive a read-only SessionFactory each time. If you want to be absolutely sure that there is no writing to the database, you can override the methods that write to db, for example. saveOrUpdate , update , although I'm not sure if this is really necessary.
source share