2010-04-08 89 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