2010-04-08 110 views
9

我试图用JPA 2.0中的Criteria API创建一个查询,但我无法让它工作。使用Criteria API创建查询(JPA 2.0)

问题出在“之间”的条件方法。我读some documentation知道我该怎么做,但自从我发现JPA以来,我不明白为什么它不起作用。

首先,我看不到在创建“Transaction_”时应该出现的“creationDate”。

我认为这也许是正常的,因为我读的元模型是在运行时生成的,所以我尝试使用'Foo_.getDeclaredSingularAttribute(“value”)'而不是'Foo_.value',但它仍然没有一切工作。

这里是我的代码:

public List<Transaction> getTransactions(Date startDate, Date endDate) { 
    EntityManager em = getEntityManager(); 
    try { 
     CriteriaBuilder cb = em.getCriteriaBuilder(); 
     CriteriaQuery<Transaction> cq = cb.createQuery(Transaction.class); 
     Metamodel m = em.getMetamodel(); 
     EntityType<Transaction> Transaction_ = m.entity(Transaction.class); 
     Root<Transaction> 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<Transaction> 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 + "]"; 
    } 

} 
+0

您可以发布源'Transaction'呢? – 2010-04-08 19:35:15

+0

请参阅下面。 – Pym 2010-04-08 19:46:44

回答

7

我认为这是可能正常的,因为我看到在运行时生成的元模型(...)

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

因此,使用和配置提到的构建工具之一或切换到另一个IDE。例如,使用Eclipse,上右击项目,去Java编译器>注释处理并启用它:

alt text

添加您的提供商所需的JAR(S)(参见到此步骤的JPA提供商文档)到工厂路径

+0

谢谢!我也看了一下Netbeans的夜景,看起来他们最近实现了相同的功能。 – Pym 2010-04-26 08:06:26

+0

@Pym很好理解(我明白这将在最近发布的NB 6.9中提供)。感谢您的反馈。 – 2010-04-26 08:32:23

2

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

你必须注意,在这种情况下,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/

+0

我可以在某处手动创建'Transaction_'吗? – Pym 2010-04-08 20:33:48

+0

现在确定您将如何手工创建规范元模型。 你使用任何IDE?如果是的话遵循适用的链接或日食,请看下面的答案。 您使用的是什么版本的Java? JPA提供者之间隐含的理解是,他们将使用集成在Java 6编译器中的注释处理器生成元模型。 – 2010-04-08 21:13:05

-2

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

public List<Student> 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(); 
} 
+0

OP想要使用Criteria API。 – prasopes 2011-09-16 14:33:20

相关问题