Hibernate имеет метод Session.setReadOnly(Object persited, boolean readOnly)
, который позволяет пометить постоянный объект как доступный только для чтения.
Hibernate 3.5 также имеет Session.setDefaultReadOnly(boolean)
, который можно использовать для установки всех объектов, извлекаемых сеансом, только для чтения.
Задача состоит в том, чтобы найти способ установить это свойство для Session
экземпляров, созданных SessionFactory
. Я предполагаю, что AOP можно использовать для прокси LocalSessionFactoryBean для перехвата созданных SessionFacotory
экземпляров, делегируя большинство методов исходному экземпляру, но перехватывая методы openSession(...)
. Но я не очень знаком с весенним АОП, и IMO может быстро стать довольно сложным для понимания. Вот прямой подход:
Во-первых, оберните LocalSessionFactoryBean
в пользовательскую реализацию:
<bean name="sessionFactory" class="ReadOnlySessionFactoryBean">
<constructor-arg>
<bean class="LocalSessionFactoryBean">
<!-- your existing session factory bean,
all your existing hibernate mappings, properties etc. -->
</bean>
</constructor-arg>
</bean>
Затем добавьте этот класс в свою кодовую базу. (Даже с AOP вам нужно будет ввести некоторый пользовательский код.)
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;
}
// delegate most methods to the delegate SessionFactory
// override all the openSession(...) methods
public Session openSession()
{
Session session = delegate.openSession();
session.setDefaultReadOnly(true);
return session;
}
}
}
Только с этим изменением остальная часть вашего кода может работать без изменений, и каждый раз получит SessionFactory только для чтения. Если вы хотите быть абсолютно уверены, что в базу данных не производится запись, вы можете переопределить методы, которые пишут в базу данных, например, saveOrUpdate
, update
, хотя я не уверен, что это действительно необходимо.