java 如何使用 JPA 2.0 的 CriteriaBuilder 构建多对一关系的动态查询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4825456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 08:12:39  来源:igfitidea点击:

how to construct a dynamic query for a many to one relationship using the CriteriaBuilder of JPA 2.0

javahibernatespringcriteriajpa-2.0

提问by unknown

I stucked constructing a dynamic query using the CriteriaBuilder in JPA 2.0. My application is Spring 3.0, Hibernate 3.6.0 + JPA 2.0 based. Actually I have two entities one is taUserand another one is taContact, in my taUserclass has one property ,that has many to one relationship with taContactmy pojo classes are (sample example)

我坚持使用 JPA 2.0 中的 CriteriaBuilder 构建动态查询。我的应用程序是 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;
    }

   }

and my orm .xml

和我的 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>

How can I create constructing a dynamic query using criteria actually this is my jpql query I want to change it into constructing a dynamic query using criterias.

如何使用标准创建动态查询实际上这是我的 jpql 查询我想将其更改为使用标准构建动态查询。

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

How can I check the second where condition?

如何检查第二个 where 条件?

user.taContact.contactNumber="8971329902"

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)

how can I solve this?

我该如何解决这个问题?

采纳答案by sourav

There are many wey to use that Dynamic query in a JPA EntityManagerFactory.

在 JPA EntityManagerFactory 中使用该动态查询有很多方法。

  1. If you use JPA Entity class and Use Hibernate 3 JPAannotations then you can define the query using the @NamedQueryAnnotation.

  2. You can use javax.persistence.Queryto create a Dynamic 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. You can use the Hibernate Criteria API.

  1. 如果您使用 JPA实体类并使用 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. 您可以使用 Hibernate Criteria API。

But the thing is that if u want to create criteria you need to initialize the session object. So, to get session object use your entity manager object.

但问题是,如果你想创建标准,你需要初始化会话对象。因此,要获取会话对象,请使用您的实体管理器对象。

回答by Sean Patrick Floyd

I guess this is the way to do it:

我想这是这样做的方法:

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

BTW, 8971329902 is way to large for an intfield. Set the field type to long.

顺便说一句,8971329902 是一个int领域的大方法。将字段类型设置为long