весна + спящий режим не позволяют сохранить - PullRequest
4 голосов
/ 21 апреля 2010

Есть ли какой-либо параметр, который я могу установить в спящем режиме, чтобы временное запрещение сохранения чего-либо, а только разрешение только на чтение (временное)?можно установить в applicationcontext.xml?

Ответы [ 3 ]

3 голосов
/ 07 мая 2010

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, хотя я не уверен, что это действительно необходимо.

1 голос
/ 07 мая 2010

Я бы обработал это на уровне базы данных и настроил бы приложение на использование пользователя с правами только для чтения во время демонстраций (либо используйте конкретного пользователя для демонстрации, либо измените разрешения используемых в настоящее время разрешений). Просто, эффективно и гарантированно работает с минимальными усилиями.

1 голос
/ 21 апреля 2010

Вы можете пометить транзакцию как readOnly:

@Transactional(readOnly=true)

Один побочный эффект, который я наблюдал, когда забывают сделать метод транзакционным, заключается в том, что никаких вставок или обновлений не происходит, только выбор. Вы можете попробовать полностью опустить объявление транзакции.

Вы также можете попробовать:

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

(или session.setFlushMode(FlushMode.NEVER))

Если это не сработает, вы можете обернуть ваши вызовы DAO с помощью spring AOP и перейти к методу persist только в случае, если установлено свойство пользовательской конфигурации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...