Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
This file is part of JPARepositoryCache. Copyright 2015 Ivan Krizsan. JPARepositoryCache is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. JPARepositoryCache is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with JPARepositoryCache. If not, see <http://www.gnu.org/licenses/>.
 
 package se.ivankrizsan.spring.jparepositorycache.repositoryhelpers;
 
 import java.util.List;
 import  org.springframework.beans.factory.annotation.Required;
 import  org.springframework.data.domain.Page;
 import  org.springframework.data.domain.Pageable;
 import  org.springframework.data.domain.Sort;
 import  org.springframework.data.jpa.repository.JpaRepository;
 import  org.springframework.data.repository.NoRepositoryBean;

Spring Data JPA repository caching proxy that enables caching of entities in the repository and allows for retrieval of such entities when the database in which entities are stored is offline.

Note that the methods exists and count does not use the cache but always relies on access to the database. Also note that the caching proxy does not consider entities which have relations that are loaded lazily - such entities will be inserted into the cache as retrieved from the repository delegate.

Author(s):
Ivan Krizsan
 
 @NoRepositoryBean
 public class CachingJpaRepository<T extends EntityWithId<?>, ID extends Serializableimplements
     /* Constant(s): */
    
String prefix used when constructing a key to the single entities cache.
 
     protected static final String SINGLE_ENTITIES_CACHE_KEY_PREFIX = "entity";
    
Cache key used when inserting an unordered list containing all entities.
 
     protected static final String ALL_ENTITIES_LIST_CACHE_KEY_PREFIX = "allEntitiesUnordered";
    
Cache key prefix used when inserting a sorted list containing all entities.
 
     protected static final String ALL_ENTITIES_SORTEDLIST_CACHE_KEY_PREFIX = "allEntitiesSorted";
 
     /* Instance variable(s): */
    
Repository to which interaction with database is delegated to.
 
     protected JpaRepository<T, ID> mRepositoryDelegate;
    
Cache delegate which is responsible for maintaining the repository cache.
 
     protected RepositoryCacheDelegate<T> mCacheDelegate;

    
Retrieves a page of entities. One page of entities is cached as one entry in the cache using the data in the Pageable parameter as key.

Parameters:
inPageable Specifies which entities are to be contained in the page.
 
     @Override
     public Page<T> findAll(final Pageable inPageable) {
         final String theCacheKey =
             "page" + inPageable.getPageNumber() + "pageSize" + inPageable.getPageSize() + "offset"
                 + inPageable.getOffset() + "sort" + inPageable.getSort();
 
         @SuppressWarnings("unchecked")
         Page<T> theEntitiesPage = (Page<T>) .findObjectInMultipleEntitiesCache(theCacheKey);
         if (theEntitiesPage == null) {
             theEntitiesPage = .findAll(inPageable);
             .insertObjectIntoMultipleEntitiesCache(theCacheKeytheEntitiesPage);
         }
 
         return theEntitiesPage;
     }

    
Saves the supplied entity. Updates the single entity cache and evicts all entries in the multiple entities cache. Caches are not updated if the operation on the repository throws an exception.

Parameters:
inEntity Entity to save.
 
     @Override
     public <S extends T> S save(final S inEntity) {
         final S theSavedEntity = .save(inEntity);
         final String theCacheKey = createCacheKeyForSingleEntity(theSavedEntity);
         .insertEntityIntoSingleEntitiesCache(theCacheKeytheSavedEntity);
         return theSavedEntity;
     }

    
Finds the entity with supplied id.

Parameters:
inId Id of entity to find.
    @Override
    public T findOne(final ID inId) {
        final String theCacheKey = createCacheKeyForSingleEntityId(inId);
        T theEntity = .findEntityInSingleEntitiesCache(theCacheKey);
        if (theEntity == null) {
            theEntity = .findOne(inId);
            if (theEntity != null) {
                .insertEntityIntoSingleEntitiesCache(theCacheKeytheEntity);
            }
        }
        return theEntity;
    }

    
Note! This method interacts directly with the database and does not use the cache.
    @Override
    public boolean exists(final ID inId) {
        return .exists(inId);
    }

    
Note! This method interacts directly with the database and does not use the cache.
    @Override
    public long count() {
        return .count();
    }

    
