Я использую wicket и hibernate (jpa) на простой webapp.
Task.java связан с Load.java следующим образом:LazyInitialization Exception with wicket/hibernate
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, она пытается загрузить Load for Tasks 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()); }
Странно, я обнаружил, что могу обойти это. В фильтре транзакции после запуска 'chain.doFilter (request, response)' я извлекаю EntityManager, а затем получаю транзакцию, и если он не отмечен для отката, я фиксирую txn и закрываю entitymanager. Хорошо, если я совершу транзакцию, но оставьте объект entitymanager открытым, то, похоже, он оборачивает эту проблему. Теперь мне нужно проверить, что это не вызывает никаких других ... – mdarwin
Я также заметил, что калитка, кажется, отправляет 2 запроса, когда я нажимаю ссылку на странице задач задач (ссылка, которая приводит меня к странице, где я просматриваю задачи 11-20) – mdarwin