How do I migrate my JPA DAO to Spring data with a L2 cache?
I have a JPA DAO group looking to migrate to Spring Data JPA. Some of my DAOS have second level / query caching.
I have a process where I only get the ID in my requests and then view the object with findByID()
. Thus, only identifiers are multiplied in different query caches, and all objects are in the second-level cache.
Example:
@NamedQuery(name = "SystemUser.findByEmail",
query = "SELECT u.id FROM SystemUser u WHERE email=:email"),
β¦
public SystemUser findByEmail(String email) {
TypedQuery<Long> q = getEntityManager().createNamedQuery("SystemUser.findByEmail", Long.class);
q.setParameter("email", email);
q.setHint("org.hibernate.cacheable", true);
q.setHint("org.hibernate.cacheRegion", "query.systemUser");
List<Long> res = q.getResultList();
if (res != null && res.size() > 0) {
return findById(res.get(0));
}
return null;
}
I have a few more findByβ¦
-methods, it's all done like this. This seems like a good way to reduce memory consumption in caches.
I'm kind of new to the JPA Spring data business, but I can't figure out how I would go about implementing this here? The annotations @Cacheable
seem to only deal with the query caches, which for me would duplicate entities in each query cache?
Is there a way to do this with Spring Data? Pointers would be much appreciated.
source to share
In Spring Data JPA, just create a method findByEmail
and either Spring Data JPA will find your named query or create it on its own.
public class SystemUserRepository extends CrudRepository<SystemUser, Long> {
SystemUser findByEmail(String email);
}
There should be everything that is needed to fulfill the request and the desired result. Now with, @QueryHints
you can add the hints that you are currently installing.
public class SystemUserRepository extends CrudRepository<SystemUser, Long> {
@QueryHints(
@QueryHint(name="org.hibernate.cacheable", value="true"),
@QueryHint(name="org.hibernate.cacheRegion", value="query.systemUser") )
SystemUser findByEmail(String email);
}
The result will be cached and still the user will come from the 2nd level cache (if available, not created yet). Assuming your essence @Cacheable
.
A good read on how 2 different caches work (together) can be found here . A small fragment of how the request cache works.
The request cache looks conceptually like a hash map, where the key consists of the request text and parameter values, and is a list of entity identifiers that match the request :
If you want more complex logic (and actually implement the optimization you did), you can always implement your own repository .
source to share