我在 SO 上找到了关于这个问题的几个问题和答案,但它们似乎都涵盖了问题的一个主要原因:在事务之外或另一个事务中获取集合。但在我的情况下,我在获取父对象和集合时在同一个事务中获取。
@Service
@Transactional
public class IntegrationServiceImpl implements IntegrationService {
@Override
public Integration getIntegrationByIdFetchBackendParameters(Long integrationId) {
Integration integration = integrationDao.get(integrationId);
//not all integrations have to have backend.
if (integration.getBackend() != null) {
Hibernate.initialize(integration.getBackend().getBackendParameters());
}
return integration;
}
...
但是当涉及到 Hibernate.initialize 这个分支在 org.hibernate.collection.internal.AbstractPersistentCollection 被执行
if ( session == null ) {
throw new HibernateException( "collection is not associated with any session" );
}
我不明白session
为什么null
。有人会解释这一点并提出解决方案吗?
编辑 1 - 完整堆栈跟踪
org.hibernate.HibernateException: collection is not associated with any session
at org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:676)
at org.hibernate.Hibernate.initialize(Hibernate.java:77)
at com.dhl.finFw.service.IntegrationServiceImpl.getIntegrationByIdFetchBackendParameters(IntegrationServiceImpl.java:169)
at com.dhl.finFw.web.integration.IntegrationOverviewManagedBean.loadIntegration(IntegrationOverviewManagedBean.java:59)
at com.dhl.finFw.web.integration.AbstractIntegrationManagedBean.initCommonFields(AbstractIntegrationManagedBean.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:344)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:295)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:130)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1481)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:333)
at com.dhl.finFw.spring.scope.ViewScope.get(ViewScope.java:30)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:329)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117)
at org.springframework.beans.factory.access.el.SpringBeanELResolver.getValue(SpringBeanELResolver.java:56)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:72)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:68)
at org.apache.el.parser.AstValue.getValue(AstValue.java:161)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at com.sun.faces.facelets.tag.jstl.core.ForEachHandler.apply(ForEachHandler.java:161)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:166)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:320)
at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:379)
at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:358)
at com.sun.faces.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:199)
at com.sun.faces.facelets.tag.ui.IncludeHandler.apply(IncludeHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at com.sun.faces.facelets.tag.ui.DefineHandler.applyDefinition(DefineHandler.java:106)
at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:178)
at com.sun.faces.facelets.impl.DefaultFaceletContext$TemplateManager.apply(DefaultFaceletContext.java:395)
at com.sun.faces.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletContext.java:366)
at com.sun.faces.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:111)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:187)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at com.sun.faces.facelets.tag.jsf.core.ViewHandler.apply(ViewHandler.java:179)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:320)
at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:379)
at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:358)
at com.sun.faces.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:199)
at com.sun.faces.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:155)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:164)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:870)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:99)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.dhl.finFw.web.filter.FileNotFoundFilter.doFilter(FileNotFoundFilter.java:40)
at com.dhl.finFw.web.filter.FileNotFoundFilter.doFilter(FileNotFoundFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:64)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
编辑 2 - 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<bean id="environmentVariablesConfiguration"
class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="passwordSysPropertyName" value="APP_ENCRYPTION" />
</bean>
<bean id="configurationEncryptor"
class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="config" ref="environmentVariablesConfiguration" />
</bean>
<bean id="propertyConfigurer"
class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer">
<constructor-arg ref="configurationEncryptor" />
<property name="locations">
<list>
<value>${finFw.config.location}finFwUI.properties</value>
<value>classpath:application.properties</value>
<value>classpath:dateTime.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
</bean>
<context:component-scan base-package="com.dhl.finFw"/>
<context:annotation-config/>
<tx:annotation-driven/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="FINFW"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="${finFwUI.orm.generateDdl:false}"/>
<property name="showSql" value="${finFwUI.orm.showSql:false}"/>
<property name="databasePlatform" value="${finFwUI.orm.dialect}"/>
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<aop:aspectj-autoproxy/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="view">
<bean class="com.dhl.finFw.spring.scope.ViewScope"/>
</entry>
</map>
</property>
</bean>
<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
<property name="attributes">
<map>
<entry key="finFwUIEnvironment" value="${finFwUI.environment}" />
</map>
</property>
</bean>
<bean id="eventListenerBean" class="com.dhl.finFw.spring.FinFwApplicationListener" />
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>FinFwUI</display-name>
<description>Financial Framework Configuration</description>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>fileServlet</servlet-name>
<servlet-class>com.dhl.finFw.web.FileServlet</servlet-class>
</servlet>
<!-- Location of the Log4J config file, for initialization and refresh checks.
Applied by Log4jConfigListener. The variable is replaced with System property
at runtime. -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>${finFw.config.location}log4j-finFwUI.properties</param-value>
</context-param>
<!-- Application version. The variable is replaced during Maven build. -->
<context-param>
<param-name>applicationVersion</param-name>
<param-value>${applicationVersion}</param-value>
</context-param>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>dhl</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/springsecurity.taglib.xml</param-value>
</context-param>
<!-- possible values: Development, Production, SystemTest, UnitTest The
variable is replaced during Maven build or set as System property during
development. -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>${finFwUI.jsf.stage}</param-value>
</context-param>
<!-- Spring application context config locations -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:com/dhl/finFw/finFwUI-core.xml
classpath:com/dhl/finFw/finFwUI-dataSource.xml
classpath:com/dhl/finFw/finFwUI-security.xml
classpath:com/dhl/finFw/finFwUI-forms.xml
classpath:com/dhl/finFw/finFwUI-audit.xml
</param-value>
</context-
<context-param>
<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
<param-value>true</param-value>
</context-param>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<!-- Configures Log4J for this web app. As this context specifies a context-param
"log4jConfigLocation", its file path is used to load the Log4J configuration. -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Starts Spring application context. The parent one. The web context
is started by Dispatcher servlet. -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>fileServlet</servlet-name>
<url-pattern>/file/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/pages/protected/index.xhtml</welcome-file>
</welcome-file-list>
<filter>
<filter-name>encoding-filter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>fileNotFoundFilter</filter-name>
<filter-class>com.dhl.finFw.web.filter.FileNotFoundFilter</filter-class>
</filter>
<filter>
<filter-name>browserCacheControlFilter</filter-name>
<filter-class>com.dhl.finFw.web.filter.BrowserCacheControlFilter</filter-class>
</filter>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>fileNotFoundFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>browserCacheControlFilter</filter-name>
<url-pattern>/pages/protected/integration/subscriptionScheduler.xhtml</url-pattern>
</filter-mapping>
<error-page>
<exception-type>org.springframework.security.access.AccessDeniedException</exception-type>
<location>/pages/public/error/accessDenied.xhtml</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/pages/public/error/internal.xhtml</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/pages/public/error/internal.xhtml</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/pages/public/error/notFound.xhtml</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/pages/public/error/accessDenied.xhtml</location>
</error-page>
</web-app>
ViewScope.java
public class ViewScope implements Scope {
private Logger logger = LoggerFactory.getLogger(getClass());
public static final String VIEW_SCOPE_CALLBACKS = "viewScope.callbacks";
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
Map<String, Object> viewMap = getViewMap();
Object instance = viewMap.get(name);
if (instance == null) {
instance = objectFactory.getObject();
synchronized (viewMap) {
viewMap.put(name, instance);
logger.debug("Bean '{}' has been put to ViewScope.", instance);
}
} else {
logger.debug("Going to return an existing bean '{}'", instance);
}
return instance;
}
@Override
public Object remove(String name) {
Object instance = getViewMap().remove(name);
if (instance != null) {
Map<String, Runnable> callbacks = (Map<String, Runnable>) getViewMap().get(VIEW_SCOPE_CALLBACKS);
if (callbacks != null) {
callbacks.remove(name);
logger.debug("Bean '{}' has been removed.", instance);
}
}
return instance;
}
@Override
public void registerDestructionCallback(String name, Runnable runnable) {
Map<String, Runnable> callbacks = (Map<String, Runnable>) getViewMap().get(VIEW_SCOPE_CALLBACKS);
if (callbacks != null) {
callbacks.put(name, runnable);
logger.debug("Registered callback for '{}'", name);
}
}
/**
* {@inheritDoc}
*/
@Override
public Object resolveContextualObject(String name) {
FacesContext facesContext = FacesContext.getCurrentInstance();
FacesRequestAttributes facesRequestAttributes = new FacesRequestAttributes(facesContext);
return facesRequestAttributes.resolveReference(name);
}
@Override
public String getConversationId() {
FacesContext facesContext = FacesContext.getCurrentInstance();
FacesRequestAttributes facesRequestAttributes = new FacesRequestAttributes(facesContext);
return facesRequestAttributes.getSessionId() + "-" + facesContext.getViewRoot().getViewId();
}
private Map<String, Object> getViewMap() {
return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
}
}