首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >wicket / hibernate的LazyInitialization异常

wicket / hibernate的LazyInitialization异常
EN

Stack Overflow用户
提问于 2012-01-09 11:41:43
回答 1查看 1.9K关注 0票数 0

我在一个简单的webapp上使用wicket和hibernate (jpa)。

Task.java与Load.java的关系如下:

Task.java:

代码语言:javascript
复制
@ManyToOne( targetEntity=Load.class, optional=true, fetch=FetchType.LAZY)   
@JoinColumn(name="load_id")
public Load getLoad() {
    return load;
}

一个任务可以有最大一个负载,但一个负载可以映射到多个任务:

Load.java:

代码语言:javascript
复制
@OneToMany( mappedBy="load",targetEntity=Task.class,  orphanRemoval=false)
public Set<Task> getTasks() {
    return tasks;
}

会话( JPA中的entityManager)是通过事务过滤器创建并附加到线程上的。

我有一个列出任务的页面,并显示前10个。当我单击指向下一个10的链接时,它尝试加载任务11-20的负载(使用getLoad),并出于某种原因抛出一个LazyInitializationException --尽管是该线程的有效会话(如堆栈跟踪和调试所示)。我不能使用急切的加载,因为这将导致其他地方的问题。我可以检查实体管理器在LinkPanel的构造函数中是否有效,并且它确实有效。然而,3行之后,它将抛出一个LazyInitializationException。到底怎么回事?

代码语言:javascript
复制
- could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    at com.xxx.er.batch.beans.Load_$$_javassist_7.toString(Load_$$_javassist_7.java)
    at com.xxx.er.basman.model.LinkPanel.<init>(LinkPanel.java:41)
    at com.xxx.er.basman.pages.TasksOverviewPage$7.populateItem(TasksOverviewPage.java:130)
    at org.apache.wicket.extensions.markup.html.repeater.data.grid.AbstractDataGridView.populateItem(AbstractDataGridView.java:187)
    at org.apache.wicket.markup.repeater.RefreshingView$1.newItem(RefreshingView.java:114)
    at org.apache.wicket.markup.repeater.DefaultItemReuseStrategy$1.next(DefaultItemReuseStrategy.java:71)
    at org.apache.wicket.markup.repeater.DefaultItemReuseStrategy$1.next(DefaultItemReuseStrategy.java:68)
    at org.apache.wicket.markup.repeater.RefreshingView.addItems(RefreshingView.java:189)
    at org.apache.wicket.markup.repeater.RefreshingView.onPopulate(RefreshingView.java:98)
    at org.apache.wicket.markup.repeater.AbstractRepeater.onBeforeRender(AbstractRepeater.java:131)
    at org.apache.wicket.markup.repeater.AbstractPageableView.onBeforeRender(AbstractPageableView.java:121)
    at org.apache.wicket.Component.internalBeforeRender(Component.java:1066)
    at org.apache.wicket.Component.beforeRender(Component.java:1100)
    at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1754)
    at org.apache.wicket.Component.onBeforeRender(Component.java:3966)
    at org.apache.wicket.Component.internalBeforeRender(Component.java:1066)
    at org.apache.wicket.Component.beforeRender(Component.java:1100)
    at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1754)
    at org.apache.wicket.Component.onBeforeRender(Component.java:3966)
    at org.apache.wicket.Component.internalBeforeRender(Component.java:1066)
    at org.apache.wicket.Component.beforeRender(Component.java:1100)
    at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1754)
    at org.apache.wicket.Component.onBeforeRender(Component.java:3966)
    at org.apache.wicket.Page.onBeforeRender(Page.java:1550)
    at org.apache.wicket.Component.internalBeforeRender(Component.java:1066)
    at org.apache.wicket.Component.beforeRender(Component.java:1100)
    at org.apache.wicket.Component.prepareForRender(Component.java:2292)
    at org.apache.wicket.Page.prepareForRender(Page.java:1540)
    at org.apache.wicket.Component.prepareForRender(Component.java:2329)
    at org.apache.wicket.Page.renderPage(Page.java:911)
    at org.apache.wicket.protocol.http.WebRequestCycle.redirectTo(WebRequestCycle.java:201)
    at org.apache.wicket.request.target.component.PageRequestTarget.respond(PageRequestTarget.java:58)
    at org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:105)
    at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1258)
    at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329)
    at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1436)
    at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
    at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:486)
    at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:319)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
    at com.xxx.er.basman.HibernateTransactionFilter.doFilter(HibernateTransactionFilter.java:58)

为了重新迭代,HibernateTransactionFilter创建了如下所示的EntityManager:

EntityManager em = myEntityManagerFactory.createEntityManager(); em.getTransaction().begin(); entityManagerThreadLocal.set(em);

在LinkPanel构造函数中,我按照以下方式检查这个EntityManager:

EntityManager em = entityManagerThreadLocal.get(); if (em == null) { throw new NullPointerException("No entity manager has been started on this thread: " + Thread.currentThread().getName()); }

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-09 11:54:11

仅仅因为一个实体管理器是打开的,并不意味着所有延迟加载的实体都可以被加载。如果实体是由与“当前”实体不同的实体管理器/会话加载的,则实体仍然是分离的,并且尝试在其上加载延迟关联将导致您遇到的异常。

简而言之,您的过滤器打开了一个实体管理器,这使得延迟加载当前请求成为可能。但是,一旦请求结束,实体就会被分离。

要么在第二个请求时重新加载它们,要么将它们重新附加到当前的实体管理器/会话中。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8787857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档