I am relatively new to JPA and I would like to solve the following problem using jpql exclusively (note that the implementation I am using is Datanucleus): I have a table of versioned entities, and I would like to get the latest version for all entities in the table (i.e. I have an entity class which has an id (which uniquely identifies a row, an entityId (which identifies the entity itself throughout versions) and a timestamp; I would like to get the latest version entity for all entityId). My current code goes as follows:
String innerQueryString = "SELECT entity.entityId, max(entity.timestamp) " +
"FROM Entity entity" +
"GROUP BY entity.entityId";
Query getQuery = getEntityManager().createQuery(innerQueryString);
List<Object[]> queryRes = getQuery.getResultList();
List<IEntity> ret = new ArrayList<IEntity>();
for (Object[] res : queryRes) {
ret.add(getEntity((Long)res[0], (Date)res[1]));
}
return ret;
Where getEntity gets the entity data for the specified entityId, timestamp. I have found several resources on how this code would work in sql here http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ but I cannot manage to create a jpql version of it. Help will be greatly appreciated, thanks.
JPQL does not provide a mechanism to limit queries. This is most often achieved by using the setMaxResults() method on the Query . If you must avoid specifying this in Java code, you could make a view in the database that contains your query and performs the limit. Then map an entity to this view as you would a table.
JPQL FeaturesIt is a platform-independent query language. It is simple and robust. It can be used with any type of database such as MySQL, Oracle. JPQL queries can be declared statically into metadata or can also be dynamically built in code.
The EntityManager's createQuery is used to create the Query instance whose getResultList method is then used to execute the JPQL query passed to createQuery as the parameter.
Jpql advantages: Jpql takes advantage of mapping (lazy / eager loading, relatinships) - it uses what you have already defined. In SQL you would have to map the result somehow. Queries can be stored in cache to provide better performance.
If timestamp
s are unique per entityId
, you can write something like this:
SELECT e FROM Entity e
WHERE e.timestamp = (SELECT MAX(ee.timestamp) FROM Entity ee WHERE ee.entityId = e.entityId)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With