Deletes the entity specified by supplied id from the repository. Evicts the entity from the single entity cache and evicts all entries in the multiple entities cache. Caches are not updated if the operation on the repository throws an exception.

Parameters:
inId Id of entity to delete.
    @Override
    public void delete(final ID inId) {
        final String theCacheKey = createCacheKeyForSingleEntityId(inId);
        .delete(inId);
    }

    
Deletes the supplied entity from the repository. Evicts the entity from the single entity cache and evicts all entries in the multiple entities cache. Caches are not updated if the operation on the repository throws an exception.

Parameters:
inEntity Entity to delete.
    @Override
    public void delete(final T inEntity) {
        final String theCacheKey = createCacheKeyForSingleEntity(inEntity);
        .delete(inEntity);
    }

    
Deletes the entities specified by suppled iterable from the repository. Evicts the entities from the single entity cache and evicts all entries in the multiple entities cache. Caches are not updated if the operation on the repository throws an exception.

Parameters:
inEntities Entities to delete.
    @Override
    public void delete(final Iterable<? extends T> inEntities) {
        .delete(inEntities);
        for (T theEntity : inEntities) {
            final String theCacheKey = createCacheKeyForSingleEntity(theEntity);
            .evictEntityFromSingleEntitiesCache(theCacheKey);
        }
    }

    
Deletes all entities. Evicts all entities of this type from caches.
    @Override
    public void deleteAll() {
        .deleteAll();
    }

    
Finds all entities in the repository. The list of retrieved entities is cached as one entry in the cache. If the list of entities is not present in the cache, it is inserted in the cache and each entity in the list is inserted into the single entity cache.

Returns:
List of all entities in the repository.
    @Override
    public List<T> findAll() {
        @SuppressWarnings("unchecked")
        List<T> theEntities =
        if (theEntities == null) {
            theEntities = .findAll();
            /* Insert list of entities into multiple entities cache. */
            /* Insert each discrete entity in the single entities cache. */
            for (T theEntity : theEntities) {
                final String theEntityCacheKey = createCacheKeyForSingleEntity(theEntity);
                .insertEntityIntoSingleEntitiesCache(theEntityCacheKeytheEntity);
            }
        }
        return theEntities;
    }

    
Finds all entities in the repository and sort them according to the supplied Sort object. List of sorted entities are cached as one entry in the cache using the Sort parameter to create the cache key. If the list of entities is not present in the cache, it is inserted in the cache and each entity in the list is inserted into the single entity cache.

Parameters:
inSort Specifies how to sort the retrieved entities.
Returns:
Sorted list of entities.
    @Override
    public List<T> findAll(final Sort inSort) {
        final String theCacheKey =  + inSort.toString();
        @SuppressWarnings("unchecked")
        List<T> theEntities = (List<T>) .findObjectInMultipleEntitiesCache(theCacheKey);
        if (theEntities == null) {
            theEntities = .findAll(inSort);
            .insertObjectIntoMultipleEntitiesCache(theCacheKeytheEntities);
            /* Insert each discrete entity in the single entities cache. */
            for (T theEntity : theEntities) {
                final String theEntityCacheKey = createCacheKeyForSingleEntity(theEntity);
                .insertEntityIntoSingleEntitiesCache(theEntityCacheKeytheEntity);
            }
        }
        return theEntities;
    }

    
Retrieves all the entities with ids specified by the supplied iterable. Entities retrieved using this method are cached in the single entities cache. This method will attempt to locate each entity in the cache. If an entity is not present in the cache and can be retrieved from the repository, it will be placed in the cache.

Parameters:
inIds Ids of entities to retrieve.
    @Override
    public List<T> findAll(final Iterable<ID> inIds) {
        final List<T> theFoundEntities = new ArrayList<T>();
        for (ID theEntityId : inIds) {
            final String theEntityCacheKey = createCacheKeyForSingleEntityId(theEntityId);
            final T theEntity = .findEntityInSingleEntitiesCache(theEntityCacheKey);
            if (theEntity != null) {
                /* Entity found in cache. */
                theFoundEntities.add(theEntity);
            } else {
                /* No entity in cache, try database. */
                final T theDbEntity = .findOne(theEntityId);
                if (theDbEntity != null) {
                    theFoundEntities.add(theDbEntity);
                    /* Also insert the entity into the cache. */
                    .insertEntityIntoSingleEntitiesCache(theEntityCacheKeytheDbEntity);
                }
            }
        }
        return theFoundEntities;
    }

    
