0

私はEJBとJPAでJSF2.0を使用しています。私はすでにEJBFacadeのcreateメソッドを使用して新しいレコードを追加しようとしましたが、問題はありませんでした。

しかし、今では、Questionタイプの新しいレコードをテーブルに追加できません。コードをエンティティ、コントローラ、およびEJBファサードファイルに投稿しますが、QuestionエンティティにはQuestionnaireタイプのquestionidという外部キーがあることを追加したいと思います。

新しいレコードは追加されず、試行のキャッチでエラーは発生しません。アンケートIDも正しく返送されます。実行されないのはpersist()だけです。

これが私のコントローラーのcreateメソッドです:

 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;
    }

}

私のファサードはAbstractFacadeを実装しています。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 に設定し、その生成戦略は ID ですか? 単一のクライアントの結果をインスタンス変数に割り当てるステートレスBean ? Java SE Persistence クラスを使用して EM ファクトリを取得する EJB ですか? エンティティの上に大量の名前付きクエリがありますか? 型指定されていない JPA クエリを使用していますか?

確かに、このコードは飛ぶつもりはありません。

あなたが示していないことの 1 つは、JSF バッキング Bean で EJB への参照を取得する方法と、このバッキング Bean が正確にどのような種類の Bean であるかです。それはネイティブの @ManagedBean か、CDI @Named か、それとも何か他のものですか?

あなたが行った潜在的な「奇妙さ」に応じて、エンティティが永続化されない原因の 1 つは、コミットされていないトランザクションである可能性があります。この他の奇妙な可能性のために、注入されたものを使用する代わりにファクトリから EM を設定した場合、これは実際に発生する可能性があります。

于 2012-09-11T08:58:51.940 に答える