2012-09-10 20 views
0

我使用JSF2.0與EJB和JPA。 我已經嘗試使用EJB Facade的create方法添加新記錄,並且沒有任何問題。使用EJB Facade的create()方法,使用JSF的JPA不會持久化新記錄。沒有錯誤返回

但是現在我不能在我的表格中添加一個類型爲Question的新記錄。 我會將代碼發佈到我的實體,控制器和EJB外觀文件,但我想補充一點,我的Question實體具有一個名爲Questionnaid類型Questionnaire的外鍵。

新記錄沒有添加,我在任何嘗試中都沒有收到任何錯誤。 即使我的問卷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; 
    } 

} 

我的門面實現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查詢的方式。而我的應用程序的其他部分插入記錄沒有問題。

+0

你的外觀的創建方法在哪裏? – Csaba

+0

我的門面實現了AbstractFacade。我在上面的代碼中添加了這個類。順便說一下,我啓用了JPA日誌記錄,並意識到通過單擊創建按鈕不會執行INSERT查詢。而我的應用程序的其他部分插入記錄沒有問題。 – Disasterkid

回答

1

首先,這裏有很多sl code的代碼。

一個setQuestionnaireid方法給出了一個實例嗎?將實體的ID設置爲0,而其生成策略是身份? A Stateless bean將單個客戶端的結果分配給實例變量?使用Java SE Persistence類獲取EM工廠的EJB?在實體頂部的命名查詢噸?使用無類型的JPA查詢?

當然這段代碼不會飛。

你沒有顯示的一件事是你如何在JSF支持bean中獲得對EJB的引用,以及這種支持bean的準確類型是什麼樣的bean。它是一個本地@ManagedBean,一個CDI @Named或其他東西?

根據您所做的潛在的「古怪」,實體未被保留的一個原因可能是未提交的事務。如果由於這種可能的其他奇怪,你從工廠設置EM而不是使用注入的EM,這可能確實發生。

+0

嘿邁克!謝謝回覆。我是JSF和JPA的新手,所以我同意我的代碼不是專業版,並且有錯誤。你的評論唉,只是增加了我的困惑,但我想我承擔了所有的責任。我利用了自動創建的控制器,實體和xhtml頁面。這意味着我創建了這些表並使實體bean脫離它們並創建基於實體bean的JSF頁面(使用NetBeans)。但爲此目的,我無法使用它們並必須創建自己的頁面。我也有一個JPA日誌,說明堅持被調用。但我永遠不會執行我的INSERT查詢。在它上面工作。 – Disasterkid

+0

*我的支持bean是ManagedBean。 *我知道我的世代策略是IDENTITY,但插入不起作用,除非我將id設置爲零。 *是setQuestionnaireID獲取實例,因爲它是我的問題表中的外鍵,JPA將它們映射到另一個表的問卷對象。 – Disasterkid

+0

關於setQuestionnaireID的一點是,如果它接收到調查問卷實例而不是此類的ID,那麼它應該簡單地稱爲「setQuestionnaire」。 –

相關問題