Типизированный сложный критерий запроса с Java Hiberate EntityManager - PullRequest
0 голосов
/ 19 декабря 2011

Обычно я не знаком с Java, Hibernate или EntityManager.Я использовал NHibernate достаточно хорошо, но с Linq и Fluent NHibernate почти нет необходимости использовать критерии API, поэтому я немного колеблюсь, пытаясь заставить следующий запрос работать

Получить всеэкземпляры ReferenceCodeMetaData, где siteId == 1 и codeType == 'sampleUnits'

Я знаю, что это должно быть что-то вроде

em.createQuery(Restrictions.and(
  Restrictions.eq("siteId", siteId),
  Restrictions.eq("codeType", codeType)
))

Но я не могу получить универсальную типизациюправильный.Может кто-нибудь помочь мне заполнить тело этой функции?

public ReferenceCodeMetaData[] getMatching(EntityManager em, Integer siteId, String codeType) {

  return ...
} 

1 Ответ

2 голосов
/ 20 декабря 2011

Вы используете метод в EntityManager, который принимает CriteriaQuery или JPQL-запрос в качестве аргумента, но тип ваших типов аргументов относится к Hibernate Criteria. Вот три возможных реализации для такого метода:

public ReferenceCodeMetaData[] getMatchingWithJPQL(EntityManager em,
                                                   Integer siteId,
                                                   String codeType) {
    String jpql =  "SELECT r FROM ReferenceCodeMetaData r where siteId = :siteId AND codeType = :codeType";
    TypedQuery<ReferenceCodeMetaData> query = em.createQuery(jpql, ReferenceCodeMetaData.class);

    query.setParameter("siteId", siteId);
    query.setParameter("codeType", codeType);
    List<ReferenceCodeMetaData> result = query.getResultList();

    return result.toArray(new ReferenceCodeMetaData[result.size()]);
}

public ReferenceCodeMetaData[] getMatchingWithCriteriaAPI(EntityManager em,
                                                          Integer siteId,
                                                          String codeType) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<ReferenceCodeMetaData> cq = cb.createQuery(ReferenceCodeMetaData.class);
    Root<ReferenceCodeMetaData> root = cq.from(ReferenceCodeMetaData.class);

    cq.select(root)
        .where(cb.and(
            cb.equal(root.get("siteId"), cb.parameter(Integer.class, "siteId")),
            cb.equal(root.get("codeType"), cb.parameter(String.class, "codeType"))));

    TypedQuery<ReferenceCodeMetaData> query = em.createQuery(cq);

    query.setParameter("siteId", siteId);
    query.setParameter("codeType", codeType);
    List<ReferenceCodeMetaData> result = query.getResultList();
    return result.toArray(new ReferenceCodeMetaData[result.size()]);
}

public ReferenceCodeMetaData[] getMatchingWithJHibernateCriteria(EntityManager em, 
                                                                 Integer siteId, 
                                                                 String codeType) {
    HibernateEntityManager hem = em.unwrap(HibernateEntityManager.class);
    Session session = hem.getSession();
    // If you use some older version of Hibernate, then unwrap method is not 
    // available and you can use following instead of two lines above:
    // Session session = (Session) em.getDelegate();


    List<ReferenceCodeMetaData> result = session.createCriteria(ReferenceCodeMetaData.class)
        .add(Restrictions.eq("siteId", siteId) )
        .add(Restrictions.eq("codeType", codeType))
    .list();
    return result.toArray(new ReferenceCodeMetaData[result.size()]);
}

Первые два являются стандартными JPA, а последний - для Hibernate. Все они генерируют эквивалентный SQL-запрос и выдают одинаковый результат. Я бы пошел в первом случае в этом случае.

...