【问题标题】:Hibernate: LazyInitializationException: could not initialize proxy - no Session休眠:LazyInitializationException:无法初始化代理 - 没有会话
【发布时间】:2018-01-05 07:26:34
【问题描述】:

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

板实体类...

@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";
    }
}

错误消息

심각: Servlet.service() 用于 servlet [dispatcher] 在上下文中的路径 [] 抛出异常[请求处理失败;嵌套异常是 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) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)在 java.lang.reflect.Method.invoke(未知来源)在 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) 在 org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:742) 在 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) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(Unknown Source)

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

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

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

【问题讨论】:

    标签: java hibernate jpa spring-data-jpa


    【解决方案1】:

    这是因为您正在使用JpaRepository.getOne 方法来检索成员。根据JPA repository Javadoc

    T getOne(ID id)

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

    另见:

    EntityManager.getReference(类,对象)

    还有EntityManager Javadoc

    T getReference(Class entityClass, 对象primaryKey)

    获取一个实例,其状态可能会被延迟获取。

    基本上JpaRepository.getOne 不会从获取的数据库记录返回一个对象构建,而是一个引用该记录的代理,它将在第一次访问除引用 id 之外的任何成员时初始化。因此,当您在 Session/EntityManager 中调用 MemberEntity.getName 时,当代理尝试获取记录时,您会收到 LazyException。

    要在您的情况下修复它,您有多种选择:

    1. 使用OpenSessionInViewFilter 将会话保留在整个请求中,这是一种反模式,不推荐使用
    2. 您可以使用 Hibernate 注释 @Lazy 并将惰性属性设置为 false(在其他类似情况下也可以使用,不确定是否可以在这里使用)。这里的缺点是注释不是 JPA 的注释,因此您会将项目与实现而非规范联系起来。
    3. 您可以在 Session/EntityManager 仍然打开时通过调用任何成员手动触发代理。
    4. 如果我没记错的话,CrudReposiroty.findOne 方法返回的是对象而不是代理。

    【讨论】:

      猜你喜欢
      • 2010-09-25
      • 2018-09-28
      • 2019-06-29
      • 2013-01-10
      • 1970-01-01
      • 2016-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多