Проблема отложенной загрузки в приложении Spring / Hibernate / Richfaces - PullRequest
2 голосов
/ 11 августа 2010

В приложении Spring я использую компонент rich: tree с Hibernate, который отображает иерархию приложений, использующих ленивую загрузку.Проблема в том, что сессия Hibernate закрыта, что предотвращает отложенную загрузку, и я получаю исключение, когда страница отображается.Наконец, я добавил opensessionViewFilter, который позволяет мне сохранять сеанс до тех пор, пока страница не будет отрисована.

<filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>sessionFactoryBeanName</param-name>
            <param-value>sessionFactory</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

это решение частично решило проблему, когда страница отображается, и отображается компонент rich: Tree, но при выполнении вызовов ajax(навигация между узлами) Я получил ту же ошибку отложенной загрузки:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: myPackage.entities.Module.modules, no session or session was closed
 at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
 at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
 at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
 at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
 at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
 at com.cylande.utilities.TreeNode.getNodes(TreeNode.java:77)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
 at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54)
 at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
 at org.apache.el.parser.AstValue.getValue(AstValue.java:118)
 at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
 at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
 at org.richfaces.component.html.HtmlRecursiveTreeNodesAdaptor.getNodes(HtmlRecursiveTreeNodesAdaptor.java:160)
 at org.richfaces.component.UIRecursiveTreeNodesAdaptor$1.getData(UIRecursiveTreeNodesAdaptor.java:74)
 at org.richfaces.model.StackingTreeModel.getDataModel(StackingTreeModel.java:80)
 at org.richfaces.model.StackingTreeModel.isEmpty(StackingTreeModel.java:107)
 at org.richfaces.model.StackingTreeModel.isLeaf(StackingTreeModel.java:264)
 at org.richfaces.component.UITree.isLeaf(UITree.java:534)
 at org.richfaces.renderkit.html.TreeNodeRenderer.doEncodeBegin(TreeNodeRenderer.java:105)
 at org.richfaces.renderkit.html.TreeNodeRenderer.doEncodeBegin(TreeNodeRenderer.java:86)
 at org.ajax4jsf.renderkit.RendererBase.encodeBegin(RendererBase.java:100)
 at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:813)
 at org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:275)
 at org.richfaces.renderkit.TreeRendererBase$DataVisitorWithLastElement.process(TreeRendererBase.java:255)
 at org.richfaces.model.AbstractTreeDataModel.processElement(AbstractTreeDataModel.java:111)
 at org.richfaces.model.StackingTreeModel.doWalk(StackingTreeModel.java:294)
 at org.richfaces.model.StackingTreeModel$Visitor1.process(StackingTreeModel.java:416)
 at org.richfaces.model.StackingTreeModel$ShiftingDataVisitor.end(StackingTreeModel.java:461)
 at org.richfaces.model.StackingTreeModel.doWalk(StackingTreeModel.java:348)
 at org.richfaces.model.StackingTreeModel.walk(StackingTreeModel.java:383)
 at org.richfaces.component.UITree.walk(UITree.java:422)
 at org.richfaces.renderkit.TreeRendererBase.writeContent(TreeRendererBase.java:683)
 at org.richfaces.renderkit.TreeRendererBase.encodeAjaxChildren(TreeRendererBase.java:475)
 at org.ajax4jsf.component.UIDataAdaptor.encodeAjaxChild(UIDataAdaptor.java:454)
 at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:146)
 at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:83)
 at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:157)
 at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxChildren(AjaxChildrenRenderer.java:83)
 at org.ajax4jsf.renderkit.AjaxChildrenRenderer.encodeAjaxComponent(AjaxChildrenRenderer.java:157)
 at org.ajax4jsf.renderkit.AjaxContainerRenderer.encodeAjax(AjaxContainerRenderer.java:123)
 at org.ajax4jsf.component.AjaxViewRoot.encodeAjax(AjaxViewRoot.java:680)
 at org.ajax4jsf.component.AjaxViewRoot.encodeChildren(AjaxViewRoot.java:551)
 at javax.faces.component.UIComponent.encodeAll(UIComponent.java:930)
 at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:592)
 at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
 at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
 at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:110)
 at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
 at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:266)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
 at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
 at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
 at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
 at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
 at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
 at java.lang.Thread.run(Thread.java:619)

Пожалуйста, вы можете помочь мне с отложенным списком загрузки для компонента ajax.

вот моя страница xhtml:

<h:form>
            <rich:panel>
                <rich:tree>
                    <rich:recursiveTreeNodesAdaptor roots="#{treeBean.srcRouts}"
                        var="item" nodes="#{item.nodes}">
                    </rich:recursiveTreeNodesAdaptor>
                </rich:tree>
            </rich:panel>

</h:form>

Вот бин: TreeBean.java

