Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA - FindByExample

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 provider (Hibernate), but I don't want to break with neutrality...

Seems like the criteria API might be the way to go....but I am not sure how to handle the reflection part of it.

like image 455
HDave Avatar asked May 21 '10 07:05

HDave


People also ask

What is example in JPA?

Spring Data JPA Query By Example Query by Example (QBE) is a user-friendly querying technique with a simple interface. It allows dynamic query creation. We do not need to write queries with store-specific query language. We work with three objects.

What is derived query in JPA?

A derived query method name has two main components separated by the first By keyword: The introducer clause like find , read , query , count , or get which tells Spring Data JPA what you want to do with the method.

What does findById return in JPA?

Its findById method retrieves an entity by its id. The return value is Optional<T> . Optional<T> is a container object which may or may not contain a non-null value. If a value is present, isPresent returns true and get returns the value.


1 Answers

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<Employee> 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
like image 182
Pascal Thivent Avatar answered Sep 28 '22 07:09

Pascal Thivent