2010-04-08 21 views
9

Sto provando a creare una query con l'API Criteria da JPA 2.0, ma non riesco a farlo funzionare.Creazione di query tramite Criteria API (JPA 2.0)

Il problema è con il metodo condizionale "tra". Ho letto some documentation per sapere come devo farlo, ma poiché sto scoprendo JPA, non capisco perché non funzioni.

Innanzitutto, non riesco a vedere "creationDate" che dovrebbe apparire quando scrivo "Transaction_".

Ho pensato che fosse normale, poiché ho letto che il metamodel è stato generato in fase di esecuzione, quindi ho provato a utilizzare "Foo_.getDeclaredSingularAttribute (" value ")" invece di "Foo_.value", ma non lo è ancora lavorare affatto

Ecco il mio codice:

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

qualcuno può aiutarmi a capirlo? Grazie.

EDIT: qui è la fonte di transazione (quasi nulla in essa, da quando è stato automaticamente generato da Netbeans, dalla mia base di dati)

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

è possibile inviare fonte per 'Transaction' pure? –

+0

Si prega di vedere sotto. – Pym

risposta

7

ho pensato che fosse normale forse, da quando ho letto il metamodello è stata generata in fase di esecuzione (...)

classi Metamodel vengono generati al momento della compilazione utilizzando l'elaborazione annotazioni. In altre parole, è necessario attivare l'elaborazione delle annotazioni a livello del compilatore. La documentazione Hibernate JPA 2 Metamodel Generator descrive come farlo con Ant, Maven e IDE come Eclipse o Idea (l'approccio può essere trasferito ad altri fornitori). Purtroppo, questa funzione non è attualmente supportata in NetBeans.

Quindi utilizzare e configurare uno degli strumenti di creazione menzionati o passare a un altro IDE. Ad esempio, con Eclipse, destro del mouse sul progetto e andare a Java Compiler> Annotazione lavorazione e abilitarla:

alt text

quindi aggiungere il JAR richiesto (s) del vostro provider (vedere alla documentazione del proprio provider JPA per questo passaggio) al percorso di fabbrica .

+0

Grazie! Ho anche dato un'occhiata ai nightly di Netbeans e sembra che abbiano recentemente implementato le stesse funzionalità. – Pym

+0

@Pym Buono a sapersi (ho capito che sarebbe disponibile in NB 6.9 che è stato rilasciato di recente in Beta). Grazie per il feedback. –

2

Penso che la parte di confusione qui è q.where(cb.between(transaction.get(Transaction_.creationDate), startDate, endDate));

È è necessario notare che in questo caso Transaction_ è una classe metamodel canonica statica, corrispondente alla classe di entità transazione originale. È necessario generare la classe Transaction_ compilando la classe Transaction utilizzando le librerie JPA. Un collegamento utile è qui per Eclipse: http://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_%28ELUG%29

per IntelliJ IDEA

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

+0

Posso creare 'Transaction_' manualmente da qualche parte? – Pym

+0

Ora assicurati come creerai a mano il metamodello canonico. Stai usando un IDE? se è così, segui i link applicabili o per eclissi, dai un'occhiata qui sotto. Quale versione di Java stai usando? Una comprensione implicita tra i provider JPA è che genereranno metamodel utilizzando il processore di annotazione integrato nel compilatore Java 6. –

-2

DOMANDA PER L'AVVIO DATA e fine in 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

L'OP voleva utilizzare l'API Criteri. – prasopes

Problemi correlati