JPA - FindByExample

前端 未结 7 2007
故里飘歌
故里飘歌 2020-12-08 04:29

Does anyone have a good example for how to do a findByExample in JPA that will work within a generic DAO via reflection for any entity type? I know I can do it via my prov

7条回答
  •  佛祖请我去吃肉
    2020-12-08 05:16

    Actually, Query By Example (QBE) has been considered for inclusion in the JPA 2.0 specification but is not included, even if major vendors support it. Quoting Mike Keith:

    I'm sorry to say that we didn't actually get to do QBE in JPA 2.0. Criteria API does not have any special operators for it so entity equality is just like in JP QL, based on PK value. Sorry, but hopefully we'll be more successful on that front in the next go-round. For now it is one of those vendor features that every vendor supports, but is not in the spec yet.

    Just in case, I've added (non generic) sample code for the major vendors below for documentation purposes.

    EclipseLink

    Here is a sample of using QBE in the EclipseLink JPA 2.0 reference implementation:

    // Create a native EclipseLink query using QBE policy
    QueryByExamplePolicy policy = new QueryByExamplePolicy();
    policy.excludeDefaultPrimitiveValues();
    ReadObjectQuery q = new ReadObjectQuery(sampleEmployee, policy);
    
    // Wrap the native query in a standard JPA Query and execute it 
    Query query = JpaHelper.createQuery(q, em); 
    return query.getSingleResult(); 
    

    OpenJPA

    OpenJPA supports this style of query through its extended OpenJPAQueryBuilder interface:

    CriteriaQuery q = cb.createQuery(Employee.class);
    
    Employee example = new Employee();
    example.setSalary(10000);
    example.setRating(1);
    
    q.where(cb.qbe(q.from(Employee.class), example);
    

    Hibernate

    And with Hibernate's Criteria API:

    // get the native hibernate session
    Session session = (Session) getEntityManager().getDelegate();
    // create an example from our customer, exclude all zero valued numeric properties 
    Example customerExample = Example.create(customer).excludeZeroes();
    // create criteria based on the customer example
    Criteria criteria = session.createCriteria(Customer.class).add(customerExample);
    // perform the query
    criteria.list();
    

    Now, while it should be possible to implement something approaching in a vendor neutral way with JPA 2.0 Criteria API and reflection, I really wonder if it's worth the effort. I mean, if you make any of the above snippets generic and put the code in a DAO method, it would be quite easy to switch from one vendor to another if the need should arise. I agree it's not ideal, but still.

    References

    • What about findByExample in JPA book?
    • Dynamic, typesafe queries in JPA 2.0

提交回复
热议问题