Giter Site home page Giter Site logo

company-structure-hibernate-cache's Introduction

Spring Boot + Hibernate Ehcache Build Status

Example Spring Boot + Hibernate + Ehcache project for demonstration purposes of cache mechanism. Detailed explanations here

Getting started

To run application:

mvn package && java -jar target\company-structure-hibernate-cache-1.0-SNAPSHOT.jar

Prerequisites:

  • Java 8
  • Maven
  • H2/PostgreSQL

It is possible to run application in one of two profiles:

  • h2
  • postgres

depending on database engine chose for testing.

To enable cache statistics dev profile needs to be turned on.

Testing database schema

database-schema

Configuration

Cache regions are configured via ehcache.xml file. Following regions are defined:

  • companies by id
<cache name="company.byId"
           maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600"
           timeToLiveSeconds="3600" overflowToDisk="true"/>
  • companies by name
<cache name="company.byName"
           maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600"
           timeToLiveSeconds="3600" overflowToDisk="true"/>

To enable cache mechanism @EnableCaching annotation is added to configuration class. Cache beans are created via annotation:

@Configuration
@EnableCaching(mode = AdviceMode.ASPECTJ)
public class CacheConfiguration {

    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactory() {
        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        cacheManagerFactoryBean.setShared(true);

        return cacheManagerFactoryBean;
    }

    @Bean
    public EhCacheCacheManager ehCacheCacheManager() {
        EhCacheCacheManager cacheManager = new EhCacheCacheManager();
        cacheManager.setCacheManager(ehCacheManagerFactory().getObject());
        cacheManager.setTransactionAware(true);

        return cacheManager;
    }
}

Implementation

Caching rules are defined in CompanyRepository implementation:

  • cache creation
@Cacheable(value = "company.byId", key = "#id", unless = "#result != null and #result.name.toUpperCase().startsWith('TEST')")
public Company find(Long id) {
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Company> query = builder.createQuery(Company.class);

    Root<Company> root = query.from(Company.class);
    root.fetch(Company_.cars, JoinType.LEFT);
    Fetch<Company, Department> departmentFetch = root.fetch(Company_.departments, JoinType.LEFT);
    Fetch<Department, Employee> employeeFetch = departmentFetch.fetch(Department_.employees, JoinType.LEFT);
    employeeFetch.fetch(Employee_.address, JoinType.LEFT);
    departmentFetch.fetch(Department_.offices, JoinType.LEFT);

    query.select(root).distinct(true);
    Predicate idPredicate = builder.equal(root.get(Company_.id), id);
    query.where(builder.and(idPredicate));

    return DataAccessUtils.singleResult(entityManager.createQuery(query).getResultList());
}

@Cacheable(value = "company.byName", key = "#name", unless = "#name != null and #name.toUpperCase().startsWith('TEST')")
public Company find(String name) {
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Company> query = builder.createQuery(Company.class);

    Root<Company> root = query.from(Company.class);
    root.fetch(Company_.cars, JoinType.LEFT);
    Fetch<Company, Department> departmentFetch = root.fetch(Company_.departments, JoinType.LEFT);
    Fetch<Department, Employee> employeeFetch = departmentFetch.fetch(Department_.employees, JoinType.LEFT);
    employeeFetch.fetch(Employee_.address, JoinType.LEFT);
    departmentFetch.fetch(Department_.offices, JoinType.LEFT);

    query.select(root).distinct(true);
    Predicate idPredicate = builder.equal(root.get(Company_.name), name);
    query.where(builder.and(idPredicate));

    return DataAccessUtils.singleResult(entityManager.createQuery(query).getResultList());
}
  • cache invalidation
@Caching(evict = {@CacheEvict(value = "company.byId", key = "#company.id"), @CacheEvict(value = "company.byName", key = "#company.name")})
public void delete(Company company) {
    entityManager.remove(company);
}
  • cache update
@Caching(evict = {@CacheEvict(value = "company.byName", allEntries = true), @CacheEvict(value = "company.byId", key = "#result.id", condition = "#result != null and #result.name.toUpperCase().startsWith('TEST')")},
            put = {@CachePut(value = "company.byId", key = "#result.id", unless = "#result != null and #result.name.toUpperCase().startsWith('TEST')")})
public Company update(Company company) {
    return entityManager.merge(company);
}

Cache statistics

Optionally it's possible to expose MBean to gather cache statistics:

@Bean
public MBeanServer mBeanServer() {
    MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();

    return mBeanServer;
}

@Bean
public ManagementService managementService() {
    ManagementService managementService = new ManagementService(ehCacheCacheManager.getCacheManager(), mBeanServer(), true, true, true, true);
    managementService.init();

    return managementService;
}

company-structure-hibernate-cache's People

Contributors

adamzareba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

company-structure-hibernate-cache's Issues

Generate Model_

Nice repo,

I want to ask you something.

How do you generate model_ (Company_, Employee_, ETC)?

Is there a way?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.