0

我将 JSF2.0 与 EJB 和 JPA 一起使用。我已经尝试使用 EJB Facade 的 create 方法添加新记录,并且没有遇到任何问题。

但是现在我无法在我的表中添加类型为 Question 的新记录。我会将代码发布到我的实体、控制器和 EJB 外观文件中,但我想补充一点,我的 Question 实体有一个外键,称为 Questionnaire 类型的 questionsid。

没有添加新记录,并且我的尝试中没有任何错误。甚至我的问卷 ID 也正确返回。唯一没有做的是persist()。

这是我的控制器中的创建方法:

 public void createMultipleChoiceSingleAnswerQuestion() {
    try {
        currentQuestion = new Question();
        currentQuestion.setId(0);
        currentQuestion.setQuestionnaireid(currentQuestionnaire);
        getFacade().create(currentQuestion);
        //System.out.println("QUESTIONNAIRE IIIIIIIDDDDDDDDDDD: "+currentQuestionnaire.getId());
        //getFacade().create(q);
    } catch (Exception e) {
        System.out.println("ERRORRRR: "+e.getMessage());

    }
}

这是我的问题实体:

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

import java.io.Serializable;
import java.util.Collection;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author Pedram
 */
@Entity
@Table(name = "question")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Question.findAll", query = "SELECT q FROM Question q"),
    @NamedQuery(name = "Question.findById", query = "SELECT q FROM Question q WHERE q.id = :id"),
    @NamedQuery(name = "Question.findByType", query = "SELECT q FROM Question q WHERE q.type = :type"),
    @NamedQuery(name = "Question.findByMandatory", query = "SELECT q FROM Question q WHERE q.mandatory = :mandatory"),
    @NamedQuery(name = "Question.findByOrdernumber", query = "SELECT q FROM Question q WHERE q.ordernumber = :ordernumber"),
    @NamedQuery(name = "Question.findByWeight", query = "SELECT q FROM Question q WHERE q.weight = :weight"),
    @NamedQuery(name = "Question.findByQuestionnaire", query = "SELECT q FROM Question q WHERE q.questionnaireid = :questionnaireid"),
    @NamedQuery(name = "Question.findByTag", query = "SELECT q FROM Question q WHERE q.tag = :tag")})
public class Question implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @NotNull
    @Column(name = "id")
    private Integer id;
    @Size(max = 40)
    @Column(name = "type")
    private String type;
    @Lob
    @Size(max = 65535)
    @Column(name = "questiontext")
    private String questiontext;
    @Lob
    @Size(max = 65535)
    @Column(name = "answertext")
    private String answertext;
    @Column(name = "mandatory")
    private Boolean mandatory;
    @Lob
    @Size(max = 65535)
    @Column(name = "correctanswer")
    private String correctanswer;
    @Column(name = "ordernumber")
    private Integer ordernumber;
    @Column(name = "weight")
    private Integer weight;
    @Size(max = 40)
    @Column(name = "tag")
    private String tag;
    @OneToMany(mappedBy = "questionid")
    private Collection<Textanswer> textanswerCollection;
    @JoinColumn(name = "questionnaireid", referencedColumnName = "id")
    @ManyToOne
    private Questionnaire questionnaireid;
    @OneToMany(mappedBy = "questionid")
    private Collection<Choiceanswer> choiceanswerCollection;

    public Question() {
    }

    public Question(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getQuestiontext() {
        return questiontext;
    }

    public void setQuestiontext(String questiontext) {
        this.questiontext = questiontext;
    }

    public String getAnswertext() {
        return answertext;
    }

    public void setAnswertext(String answertext) {
        this.answertext = answertext;
    }

    public Boolean getMandatory() {
        return mandatory;
    }

    public void setMandatory(Boolean mandatory) {
        this.mandatory = mandatory;
    }

    public String getCorrectanswer() {
        return correctanswer;
    }

    public void setCorrectanswer(String correctanswer) {
        this.correctanswer = correctanswer;
    }

    public Integer getOrdernumber() {
        return ordernumber;
    }

    public void setOrdernumber(Integer ordernumber) {
        this.ordernumber = ordernumber;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    @XmlTransient
    public Collection<Textanswer> getTextanswerCollection() {
        return textanswerCollection;
    }

    public void setTextanswerCollection(Collection<Textanswer> textanswerCollection) {
        this.textanswerCollection = textanswerCollection;
    }

    public Questionnaire getQuestionnaireid() {
        return questionnaireid;
    }

    public void setQuestionnaireid(Questionnaire questionnaireid) {
        this.questionnaireid = questionnaireid;
    }

    @XmlTransient
    public Collection<Choiceanswer> getChoiceanswerCollection() {
        return choiceanswerCollection;
    }

    public void setChoiceanswerCollection(Collection<Choiceanswer> choiceanswerCollection) {
        this.choiceanswerCollection = choiceanswerCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Question)) {
            return false;
        }
        Question other = (Question) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "model.Question[ id=" + id + " ]";
    }

}

这是我的 EJB 外观类:

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

import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import model.Question;
import model.Questionnaire;

/**
 *
 * @author Pedram
 */
@Stateless
public class QuestionFacade extends AbstractFacade<Question> {
    @PersistenceContext(unitName = "MobileSamplingToolkit0.4PU")
    private EntityManager em;
    List<Question> results = null;

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

    public QuestionFacade() {
        super(Question.class);
    }

    public List<Question> getQuestionsByQuestionnaire(Questionnaire questionnaire){
        try {
            em = Persistence.createEntityManagerFactory("MobileSamplingToolkit0.4PU").createEntityManager();
            Query query = em.createNamedQuery("Question.findByQuestionnaire");
            query.setParameter("questionnaireid", questionnaire);
            results = query.getResultList();
        } catch (Exception e) {
            System.out.println("ERROR IN Question FACADE:" + e.getMessage());
        }
        return results;
    }

}

我的 Facade 实现了 AbstractFacade。这是抽象外观的代码:

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

import java.util.List;
import javax.persistence.EntityManager;

/**
 *
 * @author Pedram
 */
public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

}

顺便说一句,我刚刚启用了 JPA 日志记录,并意识到通过单击创建按钮不会执行任何 INSERT 查询。而我的应用程序的其他部分插入记录没有问题。

4

1 回答 1

1

首先,那里有很多草率的代码。

给定实例的方法 setQuestionnaireid?设置实体的id为0,而它的生成策略是identity?将单个客户端的结果分配给实例变量的无状态bean?使用 Java SE Persistence 类获取 EM 工厂的 EJB?实体之上的大量命名查询?使用无类型的 JPA 查询?

当然,这段代码不会飞。

您没有展示的一件事是您如何在 JSF 支持 bean 中获得对 EJB 的引用,以及这个支持 bean 到底是什么类型的 bean。它是本机@ManagedBean、CDI @Named 还是其他?

根据您所做的潜在“怪异”,实体未持久化的一个原因可能是未提交的事务。如果由于这种可能的其他怪异,您从工厂设置了 EM 而不是使用注入的,这确实可能发生。

于 2012-09-11T08:58:51.940 回答