代码之家  ›  专栏  ›  技术社区  ›  jMarcel

JSF和JPA:在持久性/模型层中使用Filter

  •  0
  • jMarcel  · 技术社区  · 13 年前

    我正在练习JSF和JPA,下面的例子中有一个用于模型/持久层的过滤器类:

    @WebFilter(servletNames = { "Faces Servlet" })
    public class JPAFilter implements Filter {
    
        private EntityManagerFactory factory;
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            this.factory = Persistence.createEntityManagerFactory("K19-Futebol-PU");
        }
    
        @Override
        public void destroy() {
            this.factory.close();
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
    
            // in
            EntityManager manager = this.factory.createEntityManager();
            request.setAttribute("EntityManager", manager);
            manager.getTransaction().begin();
            // in
    
            // FACES SERVLET
            chain.doFilter(request, response);
            // FACES SERVLET
    
            // out
            try {
                manager.getTransaction().commit();
            } catch (Exception e) {
                manager.getTransaction().rollback();
            } finally {
                manager.close();
            }
            // out
        }
    }
    

    运行应用程序时出现NullPointerException:

    SEVERE: Error Rendering View[/times.xhtml]
    javax.el.ELException: /lista-de-times.xhtml @5,51 rendered="#{empty timeBean.times}": java.lang.NullPointerException
        at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
        at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    
        at filters.JPAFilter.doFilter(JPAFilter.java:42)
    
        Caused by: java.lang.NullPointerException
        at repositories.TimeRepository.getLista(TimeRepository.java:44)
        at managedbeans.TimeBean.getTimes(TimeBean.java:68)
    
        ... 43 more
    
    WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
    java.lang.NullPointerException
        at repositories.TimeRepository.getLista(TimeRepository.java:44)
    
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
        at filters.JPAFilter.doFilter(JPAFilter.java:42)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
    

    这是“存储库”类:

    public class TimeRepository {
    
        private EntityManager manager;
    
        public TimeRepository(EntityManager manager) {
            this.manager = manager;
        }
    
        public void adiciona(Time time) {
            this.manager.persist(time);
        }
    
        @SuppressWarnings("unchecked")
        public void remove(Long id) {
            Time time = this.procura(id);
            Query query = this.manager.createQuery("select x from Jogador x");
            List<Jogador> jogadores = query.getResultList();
            for (Jogador jogador : jogadores) {
                jogador.setTime(null);
            }
            this.manager.remove(time);
        }
    
        public Time atualiza(Time time) {
            return this.manager.merge(time);
        }
    
        public Time procura(Long id) {
            return this.manager.find(Time.class, id);
        }
    
        @SuppressWarnings("unchecked")
        public List<Time> getLista() {
            Query query = this.manager.createQuery("select x from Time x");
            return query.getResultList();
        }
    }
    

    表中已经有一些数据了,我认为这个问题与JSF生命周期和过滤器类有关,但我不知道如何解决它。

    有人能帮帮我吗?我还引用了关于使用所描述的过滤器的评论,我的意思是,这是一个好的实践,一个“优雅的解决方案”吗?

    提前谢谢。

    以下是与存储库相关的TimeBean类:

    @ManagedBean
    public class TimeBean {
    
        private Time time = new Time();
        private List<Time> times;
    
        public void adiciona() {
            EntityManager manager = this.getManager();
            TimeRepository repository = new TimeRepository(manager);
            if (this.time.getId() == null) {
                repository.adiciona(this.time);
            } else {
                repository.atualiza(this.time);
            }
            this.time = new Time();
            this.times = null;
        }
    
        public void preparaAlteracao() {
            Map< String, String> params =
                    FacesContext.getCurrentInstance().getExternalContext().Ã
                    - getRequestParameterMap();
            Long id = Long.parseLong(params.get("id"));
            EntityManager manager = this.getManager();
            TimeRepository repository = new TimeRepository(manager);
            this.time = repository.procura(id);
        }
    
        public void remove() {
            Map< String, String> params =
                    FacesContext.getCurrentInstance().getExternalContext().Ã
                    - getRequestParameterMap();
            Long id = Long.parseLong(params.get("id"));
            EntityManager manager = this.getManager();
            TimeRepository repository = new TimeRepository(manager);
            repository.remove(id);
            this.times = null;
        }
    
        public List<Time> getTimes() {
            if (this.times == null) {
                EntityManager manager = this.getManager();
                TimeRepository repository = new TimeRepository(manager);
                this.times = repository.getLista();
            }
            return this.times;
        }
    
        private EntityManager getManager() {
            FacesContext fc = FacesContext.getCurrentInstance();
            ExternalContext ec = fc.getExternalContext();
            HttpServletRequest request = (HttpServletRequest) ec.getRequest();
            return (EntityManager) request.getAttribute(" EntityManager ");
        }
        // GETTERS E SETTERS
    }
    
    1 回复  |  直到 13 年前
        1
  •  1
  •   David Levesque    13 年前

    看起来您得到的是一个null EntityManager,因为您使用了不同的标识符字符串来设置和获取请求属性:“EntityManager”与“EntityManager”。调用getAttribute时,请尝试删除前导空格和尾随空格(除非它只是代码列表中的一个拼写错误)。