2010-04-08 2 views
9

Я пытаюсь создать запрос с API-интерфейсом Criteria из JPA 2.0, но я не могу заставить его работать.Создание запросов с использованием API критериев (JPA 2.0)

Проблема связана с условным методом «между». Я прочитал some documentation, чтобы знать, как мне это нужно, но поскольку я обнаруживаю JPA, я не понимаю, почему это не работает.

Во-первых, я не вижу «creationDate», который должен появиться, когда я пишу «Transaction_».

Я думал, что это было нормально, поскольку я прочитал метамодель, которая была создана во время выполнения, поэтому я попытался использовать «Foo_.getDeclaredSingularAttribute (« значение »)» вместо «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(); 
    } 
} 

Может кто-то помочь мне понять это? Благодарю.

EDIT: здесь источник транзакций (почти ничего в нем, так как он автоматически генерируется 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', а? –

+0

См. Ниже. – Pym

ответ

7

Я думал, что это может быть нормальным, так как я прочитал метамодель был создан во время выполнения (...)

классы метамодели генерируются во время компиляции, используя обработку аннотаций. Другими словами, вам необходимо активировать обработку аннотаций на уровне компилятора. Документация Hibernate JPA 2 Metamodel Generator описывает, как это сделать с Ant, Maven и IDE, такими как Eclipse или Idea (этот подход может быть перенесен другим провайдерам). К сожалению, эта функция в настоящее время не поддерживается в NetBeans.

Так что либо используйте, либо сконфигурируйте один из указанных инструментов сборки или переключитесь на другую среду IDE. Например, с помощью Eclipse, правой кнопкой мыши на проекте и перейти к Java Compiler> Аннотация обработки и включить его:

alt text

Затем добавьте нужный файл JAR (ы) поставщика (см к документации вашего поставщика JPA для этого шага) до Заводской путь.

+0

Спасибо! Я также посмотрел на ночные часы Netbeans, и кажется, что они недавно реализовали одни и те же функции. – Pym

+0

@Pym Полезно знать (я понял, что это будет доступно в NB 6.9, который был недавно выпущен в Beta). Спасибо за ответ. –

2

Я думаю, что запутанная часть здесь q.where(cb.between(transaction.get(Transaction_.creationDate), startDate, endDate));

Вы должен заметить, что Transaction_ в этом случае представляет собой статический экземпляр, канонический класс метамодели, соответствующий первому классу сущности транзакции. Вы должны сгенерировать класс Transaction_, составив класс Transaction с использованием JPA-библиотек. Одна полезная ссылка здесь для затмения: 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

+0

Теперь убедитесь, что вы вручную создадите каноническую метамодель. Вы используете любую IDE? если так следовать применимым ссылкам или затмению, посмотрите ниже. Какую версию Java вы используете? Неявное понимание среди поставщиков JPA заключается в том, что они будут генерировать метамодель, используя процессор аннотаций, интегрированный в компилятор Java 6. –

-2

QUERY ДЛЯ СТАРТА ДАТА И КОНЕЦ ДАТА В 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 хотел использовать API критериев. – prasopes