2010-04-08 45 views
9

Tôi đang cố tạo truy vấn với API tiêu chí từ JPA 2.0, nhưng tôi không thể làm cho nó hoạt động.Tạo truy vấn bằng cách sử dụng API tiêu chí (JPA 2.0)

Sự cố xảy ra với phương pháp có điều kiện "giữa". Tôi đọc some documentation để biết làm thế nào tôi phải làm điều đó, nhưng kể từ khi tôi phát hiện ra JPA, tôi không hiểu tại sao nó không hoạt động.

Trước tiên, tôi không thể thấy "creationDate" sẽ xuất hiện khi tôi viết "Transaction_". Tôi nghĩ rằng nó có thể là bình thường, vì tôi đọc metamodel được tạo ra trong thời gian chạy, vì vậy tôi đã cố gắng sử dụng 'Foo_.getDeclaredSingularAttribute ("value")' thay vì 'Foo_.value', nhưng nó vẫn không làm việc chút nào.

Đây là mã của tôi:

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

Ai đó có thể giúp tôi con số này ra? Cảm ơn.

EDIT: đây là nguồn giao dịch (hầu như không có gì trong nó, vì nó đã được tạo tự động bởi Netbeans, từ cơ sở dữ liệu của tôi)

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

bạn có thể đăng nguồn cho 'Transaction' không? –

+0

Vui lòng xem bên dưới. – Pym

Trả lời

7

Tôi nghĩ đó là lẽ bình thường, kể từ khi tôi đọc các metamodel được tạo ra trong thời gian chạy (...)

Các lớp siêu mô hình được tạo tại thời điểm biên dịch bằng cách sử dụng xử lý chú thích. Nói cách khác, bạn cần kích hoạt quá trình xử lý chú thích ở cấp trình biên dịch. Tài liệu Hibernate JPA 2 Metamodel Generator mô tả cách thực hiện điều đó với Ant, Maven và IDE như Eclipse hoặc Idea (cách tiếp cận có thể được chuyển đổi sang các nhà cung cấp khác). Đáng buồn thay, tính năng này hiện không được hỗ trợ trong NetBeans.

Vì vậy, hãy sử dụng và định cấu hình một trong các công cụ xây dựng được đề cập hoặc chuyển sang một IDE khác. Ví dụ, với Eclipse, kích chuột phải vào về dự án và đi đến Java Compiler> Processing Chú và Enable nó:

alt text

Sau đó, thêm JAR yêu cầu (s) của nhà cung cấp của bạn (tham khảo với tài liệu của nhà cung cấp JPA của bạn cho bước này) đến Đường dẫn Nhà máy.

+0

Cảm ơn! Tôi cũng đã có một cái nhìn về các nightlies Netbeans và có vẻ như họ đã thực hiện các chức năng tương tự gần đây. – Pym

+0

@Pym Tốt để biết (Tôi hiểu điều này sẽ có sẵn trong NB 6.9 đã được phát hành gần đây trong bản Beta). Cảm ơn vì bạn đã phản hồi. –

2

Tôi nghĩ rằng phần khó hiểu ở đây là q.where(cb.between(transaction.get(Transaction_.creationDate), startDate, endDate));

Bạn phải lưu ý rằng Transaction_ trong trường hợp này là một lớp meta metamodel được khởi tạo tĩnh, tương ứng với lớp thực thể Giao dịch ban đầu. Bạn phải tạo lớp Transaction_ bằng cách biên soạn lớp Transaction của mình bằng cách sử dụng thư viện JPA. Một liên kết hữu ích là ở đây cho Eclipse: http://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_%28ELUG%29

Đối với IntelliJ IDEA

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

+0

Tôi có thể tạo 'Transaction_' ở đâu đó không? – Pym

+0

Bây giờ hãy chắc chắn bạn sẽ tạo ra metamodel chuẩn như thế nào. Bạn có đang sử dụng bất kỳ IDE nào không? nếu như vậy theo các liên kết có thể áp dụng hoặc cho nhật thực, hãy xem câu trả lời bên dưới. Bạn đang sử dụng phiên bản Java nào? Một sự hiểu biết ngầm định giữa các nhà cung cấp JPA là họ sẽ tạo ra metamodel bằng cách sử dụng bộ xử lý chú thích được tích hợp trong trình biên dịch Java 6. –

-2

QUERY CHO NGÀY BẮT ĐẦU VÀ KẾT THÚC NGÀY TRÊN 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 muốn sử dụng API tiêu chí. – prasopes

Các vấn đề liên quan