LazyInitialization Исключение с калиткой / гибернацией - PullRequest
0 голосов
/ 09 января 2012

Я использую wicket и hibernate (jpa) в простом веб-приложении.
Task.java связан с Load.java следующим образом:

Task.java:

@ManyToOne( targetEntity=Load.class, optional=true, fetch=FetchType.LAZY)   
@JoinColumn(name="load_id")
public Load getLoad() {
    return load;
}

Одна задача может иметь максимум одну загрузку, но одна загрузка может отображаться на несколько задач:
Load.java:

@OneToMany( mappedBy="load",targetEntity=Task.class,  orphanRemoval=false)
public Set<Task> getTasks() {
    return tasks;
}

Сессии (entityManager на языке JPA) создаются и присоединяютсяв поток с помощью фильтра транзакций.

У меня есть страница, на которой перечислены задачи и показаны первые 10. Когда я нажимаю ссылку на следующие 10, она пытается загрузить файл «Загрузка для задач» 11-20.(используя getLoad) и по какой-то причине выдает исключение LazyInitializationException - хотя является допустимым сеансом для этого потока (как видно из трассировки стека и отладки).Я не могу использовать загрузку EAGER, так как это вызовет проблемы в другом месте.Я могу проверить, что EntityManager действителен в конструкторе LinkPanel, и он действительно действителен.Однако через 3 строки он вызывает исключение LazyInitializationException.В чем дело?

- 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()); }

1 Ответ

4 голосов
/ 09 января 2012

То, что менеджер сущностей открыт, не означает, что можно загружать все ленивые сущности. Если сущности были загружены менеджером / сеансом сущностей, отличным от «текущего», сущности все еще отсоединены, и попытка загрузить на них ленивую ассоциацию приведет к исключению, с которым вы столкнулись.

Короче говоря, ваш фильтр открывает менеджер сущностей, который делает возможной отложенную загрузку для текущего запроса. Но как только запрос заканчивается, сущности отсоединяются.

Либо перезагрузите их при втором запросе, либо подключите их к текущему администратору / сеансу объекта.

...