Spring + hibernate set do not allow persistence

Is there any parameter i that can be set in sleep mode so that the temporary does not allow me to save something, but only allow reading (temporary)? can i set in applicationcontext.xml?

+4
source share
3 answers

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"> <!-- your existing session factory bean, all your existing hibernate mappings, properties etc. --> </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; } // delegate most methods to the delegate SessionFactory // override all the openSession(...) methods public Session openSession() { Session session = delegate.openSession(); session.setDefaultReadOnly(true); return session; } } } 

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.

+3
source

You can mark your transaction as readOnly:

 @Transactional(readOnly=true) 

One side effect that I observed when someone forgets to make a method transaction is that there are no inserts or updates, only one is selected. You can completely refuse the announcement of the transaction.

You can also try:

 <prop key="org.hibernate.FlushMode">NEVER</prop> 

(or session.setFlushMode(FlushMode.NEVER) )

If this does not work, you can wrap your DAO spring AOP calls and go to the persist method only if a custom configuration property is set.

+1
source

I would handle this at the database level and configure the application to use the user with read-only permissions during the demos (either use the specific user for the demo, or change the permissions currently in use). Simple, efficient and guaranteed operation with minimal effort.

+1
source

Source: https://habr.com/ru/post/1307524/


All Articles