我有开放会话的问题。首先我使用Spring 4.0 + JSF 2.2 + Hibernate 4.3。要提供开放会话,我使用 org.springframework.orm.hibernate4.support.OpenSessionInViewFilter 。 它部分工作,我从数据库中获取一些实体,渲染视图和延迟加载工作正确。
但是在渲染视图后我在p:dataGrid中使用分页我得到了延迟初始化异常。我怎么能避免这种情况?我希望只要管理bean存在,对象就会连接到会话。如何在没有延迟初始化错误的情况下进行分页工作?
要解决此问题,我尝试使用检查我的管理bean会发生什么。我不知道我是否理解它是正确的但是当我使用视图范围bean时我虽然总是它应该是一个处理这个bean的线程。但是当我打印线程id时,它看起来对于每个请求tomcat都使用新线程。这是正确的行为吗?之前,我没有使用spring,我在视图过滤器中使用标准的开放会话,并将 hibernate.current_session_context_class 设置为 org.hibernate.context.ThreadLocalSessionContext ,一切都很完美。我尝试在这里使用相同的设置,但它会导致许多错误,我读到当我使用春天提供的过滤器时,我不应该弄乱它。我使用Tomcat 7.0.34和hibernate-c3p0 4.3。
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>
Hibernate配置:
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>system.properties</value>
</property>
</bean>
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- c3p0 props-->
<property name="minPoolSize" value="${c3p0.minPoolSize}" />
<property name="maxPoolSize" value="${c3p0.maxPoolSize}" />
<property name="maxIdleTime" value="${c3p0.maxIdleTime}" />
<property name="maxStatements" value ="${c3p0.maxStatements}" />
</bean>
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.validator.apply_to_ddl">false</prop>
</props>
</property>
<property name="packagesToScan" value="com.efsf.ostoja" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
管理bean:
package com.efsf.ostoja.clientCase.view;
import com.efsf.ostoja.clientCase.logic.interfaces.ICaseService;
import com.efsf.ostoja.clientCase.model.ClientCase;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import lombok.Getter;
import lombok.Setter;
@ViewScoped
@ManagedBean
public class MarketMB implements Serializable{
@Getter @Setter
private List<ClientCase> cases;
@ManagedProperty(value = "#{caseService}")
@Getter @Setter
private ICaseService service;
@PostConstruct
public void init(){
cases=service.getAllActiveCases();
System.out.println("Id: "+Thread.currentThread().getId());
}
public void test(){
System.out.println("Id2: "+Thread.currentThread().getId());
}
}
服务方法:
@Override
@Transactional
public List<ClientCase> getAllActiveCases(){
return clientCaseDao.findAllByProperty("status", CaseStatus.NEW);
}
我的部分观点:
<h:form>
<p:dataGrid value="#{marketMB.cases}" var="c" id="paginatorTable" styleClass="simplePagination" paginator="true" rows="5" columns="1" paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}">
//some div with data here
</p:dataGrid>
</h:form>