jpa查询关联表懒加载数据initialize proxy no session

spring jpa could not initialize proxy - no Session

知兮丶青 异常 · spring
阅读(1398) 2018-01-20
jpa查询关联表懒加载数据initialize proxy no session
jpa查询关联表懒加载数据initialize proxy no session

springmvc4+jpa在service查询关联关系表的时候返回懒加载数据,当希望获取懒加载的时候发现session已经关闭了,然而我们不希望在service层就关闭session,懒加载的数据可能还需获取。例如一对多关联关系。



一对多关系

实体类:Teacher.java

//懒加载
@OneToMany(fetch= FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name="teacher_id")
public Set<Student> getStudents() {
    return students;
}

实体类:Student.java

//懒加载
@ManyToOne(fetch= FetchType.LAZY)
@JoinColumn(name="teacher_id")
public Teacher getTeacher() {
    return teacher;
}

Teacher和Student表,一对多关联关系,并加上了懒加载。



关联关系懒加载

例如在查询一条学生信息,Student关联了Teacher。

在用Jpa Repository 查询完的时候已经session已经关闭,在获取Teacher的时候抛出could not initialize proxy - no Session

@Autowired
private StudentRepository studentRepository;

@Override
public Student findById(Long id){
    Student student = studentRepository.findOne(id);
    Teacher teacher = student.getTeacher();
    System.out.println(teacher);
    Set<Student> students = teacher.getStudents();
    System.out.println(students);
    return student;
}



解决办法

很简单的,springmvc已经为我们提供了事务注解。直接注解@Transactional就OK。

import org.springframework.transaction.annotation.Transactional;

...

@Override
@Transactional(readOnly = true)//查询的只读就行
public Student findById(Long id){
    Student student = studentRepository.findOne(id);
    Teacher teacher = student.getTeacher();
    System.out.println(teacher);
    Set<Student> students = teacher.getStudents();
    System.out.println(students);
    return student;
}



注解不生效

1、是否开启了对注解的解析,如:

<context:annotation-config/>
...
<context:component-scan base-package="com.weizhixi.*" />
...
<tx:annotation-driven transaction-manager="jpaTransactionManager" />

2、spring初始化是否加入

<init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-*.xml</param-value>
</init-param>



异常参考

严重: Servlet.service() for servlet [spring] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: could not initialize proxy - no Session] with root cause
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165)
	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
	at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
	at com.weizhixi.entity.Teacher_$$_jvst6e0_1.toString(Teacher_$$_jvst6e0_1.java)
	at java.lang.String.valueOf(String.java:2847)
	at java.io.PrintStream.println(PrintStream.java:821)
	at org.apache.tomcat.util.log.SystemLogHandler.println(SystemLogHandler.java:269)
	at com.weizhixi.service.impl.StudentServiceImpl.findById(StudentServiceImpl.java:29)
	at com.weizhixi.controller.IndexController.find(IndexController.java:31)
	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.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1083)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:640)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)



原创文章,转载请注明出处:https://www.weizhixi.com/article/63.html