2013-05-02 15 views
8

Używam JPA 2.0. Hibernate 4.1.0.Final i Java 6. Jak napisać zapytanie JPA z następującego pseudo-SQL?Jak napisać zapytanie MAX z klauzulą ​​where w JPA 2.0?

select max(e.dateProcessed) from Event e where e.org = myOrg 

A mój obiekt domeny wygląda następująco:

@GenericGenerator(name = "uuid-strategy", strategy = "org.mainco.subco.core.util.subcoUUIDGenerator") 
@Entity 
@Table(name = "sb__event", 
    uniqueConstraints = { @UniqueConstraint(columnNames={"EVENT_ID"}) } 
) 
public class Event 
{ 

    @Id 
    @Column(name = "ID") 
    @GeneratedValue(generator = "uuid-strategy") 
    private String id; 

    @ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.REMOVE}) 
    @JoinColumn(name = "ORGANIZATION_ID", nullable = false, updatable = true) 
    private Organization org; 

    @Column(name = "DATE_PROCESSED") 
    @NotNull 
    private java.util.Date dateProcessed; 

wiem, że CriteriaBuilder.greatest jest zaangażowany, ale po prostu nie może dowiedzieć się, jak napisać zapytanie. Spowoduje to zwrócenie wszystkich obiektów zdarzeń pasujących do organizacji, ale to tyle, ile udało mi się zdobyć.

final CriteriaBuilder builder = m_entityManager.getCriteriaBuilder(); 
final CriteriaQuery<Event> criteria = builder.createQuery(Event.class); 
final Root<Event> event = criteria.from(Event.class); 
criteria.select(event); 
criteria.where(builder.equal(Event.get("org"), org)); 
results.addAll(m_entityManager.createQuery(criteria).getResultList()); 

Odpowiedz

21

Istnieją dwa sposoby, jeden przy użyciu JPQL, drugi przy użyciu zapytań kryterialnych.
JPQL jest prosta:

em.createQuery("select max(e.dateProcessed) from Event e where e.org = :myOrg") 
    .setParameter("myOrg", myOrg) 
    .getSingleResult(); 

podczas korzystania z kryteriów może mieć:

CriteriaBuilder qb = em.getCriteriaBuilder(); 
CriteriaQuery<Number> cq = qb.createQuery(Number.class); 
Root<Event> root = cq.from(Event.class); 
cq.select(qb.max(root.get("dateProcessed"))); 
cq.where(qb.equal(Event.get("org"), qb.parameter(MyOrgType.class, "myOrg"))); 
em.createQuery(cq).setParameter("myOrg", myOrg).getSingleResult(); 
+0

ponieważ chcę, aby powrócić do „java.util.Date, "Zakładam, że zmienię linię" CriteriaQuery cq = qb.createQuery (Number.class); " do "CriteriaQuery cq = qb.createQuery (Date.class);". Tak czy inaczej, otrzymuję błąd kompilacji na linii "cq.select (qb.max (root.get (" dateProcessed ")));". Jest napisane: "Związane niedopasowanie: Ogólna metoda max (Wyrażenie ) typu CriteriaBuilder nie ma zastosowania do argumentów (Ścieżka ) .Przypisany typ Obiekt nie jest poprawnym zamiennikiem ograniczonego parametru " – Dave

+3

I didn Zauważ, że Max przyjmuje tylko wyrażenie , które różni się od wyrażenia max JPQL, które będzie akceptowało dowolne wyrażenie ścieżki. Jest to objęte pytaniem http://stackoverflow.com/questions/9616390/select-max-timestamp-with-jpa2-criteria-api – Chris

+4

Kiedy użyłem "największego" (zmieniając "root.get (" dateProcessed ")" na "root.get (Event_.dateProcessed)") wszystko działało świetnie. – Dave

0

Z JPQL i CriteriaBuilder

CriteriaBuilder cb = getEntityManager().getCriteriaBuilder(); 
javax.persistence.criteria.CriteriaQuery cq= getEntityManager().getCriteriaBuilder().createQuery(); 
Root<T> c = cq.from(getEntityClass()); 
cq.select(cb.max(c.get("id"))); 
Powiązane problemy