hibernate - Spring/Hibernate @Transactional - 在它应该之前关闭 session

标签 hibernate spring spring-mvc transactions

我不知道为什么,但是 Hibernate session 提前关闭了,所以我无法获取延迟加载的列表。

在日志中,显示 session 在 DAO 内的 hibernateTemplate.findByNamedParam() 之后立即关闭。

当我运行我的网络应用程序时,我收到以下错误:

Mar 29, 2011 3:13:21 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Spring MVC Dispatcher Servlet] in context with path [/apps] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.communitydriven.apps.entities.Project.tags, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.communitydriven.apps.entities.Project.tags, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
    at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)
    at com.communitydriven.apps.managers.ProjectManager.getProject(ProjectManager.java:98)
    at com.communitydriven.apps.controllers.ProjectController.getViewProject(ProjectController.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    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:76)
    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:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)

我的 DAO:

@Repository
public class ProjectDao implements IProjectDao {

    private HibernateTemplate hibernateTemplate;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
    }

    ...

    /**
     * {@inheritDoc}
     */
    @Override
    public Project getProject(Project project) {
        // Validate required parameters
        if ( (project.getId() == null) ) {
            throw new NullPointerException("Missing required parameter: " + 
                    project.toString());
        }

        // Parameters
        List<String> paramNames = new ArrayList<String>();
        List<Object> values = new ArrayList<Object>();

        // Construct HQL
        StringBuffer hql = new StringBuffer();
        hql.append("from Project p ");

        boolean whereUsed = false; // track of "where" clause has been used

        // Filter by Id
        if (project.getId() != null) {
            whereUsed = DaoUtils.appendFilter(whereUsed, hql);
            hql.append("p.id = :id ");
            paramNames.add("id");
            values.add(project.getId());
        }

        // Get list of matching projects
        @SuppressWarnings("unchecked")
        List<Project> projects = 
            hibernateTemplate.findByNamedParam(
                    hql.toString(),
                    paramNames.toArray(new String[paramNames.size()]), 
                    values.toArray());

        // Get unique result
        Project projectResult = DataAccessUtils.uniqueResult(projects);

        return projectResult;
    }
}

我的经理:

@Component
public class ProjectManager implements IProjectManager {

    @Autowired
    private IProjectDao projectDao;

    ...


    /**
     * {@inheritDoc}
     */
    @Transactional
    @Override
    public ProjectMO getProject(Long projectId) {
        Project project = new Project();
        project.setId(projectId);
        project = projectDao.getProject(project);

        ProjectMO projectMO = new ProjectMO();
        projectMO.setId(project.getId());
        projectMO.setName(project.getName());
        projectMO.setDescription(project.getDescription());

        StringBuffer tags = new StringBuffer();
        final String DELIMITER = ", ";
        for (Tag tag : project.getTags()) {
            tags.append(tag.getName() + DELIMITER);
        }
        projectMO.setTags(tags.toString());

        return projectMO;
    }
}

实体:

@Entity
@Table
public class Project {
    private Long id;
    private String name;
    private String description;
    private User submittedBy;
    private List<Tag> tags;

    public String toString() {
        final String DELIMITER = ", ";
        StringBuffer sb = new StringBuffer();

        sb.append(getClass().getName() + ": [");
        sb.append("id: " + id).append(DELIMITER);
        sb.append("name: " + name).append(DELIMITER);
        sb.append("description: " + description).append("]");

        return sb.toString();
    }

    // GETTERS AND SETTERS //

    @Id
    @Column
    @GeneratedValue
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @Column
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Column
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    @OneToOne
    @JoinColumn
    public User getSubmittedBy() {
        return submittedBy;
    }

    public void setSubmittedBy(User submittedBy) {
        this.submittedBy = submittedBy;
    }

    @ManyToMany
    @JoinTable(name="Projects_Tags", 
            joinColumns={@JoinColumn(name="project_id")}, 
            inverseJoinColumns={@JoinColumn(name="tag_id")})
    public List<Tag> getTags() {
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }
}

我的数据库上下文:

<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-3.0.xsd 
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:property-placeholder location="classpath:database.properties"/>

    <bean id="dataSource" 
             class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="sessionFactory" 
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQLDialect
                hibernate.hbm2ddl.auto=update
            </value>
        </property>
        <property name="packagesToScan" value="com.communitydriven.apps.entities" />
    </bean>

    <tx:annotation-driven />

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory"><ref local="sessionFactory"/></property>
    </bean>

</beans>

最佳答案

您是否设置了OpenSessionInViewFilter ?

关于hibernate - Spring/Hibernate @Transactional - 在它应该之前关闭 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5479558/

相关文章:

java - ssh4 延迟初始化异常

java - 如何使用 Spring Data JPA 删除子记录

java - org.springframework.beans.TypeMismatchException : Failed to convert property value of type [$Proxy133] to required type

java - 获取 jSTL 标签内属性的值

java - hibernate 条件 : distinct entities and then limit

java - 如何在 Java 中像 Entity Framework C# 一样在 hibernate 状态下创建数据库上下文文件

java - 我们应该使用 clone 还是 BeanUtils.copyProperties 以及为什么

java - Spring + Hibernate + Gradle-> org.springframework.beans.factory.BeanCreationException

java - 如何忽略一个实体中的属性而不忽略另一个实体中的属性 - JSON

java - 将 spring mvc 添加到 spring java "desktop"应用程序