LazyInitializationException, несмотря на OpenSessionInViewFilter
Я разрабатываю веб-приложение, используя Spring 4, Hibernate 4 и JSF 2.2. Я пытаюсь использовать OpenSessionInViewFilter, чтобы избежать LazyInitializationException, но мне не удается. У меня есть класс консультанта в такой области:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "consultant")
private List<Product> products;
Теперь в другом классе, где у меня есть объект Консультант, и я пытаюсь получить продукты, используя поле выше:
List<Product> products = consultant.getProducts();
Затем создается исключение LazyInitializationException. Это мой журнал (я не вижу там подозрительных вещей):
Using SessionFactory 'sessionFactory' for OpenSessionInViewFilter
Returning cached instance of singleton bean 'sessionFactory'
Opening Hibernate Session in OpenSessionInViewFilter
/consultant/products.xhtml at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@f8b7e57f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f8b7e57f: Principal: User{userId=1, username=doradca@doradca.pl, password=$2a$10$ALqnZKxx9anO/4XnBjtt1Ocm4GC1KDfrAlIz/iV66RWANklk31WqW, authorities=[Authority{role=CONSULTANT}], accountNonExpired=true, accountNonLocked=true, credentialsNonExpired=true, enabled=true}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 9ED9D61F10507CAF3B77109D465B9AD6; Granted Authorities: Authority{role=CONSULTANT}'
/consultant/products.xhtml at position 2 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
/consultant/products.xhtml at position 3 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
/consultant/products.xhtml at position 4 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
/consultant/products.xhtml at position 5 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
/consultant/products.xhtml at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
pathInfo: both null (property equals)
queryString: both null (property equals)
requestURI: arg1=/EuroBroker/consultant/products.xhtml; arg2=/EuroBroker/consultant/products.xhtml (property equals)
serverPort: arg1=8080; arg2=8080 (property equals)
requestURL: arg1=http://localhost:8080/EuroBroker/consultant/products.xhtml; arg2=http://localhost:8080/EuroBroker/consultant/products.xhtml (property equals)
scheme: arg1=http; arg2=http (property equals)
serverName: arg1=localhost; arg2=localhost (property equals)
contextPath: arg1=/EuroBroker; arg2=/EuroBroker (property equals)
servletPath: arg1=/consultant/products.xhtml; arg2=/consultant/products.xhtml (property equals)
Removing DefaultSavedRequest from session if present
/consultant/products.xhtml at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
/consultant/products.xhtml at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f8b7e57f: Principal: User{userId=1, username=doradca@doradca.pl, password=$2a$10$ALqnZKxx9anO/4XnBjtt1Ocm4GC1KDfrAlIz/iV66RWANklk31WqW, authorities=[Authority{role=CONSULTANT}], accountNonExpired=true, accountNonLocked=true, credentialsNonExpired=true, enabled=true}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 9ED9D61F10507CAF3B77109D465B9AD6; Granted Authorities: Authority{role=CONSULTANT}'
/consultant/products.xhtml at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
/consultant/products.xhtml at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
/consultant/products.xhtml at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
Checking match of request : '/consultant/products.xhtml'; against '/consultant/**'
Secure object: FilterInvocation: URL: /consultant/products.xhtml; Attributes: [hasRole('CONSULTANT')]
Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@f8b7e57f: Principal: User{userId=1, username=doradca@doradca.pl, password=$2a$10$ALqnZKxx9anO/4XnBjtt1Ocm4GC1KDfrAlIz/iV66RWANklk31WqW, authorities=[Authority{role=CONSULTANT}], accountNonExpired=true, accountNonLocked=true, credentialsNonExpired=true, enabled=true}; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@2cd90: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 9ED9D61F10507CAF3B77109D465B9AD6; Granted Authorities: Authority{role=CONSULTANT}
Voter: org.springframework.security.web.access.expression.WebExpressionVoter@16ed6204, returned: 1
Authorization successful
RunAsManager did not change Authentication object
/consultant/products.xhtml reached end of additional filter chain; proceeding with original chain
Entering JSF Phase: RESTORE_VIEW 1
Entering JSF Phase: RENDER_RESPONSE 6
Returning cached instance of singleton bean 'org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0'
Returning cached instance of singleton bean 'org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0'
Returning cached instance of singleton bean 'org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0'
Returning cached instance of singleton bean 'accountManager'
Returning cached instance of singleton bean 'insuranceService'
Returning cached instance of singleton bean 'insuranceService'
Chain processed normally
SecurityContextHolder now cleared, as request processing completed
Closing Hibernate Session in OpenSessionInViewFilter
com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@373d727a -- Running DeadlockDetector[Exiting. No pending tasks.]
Returning cached instance of singleton bean 'transactionManager'
Creating new transaction with name [com.efsf.eurobroker.user.logic.TokenCleanerCron.deleteOldTokens]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction
Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]
trace com.mchange.v2.resourcepool.BasicResourcePool@6383a319 [managed: 5, unused: 4, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@4c7576d0)
Exposing Hibernate transaction as JDBC transaction [com.mchange.v2.c3p0.impl.NewProxyConnection@330b16dd]
Returning cached instance of singleton bean 'transactionManager'
Found thread-bound Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction
Participating in existing transaction
com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache ----> CACHE HIT
checkoutStatement: com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 4; checked out: 1; num connections: 1; num keys: 4
checkinStatement(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 4; checked out: 0; num connections: 1; num keys: 4
Initiating transaction commit
Committing Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]
Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction
checkinAll(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 4; checked out: 0; num connections: 1; num keys: 4
com.mchange.v2.async.ThreadPoolAsynchronousRunner@7f0b008a: Adding task to queue -- com.mchange.v2.resourcepool.BasicResourcePool$1RefurbishCheckinResourceTask@5149a61d
trace com.mchange.v2.resourcepool.BasicResourcePool@6383a319 [managed: 5, unused: 4, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@4c7576d0)
checkinAll(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 4; checked out: 0; num connections: 1; num keys: 4
com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@373d727a -- Running DeadlockDetector[Exiting. No pending tasks.]
com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@373d727a -- Running DeadlockDetector[Exiting. No pending tasks.]
В web.xml я добавил (перед любыми другими фильтрами):
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Как получить исключение и как этого избежать? Я пытался также OpenSessionInViewInterceptor, но не работал, или я делал что-то не так.
Я потратил много часов, пытаясь решить эту проблему, читая много тем и учебных пособий, но мне ничего не помогло.
Спасибо заранее за любую помощь.