public class TreeBean {
private List<TreeNode> srcRouts;
@Autowired
private ApplicationDAO applicationDAO;
@Transactional
public List<TreeNode> getSrcRouts() {
    List<TreeNode> ListNode=new ArrayList<TreeNode>();
    if(srcRouts==null)
    {
        List<Application> list=applicationDAO.findAll();
        for(Application app:list)
        {
            TreeNode treeNode=new TreeNode();
            treeNode.setApplication(app);
            ListNode.add(treeNode);
        }
        srcRouts=ListNode;
    }
    return srcRouts;
}

public void setSrcRouts(List<TreeNode> srcRouts) {
    this.srcRouts = srcRouts;
}
}

Вот бин TreeNode.java:

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import myPackage.entities.Application;
import myPackage.entities.Module;
import myPackage.entities.Page;
import myPackage.services.ApplicationDAO;

public class TreeNode {
    private List<TreeNode> nodes;
    private ApplicationDAO applicationDAO;
    private String libelle;
    private Application application;
    private Module module;
    private Page page;

    public Application getApplication() {
        return application;
    }

    public void setApplication(Application application) {
        this.application = application;
    }

    public Module getModule() {
        return module;
    }

    public void setModule(Module module) {
        this.module = module;
    }

    public Page getPage() {
        return page;
    }

    public void setPage(Page page) {
        this.page = page;
    }

    public String getLibelle() {
        return libelle;
    }

    public void setLibelle(String libelle) {
        this.libelle = libelle;
    }

    public ApplicationDAO getApplicationDAO() {
        return applicationDAO;
    }

    public void setApplicationDAO(ApplicationDAO applicationDAO) {
        this.applicationDAO = applicationDAO;
    }

    public List<TreeNode> getNodes() {
        List<TreeNode> listNoeud = new ArrayList<TreeNode>();
        Set<Module> setModule;
        Set<Page> setPage;
        if (nodes == null) {
            // noeud application
            if (application != null) {
                setModule = this.application.getModules();
                for (Module module : setModule) {
                    if(module.getModule()==null){
                    TreeNode treeNode = new TreeNode();
                    treeNode.module = module;
                    listNoeud.add(treeNode);
                }
                }
            }
            // noeud module
            else if (module != null) {
                setModule = this.module.getModules();
                for (Module module : setModule) {
                    TreeNode treeNode = new TreeNode();
                    treeNode.module = module;
                    listNoeud.add(treeNode);
                }
                setPage = this.module.getPages();
                for (Page page : setPage) {
                    TreeNode treeNode = new TreeNode();
                    treeNode.page = page;
                    listNoeud.add(treeNode);
                }
            }
            nodes=listNoeud;
        }

        return nodes;
    }

    public void setNodes(List<TreeNode> nodes) {
        this.nodes = nodes;
    }

    public String toString() {
        String libelle="";

        // noeud application
        if (application != null) {
            libelle = application.getNomApplication();
        }
        // noeud module
        else if (module != null) {
            libelle = module.getNomModule();
        }
        // noeud page
        else if (page != null) {
            libelle = page.getNomPage();
        }
        return libelle;
    }
}

Я использую дерево компонентов для отображенияприложения, добавленные пользователем для тестирования ... На самом деле попробуйте создать приложение, которое запускает тесты, выбранные пользователем.чтобы указать, для меня узел - это приложение, модуль или страница

Вот мой общий DAO:

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class GenericDAOHibernateImpl<T, PK extends Serializable> implements
        GenericDAO<T, PK> {
    private Class<T> type;
    @Autowired
    private HibernateTemplate hibernateTemplate;

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    public GenericDAOHibernateImpl(Class<T> type) {
        this.type = type;
    }

    public PK create(T o) {
        return (PK) getHibernateTemplate().save(o);
    }

    public T read(PK id) {
        return (T) getHibernateTemplate().get(type, id);
    }

    public void update(T o) {
        getHibernateTemplate().update(o);
    }

    public void delete(T o) {
        getHibernateTemplate().delete(o);
    }

    @SuppressWarnings("unchecked")
    public List<T> findAll() {
        List<T> toExport = null;
        toExport = (List<T>) getHibernateTemplate().find(
                "from "+ type.getName());
        return toExport;
    }

    @SuppressWarnings("unchecked")
    public T findByID(PK id) {
        T entity = null;
        entity =  (T)getHibernateTemplate().get(type, id);
        return entity;
    }

}

Заранее благодарю за помощь.

Ответы [ 2 ]

2 голосов
/ 11 августа 2010

У меня нет особого опыта работы с компонентом rich:tree, но есть варианты IMO:

  1. получить дочерние узлы с помощью некоторого метода DAO для данного идентификатора родительского узла.
  2. использовать какую-то "удаленную ленивую загрузку".
  3. не используйте ленивую загрузку.

Я не считаю # 3"решением".

Для # 2 посмотрите на H3T (внимательно прочитайте).

Для реализации # 1 может помочь пост Dynamic Trees в JSF . Это был бы мой выбор.

Дальнейшее чтение

2 голосов
/ 11 августа 2010

У вас есть как минимум два варианта

  • определить коллекцию (*ToMany) с помощью fetchType=FetchType.EAGER
  • вручную инициализировать объект перед «отправкой» его в представление с помощью Hibernate.initialize(..)
...