как построить динамический запрос для отношения "многие к одному" с помощью CriteriaBuilder из JPA 2.0

Я застрял в создании динамического запроса с использованием CriteriaBuilder в JPA 2.0. Мое приложение - Spring 3.0, Hibernate 3.6.0 + JPA 2.0. На самом деле у меня есть две сущности: одна taUser, а другая taContact, в моем классе taUser есть одно свойство, которое имеет отношение "многие к одному" с taContact, мои классы pojo (пример примера)

public class TaUser implements java.io.Serializable {
    private int userId;
    private TaContact taContact;
    public int getUserId() {
        return this.userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }
    public TaContact getTaContact() {
        return taContact;
    }

    public void setTaContact(TaContact taContact) {
        this.taContact = taContact;
    }

    }


   public class TaContact implements java.io.Serializable {

    private int contactId;

    public int getContactId() {
        return this.contactId;
    }

    public void setContactId(int contactId) {
        this.contactId = contactId;
    }
   private int contactNumber;

    public int getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(int contactNumber) {
        this.contactNumber = contactNumber;
    }

   }

и мой orm .xml

<entity class="com.common.model.TaUser" name="TaUser">
        <table name="ta_user" />
        <attributes>
            <id name="userId">
                <column name="USER_ID" />
                <generated-value strategy="AUTO" />
            </id>
            <many-to-one name="taContact"
                target-entity="TaContact">
                <join-column name="Contact_id" />
            </many-to-one>
</attributes>
</entity>

Как я могу создать построение динамического запроса с использованием критериев, на самом деле это мой jpql-запрос. Я хочу изменить его на построение динамического запроса с использованием критериев.

String jpql = 
    "select * from Tauser user where user.userId = "1" and user.taContact.contactNumber="8971329902";

Как я могу проверить второе условие where?

user.taContact.contactNumber = "8971329902"

Root<T> rootEntity;
        TypedQuery<T> typedQuery = null;
        EntityManagerFactory entityManagerFactory = this.getJpaTemplate()
                .getEntityManagerFactory();
        CriteriaBuilder criteriaBuilder = entityManagerFactory
                .getCriteriaBuilder();
        CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(TaUser.class);
                rootEntity = criteriaQuery.from(TaUser.class);
                criteriaQuery.where(criteriaBuilder.equal(rootEntity.get("userId"),
                "1"));
        criteriaQuery.where(criteriaBuilder.equal(rootEntity.get("taContact.contactNumber"),
        "8971329902")); --- here  i m getting error 
    at 

org.hibernate.ejb.criteria.path.AbstractPathImpl.unknownAttribute(AbstractPathImpl.java:110)
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:218)
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:189)
    at com.evolvus.core.common.dao.CommonDao.findByCriteria(CommonDao.java:155)

как я могу это решить?


person unknown    schedule 28.01.2011    source источник


Ответы (2)


Есть много способов использовать этот динамический запрос в JPA EntityManagerFactory.

  1. Если вы используете JPA класс Entity и аннотации Use Hibernate 3 JPA, вы можете определить запрос с помощью аннотации @NamedQuery.

  2. Вы можете использовать javax.persistence.Query для создания динамического запроса.

    Query q1=em.createQuery("SELECT TaUser AS tu WHERE tu.userId = :USERID");
    //em is entityManager object
    q1.setInteger("USERID",34);
    //here 34 is the dynamic value or if there is any relationship with
    // another entity then set the object reference of the other entity.
    q1.getResultList(); //return list of data.
    
  3. Вы можете использовать API критериев Hibernate.

Но дело в том, что если вы хотите создать критерии, вам нужно инициализировать объект сеанса. Итак, чтобы получить объект сеанса, используйте объект диспетчера сущностей.

person sourav    schedule 28.01.2011
comment
пожалуйста: если английский не ваш родной язык, ничего страшного. Но постарайтесь не усугубить ситуацию, написав на языке LOL как «u» вместо «you». Кроме того, постарайтесь не ошибаться в написании классов, пакетов и технологий, о которых вы говорите. Ваш пост и так достаточно сложен для чтения. - person Sean Patrick Floyd; 28.01.2011
comment
Я попытался исправить ваше сообщение, но даже в этом случае ваш ответ неуместен, поскольку вопрос касается API критериев JPA 2, а не API критериев гибернации. - person Sean Patrick Floyd; 28.01.2011
comment
Привет, Шон Патрик Флойд, ваш второй комментарий верен. Почему ты не можешь мне предложить? - person unknown; 28.01.2011
comment
@ Шон Патрик Флойд: В моем ответе я использовал API критериев JPA 2, поэтому я использую этот javax.persistence.Query, а не org.hibernate.Criteria, и спасибо за советы .. :) - person sourav; 21.03.2011
comment
Вопрос касался использования CriteriaBuilder из JPA 2.0, почему вы предлагаете другие способы запросов? - person afrish; 15.10.2014

Я думаю, это способ сделать это:

public TaUser getUserByIdAndContactNumber(
    final long userId,
    final long contactNumber){

    final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    final CriteriaQuery<TaUser> query = cb.createQuery(TaUser.class);
    final Root<TaUser> root = query.from(TaUser.class);
    query
        .where(cb.and(
            cb.equal(root.get("userId"), userId),
            cb.equal(root.get("taContact").get("contactNumber"), contactNumber)
        ));
    return entityManager.createQuery(query).getSingleResult();
}

Кстати, 8971329902 слишком велик для поля int. Установите тип поля long.

person Sean Patrick Floyd    schedule 28.01.2011