使用Facade Pattern和JSF,仅在一个实体中,实体管理器为空

时间:2013-05-23 15:06:30

标签: java jsf jpa

我有一个实体试图调用与DAO交谈的外观(我称之为步骤)。当我观察/设置断点时,仅在这种情况下的实体管理器为空(违规行>> http://goo.gl/rqyRg)。 Java仍然有点绿,希望从你们中间的人中收集一些能够在正确的调试方向上滚动的东西。现在,我怀疑这个问题是我自己的头骨厚度。

这是违规的门面。 << StepsFacade.java>>

package com.mdjdreview.session;

import com.mdjdreview.dao.Steps;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;


@Stateless
public class StepsFacade extends AbstractFacade<Steps> {
    @PersistenceContext(unitName = "MdJdReviewPU2")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public StepsFacade() {
        super(Steps.class);
    }

    public Object findAllRange(int low, int high) {
        try {
            Query q = this.em.createNamedQuery("Steps.findAllRange");
            q.setMaxResults(high);
            q.setFirstResult(low);
            return q.getResultList();
        }
        catch(NoResultException ex) {
            return null;
        }
    }

    public Object findByPatternRange(String title, int low, int high) {
        try {
            Query q = this.em.createNamedQuery("Steps.findByPatternRange");
            q.setParameter("title", title.toUpperCase() + "%");
            q.setMaxResults(high);
            q.setFirstResult(low);
            return q.getResultList();
        }
        catch(NoResultException ex) {
            return null;
        }
    }

    public int findByPatternRangeCount(String title) {
        Query q = this.em.createNamedQuery("Steps.findByPatternRangeCount");
        q.setParameter("title", title.toUpperCase() + "%");
        return ((Long) q.getSingleResult()).intValue();
    }

    public Object findByTitle(String title) {
        try {
            return this.em.createNamedQuery("Steps.findByTitle").setParameter("title", title).getSingleResult();
        }
        catch(NoResultException ex) {
            return null;
        }
    }

    public Object findByProductId(Object productId) {

        try {
            return this.em.createNamedQuery("Steps.findByProductId").setParameter("productId", productId).getResultList();
        } catch (Exception e) {
            System.out.println("----------- findByProductId err "+e.getLocalizedMessage());
            System.out.println("----------- findByProductId err "+e.getMessage());
            System.out.println("----------- findByProductId err "+e.getStackTrace());
            System.out.println(productId);
            return e.getMessage();
        }
    }

    public int findByProductQuestionCount(Object productId) {
        Query q = this.em.createNamedQuery("Steps.findByProductQuestionCount");
        q.setParameter("productId", productId);

        if(q.getSingleResult() == null) {
            return 0;
        }
        else {
            return ((Long) q.getSingleResult()).intValue();
        }
    }

    public int findBySlideStepCount(Object slidesId) {
        Query q = this.em.createNamedQuery("Steps.findBySlideStepCount");
        q.setParameter("slidesId", slidesId);

        if(q.getSingleResult() == null) {
            return 0;
        }
        else {
            return ((Long) q.getSingleResult()).intValue();
        }
    }

    public int findByCategoryStepCount(Object categoriesId) {
        Query q = this.em.createNamedQuery("Steps.findByCategoryStepCount");
        q.setParameter("categoriesId", categoriesId);

        if(q.getSingleResult() == null) {
            return 0;
        }
        else {
            return ((Long) q.getSingleResult()).intValue();
        }
    }

    public int findByModuleStepCount(Object modulesId) {
        Query q = this.em.createNamedQuery("Steps.findByModuleStepCount");
        q.setParameter("modulesId", modulesId);

        if(q.getSingleResult() == null) {
            return 0;
        }
        else {
            return ((Long) q.getSingleResult()).intValue();
        }
    }

    public Object findByExamStep(Object step, Object generatedExamsId) {
        try {
            Query q = this.em.createNamedQuery("Steps.findByExamStep");
            q.setParameter("step", step);
            q.setParameter("generatedExamsId", generatedExamsId);
            q.setMaxResults(1);
            q.setFirstResult(0);
            return q.getSingleResult();
        }
        catch(NoResultException ex) {
            return null;
        }
    }

    /**
     * @param em the em to set
     */
    public void setEntityManager(EntityManager em) {
        this.em = em;
    }
}

而且,令人费解的是,这里有一个几乎相同代码的Facade,效果很好。 &LT;&LT; AnswersFacade.java&gt;&gt;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.mdjdreview.session;

import com.mdjdreview.dao.Answers;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author nick
 */
@Stateless
public class AnswersFacade extends AbstractFacade<Answers> {
    @PersistenceContext(unitName = "MdJdReviewPU2")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public AnswersFacade() {
        super(Answers.class);
    }

    public Object findByQuestionId(Object questionId) {
        try {
            return this.em.createNamedQuery("Answers.findByQuestionId").setParameter("questionId", questionId).getResultList();
        }
        catch(NoResultException ex) {
            return null;
        }
    }

    public Object findAllRange(int low, int high) {
        try {
            Query q = this.em.createNamedQuery("Answers.findAllRange");
            q.setMaxResults(high);
            q.setFirstResult(low);
            return q.getResultList();
        }
        catch(NoResultException ex) {
            return null;
        }
    }

    public Object findByPatternRange(String title, int low, int high) {
        try {
            Query q = this.em.createNamedQuery("Answers.findByPatternRange");
            q.setParameter("title", title.toUpperCase() + "%");
            q.setMaxResults(high);
            q.setFirstResult(low);
            return q.getResultList();
        }
        catch(NoResultException ex) {
            return null;
        }
    }

    public int findByPatternRangeCount(String title) {
        Query q = this.em.createNamedQuery("Answers.findByPatternRangeCount");
        q.setParameter("title", title.toUpperCase() + "%");
        return ((Long) q.getSingleResult()).intValue();
    }
}

这是调用Facade的实体,&lt;&lt; ExamResults.java&gt;&gt;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mdjdreview.entities;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.ChartSeries;
import org.primefaces.model.chart.PieChartModel;

// I need to import this package to allow for access to the category object
import com.mdjdreview.dao.Steps;
import com.mdjdreview.dao.Categories;
import com.mdjdreview.session.StepsFacade;
import com.mdjdreview.session.CategoriesFacade;
import com.mdjdreview.session.ProductToCategoriesFacade;
import com.mdjdreview.session.ProductToStepsFacade;

import java.util.List;
import java.util.Map;

import javax.ejb.EJB;

/**
 *
 * @author joshua
 * this is where we layout the graph
 * 
 */
@ManagedBean
@ViewScoped
public class ExamResults implements Serializable {

    private CartesianChartModel categoryModel;
    private PieChartModel pieModel;

    @EJB
    private StepsFacade stepsFacade = new StepsFacade();

    @EJB
    private CategoriesFacade categoryFacade = new CategoriesFacade();

    public ExamResults() {
        createCategoryModel();
    }

    public CartesianChartModel getCategoryModel() {
        return categoryModel;
    }

    public PieChartModel getPieModel() {
        return pieModel;
    }
     // this one draws out the graph

    private void createCategoryModel() {
        categoryModel = new CartesianChartModel();

        Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        // TODO: this is not called eamxId, this is a productId don't forget to change this
        String productId = (String) requestMap.get("productId");

        System.out.println("--------------------------- prouctID = "+productId);


        List<Categories> cats;

        List<Steps> steps;

        try {
            steps = (List<Steps>)this.stepsFacade.findByProductId((Object)productId);
            int itemCount = steps.size();
            System.out.println("setps in list = "+itemCount);
        } catch (Exception e) {
            System.out.println("no steps for you");
            System.out.println(e.getMessage());
        }

        try {

            cats = this.categoryFacade.findByTypeParentId((Object)productId, "question");
            int itemCount = cats.size();
            System.out.println("cats in list = "+itemCount);

        } catch (Exception e) {
            System.out.println("no, dice on the categories");
        }

        //


        System.out.println("just tried to pull steps what's above this line?");


        ChartSeries correct = new ChartSeries();
        correct.setLabel("Correct");
        // what they got right
        // setp 1: 
            // <LIST> Step pull back by the steps facade
            // <LIST> Keywords
            // <LIST> Catnames 

        // step 2: loop through steps, query category ID

        // that 90 there for heart is a magic number, that needs to be pulled in dynamically
        // it looks lie in the AnswersToCategories dao, we can pull the 

        correct.set("Heart", 90);
        correct.set("Bacteria", 100);
        correct.set("Mitral Valve", 44);
        correct.set("Pediatrics", 80);
        correct.set("OBGYN", 25);

        ChartSeries missed = new ChartSeries();
        missed.setLabel("Missed");
        // what they got wrong
        missed.set("Heart", 10);
        missed.set("Bacteria", 0);
        missed.set("Mitral Valve", 56);
        missed.set("Pediatrics", 20);
        missed.set("OBGYN", 75);
// auto create x & y
        categoryModel.addSeries(correct);
        categoryModel.addSeries(missed);
    }   
}

以下是我到目前为止尝试修复的内容:

  1. 我已经倾倒了应用程序服务器(GlassFish)的启动输出,没有看到任何内容,每个人都很高兴,没有警告,错误或更高的东西,只是一堆信息。
  2. 我遍布Stack Overflow,很多代码看起来与此完全相同,并且无法提醒任何线索。
  3. 我想,从我的实体,希望外墙(http://goo.gl/MSl8F)应该被注入并尝试不实例化新的外观对象(以下),但这只会产生更多问题(当破坏点时外墙为空)。
  4. @EJB
    private StepsFacade stepsFacade;
    
    @EJB
    private CategoriesFacade categoryFacade;
    

    有什么想法吗?谢谢你的期待。

1 个答案:

答案 0 :(得分:6)

这是不对的:

@EJB
private StepsFacade stepsFacade = new StepsFacade();

@EJB
private CategoriesFacade categoryFacade = new CategoriesFacade();

public ExamResults() {
    createCategoryModel();
}

以下是两个主要错误:

  1. 您不应该自己实例化EJB。容器负责它。您应该通过@EJB通过容器注入它们。容器还将注意每个EJB依次通过@PersistenceContext注入正确的实体管理器。
  2. 您不应该尝试在构造函数中使用EJB。它们不是在那时注入的。在构造实例之前,无法在Java中设置实例变量。您应该使用@PostConstruct。容器将在构造和依赖注入后直接调用它。
  3. 这是对的:

    @EJB
    private StepsFacade stepsFacade;
    
    @EJB
    private CategoriesFacade categoryFacade;
    
    @PostConstruct
    public void init() { // Note: method name is fully to your choice.
        createCategoryModel();
    }
    

    另见: