How to use Spring, Hibernate, and EhCache Caching Features

In this post, we are going to demonstrate the Spring cache + EhCache feature on an example Spring Boot project. Caching will be defined as data queried from a relational database (example configurations prepared for H2 and PostgreSQL database engines).

Application

Let’s consider the database layer and application layer.

Database Layer

The below diagram shows relationships between data tables. Our main object type is Company, which we will want to cache. Company is related to many other tables; some of the relationships are OneToMany, so querying the whole structure might be a time-consuming operation.

Image title

Application Layer

The test application is developed in Spring Boot + Hibernate + Flyway with an exposed REST API. To demonstrate data company operations, the following endpoints were created:

@RestController
@RequestMapping("/company")
public class CompanyController {

    @Autowired
    private CompanyService companyService;

    @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody
    List<Company> getAll() {
        return companyService.getAll();
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody
    Company get(@PathVariable Long id) {
        return companyService.get(id);
    }

    @RequestMapping(value = "/filter", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody
    Company get(@RequestParam String name) {
        return companyService.get(name);
    }

    @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity<?> create(@RequestBody Company company) {
        companyService.create(company);
        HttpHeaders headers = new HttpHeaders();
        ControllerLinkBuilder linkBuilder = linkTo(methodOn(CompanyController.class).get(company.getId()));
        headers.setLocation(linkBuilder.toUri());
        return new ResponseEntity<>(headers, HttpStatus.CREATED);
    }

    @RequestMapping(method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public void update(@RequestBody Company company) {
        companyService.update(company);
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public void delete(@PathVariable Long id) {
        companyService.delete(id);
    }
}

Cache Configuration

Let’s see how to enable caching and work with cache regions.

Enable Caching

To enable the annotation-driven cache management capability in your Spring application, we need to add @EnableCaching annotation to configuration class. This annotation registers CacheInterceptor or AnnotationCacheAspect, which will detect cache annotations like @Cacheable, @CachePut, and @CacheEvict.

Spring comes with the cache manager interface org.springframework.cache.CacheManager, so we need to provide concrete implementation for cache storage. There’re multiple implementations, such as:

  • Generic
  • JCache
  • EhCache 2.x
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffeine

In this post, we are going to use the EhCache provider. The below example shows cache enabling with EhCache-related beans in a separate configuration class. Overriding these two beans is not needed if you want to stay with the default definition, but we wanted to make cache transactions aware to synchronize put/evict operations with ongoing Spring-managed transactions.

@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;
    }
}

Cache Regions

Cached data could be stored in separate regions and we can define individual configurations for cache items with an XML file. Let’s define two regions:

  1. Storing companies by ID.
  2. Storing companies by name.

For both regions, the maximum elements kept in memory is 10,000 and the maximum time for the company before it’s invalidated is 60 minutes (for more detailed configuration, go to EhCache Official Reference).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ehcache>
<ehcache>
    <diskStore path="java.io.tmpdir"/>

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

    <cache name="company.byName"
           maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600"
           timeToLiveSeconds="3600" overflowToDisk="true"/>
</ehcache>

Cache Operations

Let’s look at populating with @Cacheable, invaldating with @CacheEvict, and updating with @CachePut.

Populate: @Cacheable

The @Cacheable annotation indicates that the result of invoking a method (or all methods in a class) can be cached. Each time an advised method is invoked, the caching behavior will be applied, checking whether the method was already invoked for the given arguments.

In the example below, we want to cache Company objects in the company.byId cache region. The key in our region is the Company ID field. To handle something other than cache example test data (name starting with test), we can add a condition based on the result object (object returned as a result of a method).

@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());
}

To better see what’s happening, we can turn on debug-level logging for Hibernate:

logging.level.org.hibernate.SQL=debug

…and invoke REST company endpoint:

curl http://localhost:9000/company/1

Server logs will show the below SQL query only once:

2018-01-19 10:00:34.143 DEBUG 20256 --- [nio-8080-exec-4] org.hibernate.SQL                        : 
    select
        distinct company0_.id as id1_2_0_,
        cars1_.id as id1_1_1_,
        department2_.id as id1_3_2_,
        employees3_.id as id1_4_3_,
        address4_.id as id1_0_4_,
        offices5_.id as id1_5_5_,
        company0_.name as name2_2_0_,
        cars1_.company_id as company_3_1_1_,
        cars1_.registration_number as registra2_1_1_,
        cars1_.company_id as company_3_1_0__,
        cars1_.id as id1_1_0__,
        department2_.company_id as company_3_3_2_,
        department2_.name as name2_3_2_,
        department2_.company_id as company_3_3_1__,
        department2_.id as id1_3_1__,
        employees3_.address_id as address_4_4_3_,
        employees3_.department_id as departme5_4_3_,
        employees3_.name as name2_4_3_,
        employees3_.surname as surname3_4_3_,
        employees3_.department_id as departme5_4_2__,
        employees3_.id as id1_4_2__,
        address4_.house_number as house_nu2_0_4_,
        address4_.street as street3_0_4_,
        address4_.zip_code as zip_code4_0_4_,
        offices5_.address_id as address_3_5_5_,
        offices5_.department_id as departme4_5_5_,
        offices5_.name as name2_5_5_,
        offices5_.department_id as departme4_5_3__,
        offices5_.id as id1_5_3__ 
    from
        company company0_ 
    left outer join
        car cars1_ 
            on company0_.id=cars1_.company_id 
    left outer join
        department department2_ 
            on company0_.id=department2_.company_id 
    left outer join
        employee employees3_ 
            on department2_.id=employees3_.department_id 
    left outer join
        address address4_ 
            on employees3_.address_id=address4_.id 
    left outer join
        office offices5_ 
            on department2_.id=offices5_.department_id 
    where
        company0_.id=1

The next time the repository method is invoked, data will be gathered from the cache.

The example below shows an implementation for caching data based on the name.

@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());
}

Invalidate: @CacheEvict

The @CacheEvict annotation indicates that a method (or all methods on a class) triggers a cache evict operation, removing only specific or removing all items from the cache region.

Since the code below removes data from the database, the object needs to be removed from both caches:

@Caching(evict = {@CacheEvict(value = "company.byId", key = "#company.id"), @CacheEvict(value = "company.byName", key = "#company.name")})
public void delete(Company company) {
    entityManager.remove(company);
}

Update: @CachePut

With the @CachePut annotation, it’s possible to update the cache. In the below example, the cache for storing companies by ID is updated. It’s worth noting that since the company name is mutable, we cannot update the cache because we don’t know the old name value for that company. To proceed with that, we remove all entries in the cache for companies by name.

@Caching(evict = {@CacheEvict(value = "company.byName", allEntries = true)},
        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

To preview live cache, statistics it is possible to expose EhCache MBeans through JMX like below:

@Configuration
@Dev
public class CacheMonitoring {

    @Autowired
    private EhCacheCacheManager ehCacheCacheManager;

    @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;
    }
}

The following MBeans will be exposed:

  • CacheManager
  • Cache
  • CacheConfiguration
  • CacheStatistics

Image title

Summary

In this post, we covered basic cache operations like getting, inserting, removing, and updating. Defining these operations and more complex requirements (like conditional caching or cache synchronization) is straightforward with annotations.

The source code for above listings can be found in the GitHub project company-structure-hibernate-cache.

#Spring #Hibernate #Java #WebDev

What is GEEK

Buddha Community

How to use Spring, Hibernate, and EhCache Caching Features
Samanta  Moore

Samanta Moore

1623017160

Spring, Hibernate, EhCache Recipe

Integration of Spring and Hibernate with Second Level Cache (EhCache) is Demonstrated using a Simple Example. Check for Yourself the Positive Impact of a Second Level Cache in Hibernate.

A Simple Scenario explaining the Usage and Performance, when using EhCache (2nd Level Cache of along with Hibernate in a Spring environment. The performance results are taken using mySQL as the Database.

Though this Example is from Spring 2.5.x and Hibernate 3.x and EhCache 1.4, MySQL 5.0 => The Concepts Demonstrated will Continue to Hold Good for any Version of any Make of Second Level Cache Product with Hibernate (Optionally, Spring) such as Infinispan, Redis, Hazelcast, …

[Download Sample Code] Please be informed that the size is about 10MB; as i have provided all the dependencies.

In this example, I need to retrieve close to 5,000 records in a single fetch and then cache this information. As usual, setup Spring contexts in your Spring configuration file. I have just one class, which is a Hibernate DAO, _HibernateDoctorDAO.java. _The dependency injection hierarchy is dataSource **> **sessionFactory **> **hibernateTemplate. hibernateTemplate is then injected into the _HibernateDoctorDAO.java _at runtime by the Spring Framework.

#hibernate #j2ee #core java #java performance #ehcache #mysql ( 5 ) #data caching #java persistence #spring 2.5 #hibernate caching

How to use Spring, Hibernate, and EhCache Caching Features

In this post, we are going to demonstrate the Spring cache + EhCache feature on an example Spring Boot project. Caching will be defined as data queried from a relational database (example configurations prepared for H2 and PostgreSQL database engines).

Application

Let’s consider the database layer and application layer.

Database Layer

The below diagram shows relationships between data tables. Our main object type is Company, which we will want to cache. Company is related to many other tables; some of the relationships are OneToMany, so querying the whole structure might be a time-consuming operation.

Image title

Application Layer

The test application is developed in Spring Boot + Hibernate + Flyway with an exposed REST API. To demonstrate data company operations, the following endpoints were created:

@RestController
@RequestMapping("/company")
public class CompanyController {

    @Autowired
    private CompanyService companyService;

    @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody
    List<Company> getAll() {
        return companyService.getAll();
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody
    Company get(@PathVariable Long id) {
        return companyService.get(id);
    }

    @RequestMapping(value = "/filter", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public @ResponseBody
    Company get(@RequestParam String name) {
        return companyService.get(name);
    }

    @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public ResponseEntity<?> create(@RequestBody Company company) {
        companyService.create(company);
        HttpHeaders headers = new HttpHeaders();
        ControllerLinkBuilder linkBuilder = linkTo(methodOn(CompanyController.class).get(company.getId()));
        headers.setLocation(linkBuilder.toUri());
        return new ResponseEntity<>(headers, HttpStatus.CREATED);
    }

    @RequestMapping(method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public void update(@RequestBody Company company) {
        companyService.update(company);
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public void delete(@PathVariable Long id) {
        companyService.delete(id);
    }
}

Cache Configuration

Let’s see how to enable caching and work with cache regions.

Enable Caching

To enable the annotation-driven cache management capability in your Spring application, we need to add @EnableCaching annotation to configuration class. This annotation registers CacheInterceptor or AnnotationCacheAspect, which will detect cache annotations like @Cacheable, @CachePut, and @CacheEvict.

Spring comes with the cache manager interface org.springframework.cache.CacheManager, so we need to provide concrete implementation for cache storage. There’re multiple implementations, such as:

  • Generic
  • JCache
  • EhCache 2.x
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffeine

In this post, we are going to use the EhCache provider. The below example shows cache enabling with EhCache-related beans in a separate configuration class. Overriding these two beans is not needed if you want to stay with the default definition, but we wanted to make cache transactions aware to synchronize put/evict operations with ongoing Spring-managed transactions.

@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;
    }
}

Cache Regions

Cached data could be stored in separate regions and we can define individual configurations for cache items with an XML file. Let’s define two regions:

  1. Storing companies by ID.
  2. Storing companies by name.

For both regions, the maximum elements kept in memory is 10,000 and the maximum time for the company before it’s invalidated is 60 minutes (for more detailed configuration, go to EhCache Official Reference).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ehcache>
<ehcache>
    <diskStore path="java.io.tmpdir"/>

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

    <cache name="company.byName"
           maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600"
           timeToLiveSeconds="3600" overflowToDisk="true"/>
</ehcache>

Cache Operations

Let’s look at populating with @Cacheable, invaldating with @CacheEvict, and updating with @CachePut.

Populate: @Cacheable

The @Cacheable annotation indicates that the result of invoking a method (or all methods in a class) can be cached. Each time an advised method is invoked, the caching behavior will be applied, checking whether the method was already invoked for the given arguments.

In the example below, we want to cache Company objects in the company.byId cache region. The key in our region is the Company ID field. To handle something other than cache example test data (name starting with test), we can add a condition based on the result object (object returned as a result of a method).

@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());
}

To better see what’s happening, we can turn on debug-level logging for Hibernate:

logging.level.org.hibernate.SQL=debug

…and invoke REST company endpoint:

curl http://localhost:9000/company/1

Server logs will show the below SQL query only once:

2018-01-19 10:00:34.143 DEBUG 20256 --- [nio-8080-exec-4] org.hibernate.SQL                        : 
    select
        distinct company0_.id as id1_2_0_,
        cars1_.id as id1_1_1_,
        department2_.id as id1_3_2_,
        employees3_.id as id1_4_3_,
        address4_.id as id1_0_4_,
        offices5_.id as id1_5_5_,
        company0_.name as name2_2_0_,
        cars1_.company_id as company_3_1_1_,
        cars1_.registration_number as registra2_1_1_,
        cars1_.company_id as company_3_1_0__,
        cars1_.id as id1_1_0__,
        department2_.company_id as company_3_3_2_,
        department2_.name as name2_3_2_,
        department2_.company_id as company_3_3_1__,
        department2_.id as id1_3_1__,
        employees3_.address_id as address_4_4_3_,
        employees3_.department_id as departme5_4_3_,
        employees3_.name as name2_4_3_,
        employees3_.surname as surname3_4_3_,
        employees3_.department_id as departme5_4_2__,
        employees3_.id as id1_4_2__,
        address4_.house_number as house_nu2_0_4_,
        address4_.street as street3_0_4_,
        address4_.zip_code as zip_code4_0_4_,
        offices5_.address_id as address_3_5_5_,
        offices5_.department_id as departme4_5_5_,
        offices5_.name as name2_5_5_,
        offices5_.department_id as departme4_5_3__,
        offices5_.id as id1_5_3__ 
    from
        company company0_ 
    left outer join
        car cars1_ 
            on company0_.id=cars1_.company_id 
    left outer join
        department department2_ 
            on company0_.id=department2_.company_id 
    left outer join
        employee employees3_ 
            on department2_.id=employees3_.department_id 
    left outer join
        address address4_ 
            on employees3_.address_id=address4_.id 
    left outer join
        office offices5_ 
            on department2_.id=offices5_.department_id 
    where
        company0_.id=1

The next time the repository method is invoked, data will be gathered from the cache.

The example below shows an implementation for caching data based on the name.

@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());
}

Invalidate: @CacheEvict

The @CacheEvict annotation indicates that a method (or all methods on a class) triggers a cache evict operation, removing only specific or removing all items from the cache region.

Since the code below removes data from the database, the object needs to be removed from both caches:

@Caching(evict = {@CacheEvict(value = "company.byId", key = "#company.id"), @CacheEvict(value = "company.byName", key = "#company.name")})
public void delete(Company company) {
    entityManager.remove(company);
}

Update: @CachePut

With the @CachePut annotation, it’s possible to update the cache. In the below example, the cache for storing companies by ID is updated. It’s worth noting that since the company name is mutable, we cannot update the cache because we don’t know the old name value for that company. To proceed with that, we remove all entries in the cache for companies by name.

@Caching(evict = {@CacheEvict(value = "company.byName", allEntries = true)},
        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

To preview live cache, statistics it is possible to expose EhCache MBeans through JMX like below:

@Configuration
@Dev
public class CacheMonitoring {

    @Autowired
    private EhCacheCacheManager ehCacheCacheManager;

    @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;
    }
}

The following MBeans will be exposed:

  • CacheManager
  • Cache
  • CacheConfiguration
  • CacheStatistics

Image title

Summary

In this post, we covered basic cache operations like getting, inserting, removing, and updating. Defining these operations and more complex requirements (like conditional caching or cache synchronization) is straightforward with annotations.

The source code for above listings can be found in the GitHub project company-structure-hibernate-cache.

#Spring #Hibernate #Java #WebDev

Were  Joyce

Were Joyce

1620728340

Spring Framework: To Use Or Not To Use, That Is The Question

It’s impossible to write OOP code with Spring. From its core it promotes the use of singletons and anemic data structures a.k.a. data “objects” a.k.a. DTO. This fuels procedural programming and kills OOP.

In the next paragraphs I’ll highlight three **major **Spring components involved. I start from the core.

IoC Container

The core of Spring is the IoC container, represented by the

ApplicationContextinterface. Basically it defines a context through which we get beans. A bean is an object managed by the container and it has a name attached to it.

We can configure the context thanks to some annotations, called steorotype. These annotations were introduced in Spring 2.5 and enhanced in Spring 3.0. Previously we could only use an external XML. This was even worse…

So we annotate a class with a stereotype, the container reads it and it builds a bean. A bean is a singleton. For this reason it cannot represent anything specific. This means that to do something useful we should pass around data “objects” through them.

A bean is an object only from a technological point of view. But at the conceptual level it’s just a namespace for procedures. In other words it’s a bunch of procedure grouped by a name. Nothing more. Every bean, regardless the stereotype, is bad.

This is not OOP. But I’m not saying anything new. It’s known that singleton are bad. But this (anti)pattern is the Spring backbone.

At this point it should suffice to say that everything else in Spring is based on bean. This means that every Spring application is composed by bean that works on data structure. Definitely this is not OOP.

However I think that things gets worse with the next two components…

#spring #spring-boot #java #spring-mvc #spring-data #oop #procedural-programming #software-engineering

Why Use WordPress? What Can You Do With WordPress?

Can you use WordPress for anything other than blogging? To your surprise, yes. WordPress is more than just a blogging tool, and it has helped thousands of websites and web applications to thrive. The use of WordPress powers around 40% of online projects, and today in our blog, we would visit some amazing uses of WordPress other than blogging.
What Is The Use Of WordPress?

WordPress is the most popular website platform in the world. It is the first choice of businesses that want to set a feature-rich and dynamic Content Management System. So, if you ask what WordPress is used for, the answer is – everything. It is a super-flexible, feature-rich and secure platform that offers everything to build unique websites and applications. Let’s start knowing them:

1. Multiple Websites Under A Single Installation
WordPress Multisite allows you to develop multiple sites from a single WordPress installation. You can download WordPress and start building websites you want to launch under a single server. Literally speaking, you can handle hundreds of sites from one single dashboard, which now needs applause.
It is a highly efficient platform that allows you to easily run several websites under the same login credentials. One of the best things about WordPress is the themes it has to offer. You can simply download them and plugin for various sites and save space on sites without losing their speed.

2. WordPress Social Network
WordPress can be used for high-end projects such as Social Media Network. If you don’t have the money and patience to hire a coder and invest months in building a feature-rich social media site, go for WordPress. It is one of the most amazing uses of WordPress. Its stunning CMS is unbeatable. And you can build sites as good as Facebook or Reddit etc. It can just make the process a lot easier.
To set up a social media network, you would have to download a WordPress Plugin called BuddyPress. It would allow you to connect a community page with ease and would provide all the necessary features of a community or social media. It has direct messaging, activity stream, user groups, extended profiles, and so much more. You just have to download and configure it.
If BuddyPress doesn’t meet all your needs, don’t give up on your dreams. You can try out WP Symposium or PeepSo. There are also several themes you can use to build a social network.

3. Create A Forum For Your Brand’s Community
Communities are very important for your business. They help you stay in constant connection with your users and consumers. And allow you to turn them into a loyal customer base. Meanwhile, there are many good technologies that can be used for building a community page – the good old WordPress is still the best.
It is the best community development technology. If you want to build your online community, you need to consider all the amazing features you get with WordPress. Plugins such as BB Press is an open-source, template-driven PHP/ MySQL forum software. It is very simple and doesn’t hamper the experience of the website.
Other tools such as wpFoRo and Asgaros Forum are equally good for creating a community blog. They are lightweight tools that are easy to manage and integrate with your WordPress site easily. However, there is only one tiny problem; you need to have some technical knowledge to build a WordPress Community blog page.

4. Shortcodes
Since we gave you a problem in the previous section, we would also give you a perfect solution for it. You might not know to code, but you have shortcodes. Shortcodes help you execute functions without having to code. It is an easy way to build an amazing website, add new features, customize plugins easily. They are short lines of code, and rather than memorizing multiple lines; you can have zero technical knowledge and start building a feature-rich website or application.
There are also plugins like Shortcoder, Shortcodes Ultimate, and the Basics available on WordPress that can be used, and you would not even have to remember the shortcodes.

5. Build Online Stores
If you still think about why to use WordPress, use it to build an online store. You can start selling your goods online and start selling. It is an affordable technology that helps you build a feature-rich eCommerce store with WordPress.
WooCommerce is an extension of WordPress and is one of the most used eCommerce solutions. WooCommerce holds a 28% share of the global market and is one of the best ways to set up an online store. It allows you to build user-friendly and professional online stores and has thousands of free and paid extensions. Moreover as an open-source platform, and you don’t have to pay for the license.
Apart from WooCommerce, there are Easy Digital Downloads, iThemes Exchange, Shopify eCommerce plugin, and so much more available.

6. Security Features
WordPress takes security very seriously. It offers tons of external solutions that help you in safeguarding your WordPress site. While there is no way to ensure 100% security, it provides regular updates with security patches and provides several plugins to help with backups, two-factor authorization, and more.
By choosing hosting providers like WP Engine, you can improve the security of the website. It helps in threat detection, manage patching and updates, and internal security audits for the customers, and so much more.

Read More

#use of wordpress #use wordpress for business website #use wordpress for website #what is use of wordpress #why use wordpress #why use wordpress to build a website

Were  Joyce

Were Joyce

1620720872

Spring vs Spring BooDifference Between Spring and Spring Boot

As an extension of the Spring Framework, Spring Boot is widely used to make development on Spring faster, more efficient and convenient. In this article, we will look at some of the parameters were using Spring Boot can drastically reduce the time and effort required in application development.

What is Spring?

Spring Boot

Difference between Spring and Spring Boot

Advantages of Spring Boot over Spring

Conclusion

#full stack development #spring #spring and spring boot #spring boot