简体   繁体   中英

New record not persisted using EJB Facade's create() method, JPA using JSF. No errors returned either

I'm using JSF2.0 with EJB and JPA. I've already tried adding new records using EJB Facade's create method and had no problems with them.

But now I cannot add a new record of type Question in my tables. I will post the code to my entity, controller and EJB facade files but I want to add that my Question entity has a foreign key called questionnaireid of type Questionnaire.

The new record is not added and I get no errors in the catch of my try whatsoever. Even my questionnaire ID is returned correctly. The only thing that is not done is persist().

Here's the create method in my controller:

 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());

    }
}

Here's my Question entity:

/*
 * 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 + " ]";
    }

}

And here's my EJB facade class:

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

}

My Facade implements AbstractFacade. Here's the code to Abstract Facade:

/*
 * 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();
    }

}

By the way I just enabled JPA logging and realized that by clicking the create button no INSERT query is executed. Whereas other parts of my application have no problem inserting records.

First of all, there's quite a lot of sloppy code there.

A method setQuestionnaireid that's given an instance? Setting the id of the entity to 0, while its generation strategy is identity? A Stateless bean assigning the result of a single client to an instance variable? An EJB using the Java SE Persistence class to obtain an EM factory? Tons of named queries on top of the entity? Using untyped JPA queries?

Surely this code is not going to fly.

One thing you didn't show is how you obtain a reference to your EJB in your JSF backing bean, and what kind of bean this backing bean exactly is. Is it a native @ManagedBean, a CDI @Named, or something else?

Depending on potential "weirdness" that you did, one cause of the entity not being persisted could be a transaction that's not committed. If due to this possible other weirdness you set an EM from a factory instead of using the injected one, this could happen indeed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM