Вручную откройте сеанс гибернации с конфигурацией Spring

Проблема, с которой я сталкиваюсь, заключается в том, что я использую Spring для управления и загрузки спящего режима для своего веб-приложения. В настоящее время я использую OpenSessionInViewFilter. Это работает, как задумано, когда я просматриваю приложение, но не так хорошо, когда я пытаюсь получить доступ к спящему режиму из действий, не связанных с просмотром, таких как задача Quartz или какой-то поток Runnable, который я создаю, чтобы помочь с некоторыми задачами. Это приводит к возникновению исключения отложенной инициализации и исключений, доступных для сеанса.

Вот как я сейчас использую Spring для управления Hibernate

<bean id="mainDataSource" 
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

    [..DB config..]
</bean>

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <property name="dataSource">
        <ref bean="mainDataSource"/>
    </property>
</bean>

<bean id="txManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">

    <property name="sessionFactory"><ref local="sessionFactory"/></property>
    <property name="dataSource"><ref local="mainDataSource"/></property>
</bean>

Затем я настраиваю объекты DAO, которые расширяют HibernateDaoSupport, и внедряю их в классы обслуживания.

<bean id="myDAO"
    class="package.myDAO">
    <property name="sessionFactory">
        <ref bean="sessionFactory" />
    </property>
</bean>

<bean id="mySvcTarget" class="package.myService">
    <property name="myDAO"><ref bean="myDAO"/></property>
</bean> 

<bean id="myService" 
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager">
        <ref bean="txManager"/>
    </property>

    <property name="target">
        <ref bean="mySvcTarget"/>
    </property>

    <property name="transactionAttributes">
        <props>
            <prop key="*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

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


person Raymond Holguin    schedule 02.08.2014    source источник


Ответы (1)


Прежде всего, те дополнительные службы, которые вы используете (не представления), должны быть видны Spring. Самый простой способ сделать это — использовать аннотацию @Service. И чтобы это работало, вы можете добавить <context:component-scan base-package="your.package"> в свою конфигурацию.

После этого, если Spring видит ваш сервис как bean-компонент, должно быть достаточно использовать аннотацию @Transactional, чтобы иметь в нем сеанс Hibernate.

person sap1ens    schedule 02.08.2014
comment
применение @Transactional будет работать вообще. Нет необходимости вызывать Session session=sessionFactory.openSession(); в методах службы CRUD? Поскольку @Raymond хочет вручную открывать и закрывать сеансы гибернации - person Amogh; 02.08.2014
comment
..А что насчет filter, написанного для org.springframework.orm.hibernate.support.OpenSessionInViewFilter в web.xml, остается таким же, нет необходимости удалять этот фильтр. - person Amogh; 02.08.2014
comment
@Amogh, чтобы уточнить, единственная причина, по которой я сказал, что хочу вручную открывать и закрывать сеанс, заключалась в том, что я думал, что это единственный способ выполнить то, что мне нужно. Если мне не нужно этого делать, я бы тоже предпочел этого не делать. - person Raymond Holguin; 04.08.2014
comment
@ sap1ens, к сожалению, это не сработало. Я сделал, как вы предложили, и все еще получаю ленивую ошибку инициализации. Просто для безопасности я добавляю аннотацию транзакции к каждому методу, который я вызываю, а также помечаю классы, которые я использую как транзакционные, но все равно не повезло - person Raymond Holguin; 04.08.2014