Hibernate:LazyInitializationException:无法初始化代理 - 没有会话

时间:2018-01-05 07:26:35

标签: java hibernate jpa spring-data-jpa

董事会实体和成员实体不是关联映射

董事会实体类......

@Entity(name = "BOARD")
@Table
@SequenceGenerator(name = "BOARD_SEQ_GENERATOR"
                    , sequenceName = "BOARD_SEQ"
                    , initialValue = 1)
public class BoardEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE
                    , generator = "BOARD_SEQ_GENERATOR")
    private long idx;

    @Lob
    private String contents;

    private String title;

    private long insNo;

    @Temporal(TemporalType.TIMESTAMP)
    private Date insDate;

    private long uptNo;

    @Temporal(TemporalType.TIMESTAMP)
    private Date uptDate;

    @Transient
    private String insName;
    .....
    getter / setter

成员实体类......

@Entity
@Table(name = "MEMBER")
@SequenceGenerator(name = "MEMBERIDX_SEQ_GENERATOR"
                    , sequenceName = "MEMBERIDX_SEQ"
                    , initialValue = 1)
public class MemberEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE
                    , generator = "MEMBERIDX_SEQ_GENERATOR")
    private long memberIdx;

    @Column(nullable = false)
    private String id;

    @Column(nullable = false)
    private String pwd;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private int age;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    private Date insDate;
    .....
    getter / setter

MemberRepository类代码......

@Repository
public interface MemberRepository extends JpaRepository<MemberEntity, Long> {

    @Query("select m from MemberEntity m where m.id=:id")
    public MemberEntity getMemberIDbyId(@Param("id") String id);
}

MemberService类代码......

@Service
@Transactional
public class MemberService {

    @Autowired private MemberRepository memberRepository;

    public void addMember(MemberEntity member) {
        memberRepository.save(member);
    }

    public MemberEntity getMember(Long memberIdx) {
        return memberRepository.getOne(memberIdx);
    }
}

BoardController类代码......

@Controller
@RequestMapping(value = "/board")
public class BoardController {

    @Autowired 
    private BoardService boardService;

    @Autowired
    private MemberService memberService;

    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String BoardList(HttpServletRequest req, HttpServletResponse resp, Model model) throws Exception {

        List<BoardEntity> resutlList = boardService.getBoardList();

        //resutlList.forEach(System.out::println);

        for (BoardEntity item : resutlList) {
            MemberEntity memberEntity = memberService.getMember(item.getInsNo());
            item.setInsName(memberEntity.getName());
        }

        model.addAttribute("boardList", resutlList);

        return "board/boardList";
    }
}

的ErrorMessage

  

심각:Servlet [dispatcher]的Servlet.service()与path []的上下文   抛出异常[请求处理失败;嵌套异常是   org.hibernate.LazyInitializationException:无法初始化代理    - 没有会话]根本原因org.hibernate.LazyInitializationException:无法初始化代理    - org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:147)没有会话     在   org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:260)     在   org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:68)     在   com.knk.spring4.entity.member.MemberEntity _ $$ _ jvst201_0.getName(MemberEntity _ $$ _ jvst201_0.java)     在   com.knk.spring4.controller.board.BoardController.BoardList(BoardController.java:70)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)at   sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)at   java.lang.reflect.Method.invoke(未知来源)at   org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)     在   org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)     在   org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)     在   org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)     在   org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)     在   org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)     在   org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)     在   org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)     在   org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)     在   org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)     在javax.servlet.http.HttpServlet.service(HttpServlet.java:635)at   org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)     在javax.servlet.http.HttpServlet.service(HttpServlet.java:742)at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)     在   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在   org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)     在   org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)     在   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在   org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)     在   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)     在   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)     在   org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)     在   org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)     在   org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)     在   org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)     在   org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)     在   org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)     在   org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)     在   org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)     在   org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)     在   org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)     在   org.apache.coyote.AbstractProtocol $ ConnectionHandler.process(AbstractProtocol.java:868)     在   org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1455)     在   org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)     at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)     在   org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)     在java.lang.Thread.run(未知来源)

ERD

Board表中的InsNo和UptNo列包含创建和编辑帖子的成员的MemberIdx值。

我想使用InsNo列或公告板表的UptNo列导入成员资格表的ID列。

如果没有关联映射,如何处理当前错误?

1 个答案:

答案 0 :(得分:1)

这是因为您使用JpaRepository.getOne方法来检索成员。根据{{​​3}}:

  

T getOne(ID id)

     

返回对具有给定标识符的实体的引用。

     

另见:

     

EntityManager.getReference(Class,Object)

以及JPA repository Javadoc

  

T getReference(Class entityClass,                      对象primaryKey)

     

获取一个实例,其状态可能会被懒散地取出。

基本上JpaRepository.getOne不会从提取的数据库记录返回对象构建,而是引用记录的代理,它将在第一次访问除了引用id。因此,当代理尝试获取记录时,在Session / EntityManager中调用MemberEntity.getName时会出现LazyException。

要在您的情况下修复它,您有多个选项:

  1. 使用EntityManager Javadoc将会话保留在整个请求中,这个是反模式而不推荐
  2. 您可以使用Hibernate注释@Lazy并将lazy属性设置为false(它适用于其他类似情况,不确定它是否可以在此处运行)。这里的缺点是注释不是JPA的注释,所以你要将项目与实现联系起来,而不是规范。
  3. 当会话/实体管理器仍处于打开状态时,您可以通过呼叫任何成员来手动触发代理。
  4. 如果我没记错的话,CrudReposiroty.findOne方法会返回对象,而不是代理。