我正在使用JSF2.0和EJB和JPA。 我已经尝试使用EJB Facade的create方法添加新记录,并且没有问题。
但现在我无法在表格中添加类型问题的新记录。 我将代码发布到我的实体,控制器和EJB外观文件,但我想补充一点,我的Question实体有一个名为Questionireire类型的问卷调查表的外键。
新记录没有被添加,我的尝试中没有任何错误。 甚至我的问卷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;
}
}
我的Facade实现了AbstractFacade。这是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();
}
}
顺便说一下,我刚刚启用了JPA日志记录,并意识到通过单击“创建”按钮,不会执行INSERT查询。而我的应用程序的其他部分插入记录没有问题。
答案 0 :(得分:1)
首先,那里有很多草率的代码。
给出实例的方法setQuestionnaireid?将实体的id设置为0,而其生成策略是标识? 无状态 bean将单个客户端的结果分配给实例变量?使用Java SE Persistence类获取EM工厂的EJB?在实体之上的大量命名查询?使用无类型的JPA查询?
肯定这段代码不会飞。
你没有展示的一件事是你如何在JSF支持bean中获得对EJB的引用,以及这个支持bean究竟是什么类型的bean。它是原生的@ManagedBean,CDI @Named还是别的什么?
根据您所做的潜在“怪异”,实体未被持久化的一个原因可能是未提交的事务。如果由于这种可能的其他怪异你从工厂设置EM而不是使用注入的EM,这确实可能发生。