2010-10-21 5 views
0

Из того, что я читал до сих пор, я понял, что использование транзакций будет решением проблем с ленивой загрузкой в ​​спящем режиме. Сессия будет доступна в течение всей транзакции на уровне обслуживания без дальнейшего простоя.Весенние транзакции и спящий режим: ленивая инициализация

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

Моя конфигурация:

<bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" 
    id="sessionFactory"> 
    <property name="configLocation"> 
     <value>classpath:hibernate.cfg.xml</value> 
    </property> 
</bean> 
<!-- Hibernate Template bean that will be assigned to DAOs. --> 
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> 
    <property name="sessionFactory"> 
     <ref bean="sessionFactory" /> 
    </property> 
</bean> 

<!-- 
    Transaction manager for a single Hibernate SessionFactory (alternative 
    to JTA) 
--> 
<bean id="transactionManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory"> 
     <ref local="sessionFactory" /> 
    </property> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

Моя реализация DAO бы просто иметь @Repository аннотацию и Hibernate-template боб вводится с помощью автоматического связывания.

Типичный заголовок в реализации услуг будет:

@Service 
@Transactional(readOnly=true) 
public class LeerlingServiceImpl implements LeerlingService { 

    @Autowired 
    LeerlingDAO leerlingDAO; 
    @Autowired 
    LeerplanDAO leerplanDAO; 

С @Service(readOnly=false) аннотацию, если что-нибудь на самом деле сохранен/обновлено в этом конкретном методе.

Нужно ли мне настроить что-то еще, чтобы убедиться, что я могу загрузить правильные ассоциации в своей службе или это нормально обрабатывается транзакциями?

Прямо сейчас я просто немного запутался, что я на самом деле, поэтому, пожалуйста, помогите мне :)

ответ

1

проблемы Ленивый загрузкой и операции на самом деле не связаны друг с другом. Но это еще одна история :) Вы сделали все хорошо, кроме доступа к сеансу в ваших бобах. Не уверен, как вы собираетесь это делать. Стандартное решение (весной 2.x, не уверенное в 3.x, еще не рассмотрено) заключается в использовании HibernateDaoSupport в качестве базового класса для классов, если у вас будет доступ к сеансу. Но лично это выглядит немного изворотливым для меня, потому что добавляет зависимость от классов, специфичных для Spring. Лучше всего ввести сессию в свои бобы. Чтобы сделать это, вам нужно объявить свой сеансовый компонент с определением, аналогичным определению:

<bean name="hibernateSession" class="org.springframework.orm.hibernate3.SessionFactoryUtils" factory-method="getSession" 
    scope="prototype"> 
    <constructor-arg index="0" ref="hibernateSessionFactory"/> 
    <constructor-arg index="1" value="false"/> 
    <aop:scoped-proxy/> 
</bean> 

а затем просто используйте его.

Вот детали:

http://stas-blogspot.blogspot.com/2009/10/hibernate-spring-in-standalone.html

+0

Использование шаблона не «стандартный» решение, это только один вариант, который на самом деле не рекомендуется с 2007 года Просто впрыснуть 'sessionFactory' и использовать' sessionFactory.getCurrentSession() ', если вы хотите идти шаблон -Меньше. См. [Так что, если вы все еще используете Spring HibernateTemplate и/или JpaTemplate?] (Http://blog.springsource.com/2007/06/26/so-should-you-still-use-springs-hibernatetemplate-andor-jpatemplate /). –

+0

Это довольно ошеломляющая величина косвенности, чтобы обойти вызов sessionFactory.getCurrentSession(). Не знаю, каковы последствия производительности вставки getBean() для каждого вызова метода на сеансе. – Affe

+0

Я использовал расширение класса hibernateDAOSupport в своих DAO (и ввел его.). Но как мне получить доступ к моей сессии в моем сервисе и DAO, или это неестественная вещь? Другие рекомендуют использовать: http://community.jboss.org/wiki/OpenSessioninView; поскольку это связывает сессию с потоком при каждом запросе (так что да: я делаю webapp) – toomuchcs

1

Я думаю, что мое понимание весной было просто плохо до сих пор; для управления сеансами действительно не было реального управления. В основном, что теперь произошло, вы могли получить данные из DAO, но сразу после того, как вы его получили, вы не могли даже загружать ленивые коллекции, потому что сессия была закрыта.

Теперь мы используем перехватчик hibernate, который присоединяет сеанс к потоку в начале каждого запроса и закрывает его, когда он заканчивается. Это не всегда самое идеальное решение, но для школьного проекта я бы не стал слишком сильно беспокоиться.

Другое решение похоже: добавьте АОП таким образом, чтобы использовать @around, что сеанс доступен только во время вызова метода службы. Я думаю, что это лучшее решение, но я не собираюсь копать это прямо сейчас для этого проекта. Хорошо, что я знаю, что он существует.

Эта статья также помогла мне много: http://www.jroller.com/kbaum/entry/orm_lazy_initialization_with_dao

Для тех, кто заинтересован: вот что я должен был добавить: В Spring MVC 3.0 появилась новая функция под названием mvc:intereceptors который заставил меня набрать меньше XML.

<!-- WEB-INF/applicationContext.xml or your own XML config file --> 
<mvc:interceptors> 
    <bean 
     class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"> 
     <property name="sessionFactory"> 
      <ref local="sessionFactory" /> 
     </property> 
    </bean> 
</mvc:interceptors> 
Смежные вопросы