Ленивые ошибки инициализации из обновлений - PullRequest
3 голосов
/ 23 сентября 2011

Как я могу предотвратить появление исключений LazyInitializationException при многократном запросе страницы?Если я просто удерживаю Ctrl-R на странице в моем веб-приложении, я последовательно получаю это сообщение в моих файлах журнала.

В моем файле servlet.xml настроен следующий перехватчик:

<mvc:interceptors>
  <bean 
   class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor" />  
</mvc:interceptors>

Тем не менее, я постоянно получаю следующие ошибки:

2011-09-23 15:14:28,854 [http-8080-23] ERROR org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/web-app].[springmvc]  - Servlet.service() for servlet springmvc threw exception
org.hibernate.LazyInitializationException: illegal access to loading collection
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:366)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)

Примечание. Включение ведения журнала на перехватчике Я ясно вижу, что он вызывается и открывает / закрывает транзакции:

2011-09-23 15:36:53,229 [http-8080-5] DEBUG org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - Opening single Hibernate Session in OpenSessionInViewInterceptor
2011-09-23 15:36:53,229 [http-8080-5] WARN  eqip.core.springmvc.extensions.interceptors.AbstractAgencyDataInterceptor IP134.167.141.34 CV#ef955014-cc9d-42fc P#75004 - Pre handle: http://134.167.141.34:8080/web-app/main.xhtml Status: 200

2011-09-23 15: 36: 53,511 [http-8080-5] WARN org.hibernate.engine.StatefulPersistenceContext.ProxyWarnLog IP134.167.141.34 CV # ef955014-cc9d-42fc P # 75004 - Сужение прокси для класса core.model.entities.Subclass - эта операция прерывается == 2011-09-23 15: 36: 53,511 [http-8080-5] WARN org.hibernate.engine.StatefulPersistenceContext.ProxyWarnLog IP134.167.141.34 CV # ef955014-cc9d-42fc P # 75004- Сужение прокси до класса core.model.entities.Subclass - эта операция прерывается == 2011-09-23 15: 36: 53,916 [http-8080-5] DEBUG org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor IP134.167.1410,34CV # ef955014-cc9d-42fc P # 75004 - сброс одного сеанса гибернации в OpenSessionInViewInterceptor 2011-09-23 15: 36: 53,916 [http-8080-5] DEBUG org.springframework.web.servlet.DispatcherServlet IP134.167.141.34 CV# ef955014-cc9d-42fc P # 75004 - Представление рендеринга [eqip.core.springmvc.extensions.velocity.VelocityToolsLayoutView: name 'pages / myEqip';URL [pages / main.xhtml]] в DispatcherServlet с именем 'springmvc' 2011-09-23 15: 36: 54,213 [http-8080-5] DEBUG eqip.core.springmvc.extensions.velocity.VelocityToolsLayoutView IP134.167.141.34CV # ef955014-cc9d-42fc P # 75004 - Шаблон содержимого экрана рендеринга [pages / main.xhtml] 2011-09-23 15: 36: 54,384 [http-8080-5] DEBUG org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor IP134.167.141.34 CV # ef955014-cc9d-42fc P # 75004 - Закрытие одного сеанса Hibernate в OpenSessionInViewInterceptor

Использование Spring 3.0.5, Hibernate 3.6.5, скорость 1.7

Окончательное исправление : добавлено следующее в декларации нашего контроллера:

@Scope(BeanDefinition.SCOPE_PROTOTYPE) 

Это позволило нам продолжать использовать наши перехватчики и получать новые копии предварительно загруженных фрагментов на каждомзапрос.

Ответы [ 3 ]

0 голосов
/ 24 сентября 2011

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

Каждый раз, когда вы нажимаете Ctrl + R, открывается новый запрос, и невозможно инициализировать прокси-объект из предыдущего запроса во время текущего запроса, и в результате возникает LazyInitializationException исключение.

Если это не ваш случай, попробуйте копать в этом направлении.

0 голосов
/ 26 сентября 2011

Написать класс как: -

public class CustomHibernateSessionViewFilter extends   OpenSessionInViewFilter {

protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
    Session session = super.getSession(sessionFactory);
    session.setFlushMode(FlushMode.COMMIT);
    return session;
}

protected void closeSession(Session session, SessionFactory factory) {
    session.flush();
    super.closeSession(session, factory);
}

}

Объявите это в web.xml следующим образом: -

<filter>
    <filter-name>OSIVF Filter</filter-name>
    <filter-class>your.path.to.CustomHibernateSessionViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>OSIVF Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
0 голосов
/ 23 сентября 2011

Вы уверены, что класс перехватчика действительно вызывается?Получите исходные коды и выполните отладку, чтобы увидеть, действительно ли выполнено выполнение.Убедитесь, что вы на самом деле объявили этот перехватчик как перехватчик в вашей конфигурации Spring mvc:

 <bean id="urlMapping"class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>

<property name="mappings">

</bean>

Или вы можете просто пойти с более простым OpenSessionInVIewFilter, который нужно настроить только как фильтр сервлета, который перехватывает* (или универсальный enoug URL, чтобы охватить все URL ваших контроллеров, которые имеют дело со спящими сущностями).

...