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

unk*_*own 5 java spring hibernate criteria jpa-2.0

我坚持使用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;
    }

   }
Run Code Online (Sandbox Code Playgroud)

和我的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>
Run Code Online (Sandbox Code Playgroud)

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

String jpql = 
    "select * from Tauser user where user.userId = "1" and user.taContact.contactNumber="8971329902";
Run Code Online (Sandbox Code Playgroud)

我怎样才能检查第二个条件?

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)
Run Code Online (Sandbox Code Playgroud)

我该怎么解决这个问题?

Sea*_*oyd 14

我想这是做到这一点的方法:

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();
}
Run Code Online (Sandbox Code Playgroud)

BTW,8971329902是一个很大的int领域.将字段类型设置为long.


小智 -2

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

  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.
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您可以使用 Hibernate Criteria API。

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

  • 请:如果英语不是您的母语,那也没关系。但尽量不要写“u”而不是“you”,这样会让一切变得更糟。另外,尽量不要拼错您引用的类、包和技术。你的帖子本身就很难阅读。 (2认同)