this is my first question at stackoverflow, so please give feedback, if you miss something.
I'm using JPA (Hibernate 3), Spring 3.0.6 and JSF (Icefaces 3.0) for my web application. There are no problems on my local machine, when I use the app. But if a second user starts clicking around, sometimes the following Exception occurs:
"Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access."
I my situation this doesn't make sense, since I only use one JPATransactionManager and one EntityManager (see config below). The only situation, this exception should be thrown is when using multiple transactionmanagers with a single datasource.
(I think) Because of JSF I had many problems with the session and transaction handling and used this solution to get it working.
After a week of many, many different configurations and endlessly trying out things, I can't find the source of the problem. It feels like I totally miss something in the configuration.
BTW: Currently I regularly get the Exception
"null id in xxxxx.xxxx.xxxx entry (don't flush the Session after an exception occurs)"
after a getAll() from a totally different Table. That is, the stacktrace contains yyyy.getAll() and the above expception is thrown. I don't have any idea, where this comes from.
Thank you very much for your help!
Here are my current configs:
applicationContext.xml:
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
<property name="removeAbandonedTimeout" value="180" />
<property name="removeAbandoned" value="true" />
<property name="defaultCatalog" value="${datasource.defaultCatalog}" />
<property name="testWhileIdle" value="true" />
<property name="validationQuery" value="Select 1" />
</bean>
<!-- Spring Data Access Exception Translator Defintion -->
<bean id="jdbcExceptionTranslator"
class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="HomeDao"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${hibernate.show_sql}" />
</bean>
</property>
</bean>
<util:properties id="hibernateProperties">
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
<prop key="hibernate.hbm2ddl.auto">none</prop>
</util:properties>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="openEntityManagerInViewPhaseListener"
class="de.itcampus.endopdb.util.OpenEntityManagerInViewPhaseListener">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="transactionManager" ref="transactionManager"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:annotation-config/>
<aop:aspectj-autoproxy />
<context:component-scan base-package="de.endopdb" />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<!-- spring-security -->
<security:http realm="Sample Realm" entry-point-ref="authenticationEntryPoint"
auto-config="false">
<security:custom-filter ref="sessionManagementFilter"
before="SESSION_MANAGEMENT_FILTER" />
<security:intercept-url pattern="/ifpages/pages/administration/**"
access="ROLE_ADMIN" />
<security:intercept-url pattern="/ifpages/pages/**"
access="ROLE_ADMIN,
ROLE_USER" />
<security:access-denied-handler
error-page="/loginError.xhtml" />
<security:form-login login-page="/loginStart.xhtml" />
<security:logout logout-url="/j_spring_security_logout"
logout-success-url="/logoutSuccess.xhtml" invalidate-session="true" />
</security:http>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/loginStart.xhtml" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
user-service-ref="userDetailsService">
<security:password-encoder hash="md5" />
</security:authentication-provider>
</security:authentication-manager>
<bean id="userDetailsService" class="de.itcampus.endopdb.security.UserDetailsServiceImpl">
</bean>
<bean id="sessionManagementFilter"
class="org.springframework.security.web.session.SessionManagementFilter">
<constructor-arg name="securityContextRepository"
ref="httpSessionSecurityContextRepository" />
<property name="invalidSessionStrategy" ref="invalidSessionStrategy" />
</bean>
<bean id="httpSessionSecurityContextRepository"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
<bean id="invalidSessionStrategy"
class="org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy">
<constructor-arg name="invalidSessionUrl"
value="/ifpages/pages/loginStart.xhtml" />
</bean>
web.xml
<context-param>
<param-name>openEntityManagerInViewPhaseListenerBeanName</param-name>
<param-value>openEntityManagerInViewPhaseListener</param-value>
</context-param>
<filter>
<filter-name>MyJSFCompatibleOpenEntityManagerInViewFilter</filter-name>
<filter-class>de.itcampus.endopdb.util.myJSFCompatibleOpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyJSFCompatibleOpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
// Spring Listener for Request und Session-Scoped beans
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
// Spring Context Loader Listener
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
// SOAP-Servlet
<servlet>
<servlet-name>jaxws-servlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jaxws-servlet</servlet-name>
<url-pattern>/soap</url-pattern>
</servlet-mapping>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
//minutes
<session-timeout>30</session-timeout>
</session-config>
// tomcat basic auth
<security-constraint>
<web-resource-collection>
<web-resource-name>SOAP-Auth</web-resource-name>
<url-pattern>/soap</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>XXXXX</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>SOAP-Auth</realm-name>
</login-config>
<security-role>
<role-name>XXXXXXX</role-name>
</security-role>
//Java Faces
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/icefaces/*</url-pattern>
</servlet-mapping>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Production</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.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>false</param-value>
</context-param>
//Icefaces
<context-param>
<param-name>com.icesoft.faces.standardRequestScope</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.icesoft.faces.synchronousUpdate</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>com.icesoft.faces.webapp.CompatResourceServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/xmlhttp/*</url-pattern>
</servlet-mapping>
faces-config.xml
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
<lifecycle>
<phase-listener>de.itcampus.endopdb.util.OpenEntityManagerInViewPhaseListenerDelegator</phase-listener>
</lifecycle>