2013-05-02 5 views
8

Я использую JPA 2.0. Hibernate 4.1.0.Final и Java 6. Как написать запрос JPA из следующего psuedo-SQL?Как написать MAX-запрос с предложением where в JPA 2.0?

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

И мой объект домена выглядит следующим образом:

@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; 

Я знаю, что CriteriaBuilder.greatest участвует, но я просто не могу понять, как написать запрос. Это вернет все объекты событий, которые соответствуют организации, но это насколько я получил.

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

ответ

21

Существует два способа: один использует JPQL, другой - с использованием запросов критериев.
JPQL просто:

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

при использовании критериев вы можете иметь:

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

Так как я хочу, чтобы вернуть «java.util.Date, «Я предполагаю, что я меняю строку« CriteriaQuery cq = qb.createQuery (Number.class); » to "CriteriaQuery cq = qb.createQuery (Date.class);". В любом случае, я получаю ошибку компиляции в строке «cq.select (qb.max (root.get (« dateProcessed »));». В нем говорится: «Связанное несоответствие: общий метод max (выражение ) типа CriteriaBuilder не применим для аргументов (путь ). Выведенный тип Object не является допустимым заменителем ограниченного параметра " – Dave

+3

I didn Не замечаем, что Max принимает только выражение , которое отличается от выражения JPQL max, которое примет любое выражение пути. Это рассматривается в вопросе http://stackoverflow.com/questions/9616390/select-max-timestamp-with-jpa2-criteria-api – Chris

+4

Когда я использовал «наибольший» (меняя «root.get (« dateProcessed »)» на 'root.get (Event_.dateProcessed)') все отлично работало. – Dave

0

С JPQL и 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"))); 
Смежные вопросы