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.

+3


source to share


1 answer


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 .

+4


source







All Articles