具有开放会话分页的Spring + JSF不起作用

时间:2014-05-16 06:15:05

标签: java spring hibernate jsf

我有开放会话的问题。首先我使用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>

0 个答案:

没有答案