Saves the supplied entities in the repository. Saves the entities from the single entity cache and evicts all entries in the multiple entities cache. Caches are not updated if the operation on the repository throws an exception.

Parameters:
inEntities Entities to save.
    @Override
    public <S extends T> List<S> save(final Iterable<S> inEntities) {
        final List<S> theSavedEntities = .save(inEntities);
        /* Save saved entities to single entity cache. */
        for (S theSavedEntity : theSavedEntities) {
            final String theEntityCacheKey = createCacheKeyForSingleEntity(theSavedEntity);
            .insertEntityIntoSingleEntitiesCache(theEntityCacheKeytheSavedEntity);
        }
        /* Evict all entries in the multiple entities cache. */
        return theSavedEntities;
    }
    @Override
    public void flush() {
        .flush();
    }

    
Saves the supplied entity and flushes changes immediately. Updates the single entity cache and evicts all entries in the multiple entities cache. Caches are not updated if the operation on the repository throws an exception.

Parameters:
inEntity Entity to save.
    @Override
    public <S extends T> S saveAndFlush(final S inEntity) {
        final S theSavedEntity = .saveAndFlush(inEntity);
        final String theEntityCacheKey = createCacheKeyForSingleEntity(theSavedEntity);
        .insertEntityIntoSingleEntitiesCache(theEntityCacheKeytheSavedEntity);
        return theSavedEntity;
    }

    
Deletes the entities specified by suppled iterable from the repository. Evicts the entities from the single entity cache and evicts all entries in the multiple entities cache. Caches are not updated if the operation on the repository throws an exception.

Parameters:
inEntities Entities to delete.
    @Override
    public void deleteInBatch(final Iterable<T> inEntities) {
        .deleteInBatch(inEntities);
        for (T theEntity : inEntities) {
            final String theEntityCacheKey = createCacheKeyForSingleEntity(theEntity);
            .evictEntityFromSingleEntitiesCache(theEntityCacheKey);
        }
    }
    @Override
    public void deleteAllInBatch() {
        .deleteAllInBatch();
    }
    @Override
    public T getOne(final ID inId) {
        final String theEntityCacheKey = createCacheKeyForSingleEntityId(inId);
        T theEntity = .findEntityInSingleEntitiesCache(theEntityCacheKey);
        if (theEntity == null) {
            theEntity = .findOne(inId);
            if (theEntity != null) {
                .insertEntityIntoSingleEntitiesCache(theEntityCacheKeytheEntity);
            }
        }
        return theEntity;
    }

    
Creates a single entity cache key for the supplied entity.

Parameters:
inEntity Entity to create cache key for.
Returns:
Single entity cache key.
    protected String createCacheKeyForSingleEntity(final T inEntity) {
        return  + inEntity.getId().toString();
    }

    
Creates a single entity cache key for an entity with the supplied id.

Parameters:
inId Entity id to create cache key for.
Returns:
Single entity cache key.
    protected String createCacheKeyForSingleEntityId(final ID inId) {
        return  + inId.toString();
    }
    public JpaRepository<T, ID> getRepositoryDelegate() {
        return ;
    }
    @Required
    public void setRepositoryDelegate(final JpaRepository<T, ID> inRepositoryDelegate) {
         = inRepositoryDelegate;
    }
        return ;
    }
    @Required
    public void setCacheDelegate(final RepositoryCacheDelegate<T> inCacheDelegate) {
        /* Ensure that the delegate is of the correct type. */
        if (!(inCacheDelegate instanceof EhcacheRepositoryCacheDelegate)) {
            throw new RuntimeException("Attempted to set a cache delegate of the wrong type: "
                + inCacheDelegate.getClass().getName());
        }
        @SuppressWarnings("unchecked")
        final EhcacheRepositoryCacheDelegate<T, ID> theCacheDelegate =
        (EhcacheRepositoryCacheDelegate<T, ID>) inCacheDelegate;
         = theCacheDelegate;
    }
New to GrepCode? Check out our FAQ X