使用Criteria API创建查询(JPA 2.0)

我正在尝试使用JPA 2.0中的Criteria API创建查询,但我无法使其工作。

问题在于“之间”条件方法。 我读了一些文档 ,知道我该怎么做,但是因为我发现了JPA,所以我不明白为什么它不起作用。

首先,当我写“Transaction_”时,我看不到应该出现的“creationDate”。

我认为这可能是正常的,因为我读过元模型是在运行时生成的,所以我尝试使用’Foo_.getDeclaredSingularAttribute(“value”)’而不是’Foo_.value’,但它仍然无法正常工作。

这是我的代码:

public List getTransactions(Date startDate, Date endDate) { EntityManager em = getEntityManager(); try { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(Transaction.class); Metamodel m = em.getMetamodel(); EntityType Transaction_ = m.entity(Transaction.class); Root transaction = cq.from(Transaction.class); // Error here. cannot find symbol. symbol: variable creationDate cq.where(cb.between(transaction.get(Transaction_.creationDate), startDate, endDate)); // I also tried this: // cq.where(cb.between(Transaction_.getDeclaredSingularAttribute("creationDate"), startDate, endDate)); List result = em.createQuery(cq).getResultList(); return result; } finally { em.close(); } } 

有人能帮我解决这个问题吗? 谢谢。

编辑:这是交易源(几乎没有任何内容,因为它是由Netbeans自动生成的,来自我的数据库)

 package projetjava.db; import java.io.Serializable; import java.util.Date; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity @Table(name = "transaction") @NamedQueries({ @NamedQuery(name = "Transaction.findAll", query = "SELECT t FROM Transaction t"), @NamedQuery(name = "Transaction.findById", query = "SELECT t FROM Transaction t WHERE t.id = :id"), @NamedQuery(name = "Transaction.findByIDAccount", query = "SELECT t FROM Transaction t WHERE t.iDAccount = :iDAccount"), @NamedQuery(name = "Transaction.findByDescription", query = "SELECT t FROM Transaction t WHERE t.description = :description"), @NamedQuery(name = "Transaction.findByCreationDate", query = "SELECT t FROM Transaction t WHERE t.creationDate = :creationDate"), @NamedQuery(name = "Transaction.findByAmount", query = "SELECT t FROM Transaction t WHERE t.amount = :amount")}) public class Transaction implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "ID") private Integer id; @Basic(optional = false) @Column(name = "IDAccount") private int iDAccount; @Basic(optional = false) @Column(name = "Description") private String description; @Basic(optional = false) @Column(name = "CreationDate") @Temporal(TemporalType.DATE) private Date creationDate; @Basic(optional = false) @Column(name = "Amount") private double amount; public Transaction() { } public Transaction(Integer id) { this.id = id; } public Transaction(Integer id, int iDAccount, String description, Date creationDate, double amount) { this.id = id; this.iDAccount = iDAccount; this.description = description; this.creationDate = creationDate; this.amount = amount; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public int getIDAccount() { return iDAccount; } public void setIDAccount(int iDAccount) { this.iDAccount = iDAccount; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Date getCreationDate() { return creationDate; } public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } @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 Transaction)) { return false; } Transaction other = (Transaction) 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 "projetjava.db.Transaction[id=" + id + "]"; } } 

我认为这可能是正常的,因为我读过元模型是在运行时生成的(…)

使用注释处理在编译时生成元模型类。 换句话说,您需要在编译器级别激活注释处理。 Hibernate JPA 2 Metamodel Generator文档描述了如何使用Ant,Maven和IDE(如Eclipse或Idea)执行此操作(该方法可以转换为其他提供程序)。 遗憾的是,NetBeans目前不支持此function。

因此,要么使用并配置上述构建工具之一,要么切换到另一个IDE。 例如,使用Eclipse, 右键单击项目并转到Java Compiler> Annotation Processing并启用它:

替代文字

然后将您的提供程序所需的JAR(请参阅此步骤的JPA提供程序的文档)添加到Factory Path

我认为这里令人困惑的部分是q.where(cb.between(transaction.get(Transaction_.creationDate), startDate, endDate));

您必须注意,在这种情况下, Transaction_是一个静态实例化的规范元模型类,对应于原始的Transaction实体类。 您必须通过使用JPA库编译Transaction类来生成Transaction_类。 这里有一个有用的链接: http : //wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_%28ELUG%29

对于intellij IDEA

http://blogs.jetbrains.com/idea/2009/11/userfriendly-annotation-processing-support-jpa-20-metamodel/

在JPA开始日期和结束日期查询

 public List findStudentByReports(String className, Date startDate, Date endDate) { System.out .println("call findStudentMethd******************with this pattern" + className + startDate + endDate + "*********************************************"); return em .createQuery( "select attendence from Attendence attendence where lower(attendence.className) like '" + className + "' or attendence.admissionDate BETWEEN : startdate AND endDate " + "'") .setParameter("startDate", startDate, TemporalType.DATE) .setParameter("endDate", endDate, TemporalType.DATE) .getResultList(); }