How exactly does one integrate a cache in his project (spring + hibernate) - spring

I have a project that supports 10's of concurrent users.
My project is a spring + hibernate project with a MYSQL DB.
I would like to keep a cache for some of my entities (i.e. Player)
I have a couple of questions:
1) how do I exactly work with a cache (when i have one) ? if i have to persist a Player do i change the cache and immediately persist with hibernate?
2) Does spring support a cache mechanism ? if so how does one work with it?

Hibernate
Hibernate has Second level cache. To start work with you need to:
choose some cache provider (EHCache, Infinispan, ...).
configure cache region (and choose corresponding strategy depending on your situation)
enable cache for some entity
It is declarative, most of the time you do not need to change any application code.
Spring
Spring has cache abstraction. There are some common steps (choose chache provider, configure cache regions). But it is more general pourpose cache, not related to Hibernate entities and transactions. So you must do more work (annotate all necessary methods with annotations).
In general if your Player class is a Hibernate entity then it will be better to go with Hibernate cache. It may be not true if you have some special demands.
Hope it helps.

Related

Spring(boot)-redis caching- does it need repository creation?

I would like to ask a question about the spring cache annotation and repository creation.
I am trying to cache my values in redis using the Spring boot.
(I have a value, if it is not in cache, I need to cache it, if it is in cache, I need to get it from there)
I have seen a couple of tutorials on line, some using the cache annotations and others simulating the cache repository. (maybe they do not exclude each other, this is my question about)
Here are some of the tutorials that I have read:
Cache annotation tips
Caching Data using Redis
Intro to Redis with Spring Boot
Spring Boot Redis cache
Some of the above use the #Cacheable, #CachePut and #CacheEvict annotations:
#CachePut(value = 'user', key = "#id")
#CacheEvict(value = 'user', key = "#id")
and prefix the supposed-to-be-stored class with the following annotation:
#RedisHash("balance")
They also extend the JPA or CrudRepository. The 3rd one one, however, creates its own repository.
My question is:
If I used the above annotations (#Cacheable, #CachePut and #CacheEvict) should I create a repository for the class objects I am interested in storing by extending the CrudRepository?
Or does spring create it automatically when using the above annotation and manage it automatically?
An if you extend the CrudRepository yourself, how would you retrieve the items by key from Redis?
Thanks
No this is not needed. Notice that the third link does not mention caching up front. There are two projects , spring cache with a redis cache provider and spring data redis. The third link is talking about the larger and more general use case. Spring data redis is meant to support redis as a full fledged persistence layer. However you are certainly free to only use redis as a caching layer. In this case you do not need to do anything nor should you besides using the normal annotations

Spring Roo and EhCache

roo-1.3.1.RC1.
I created simple 3-4 tables with proper PK and FK relations.
I loaded data into it.
I use spring-roo - reverse engg techniques to generate the JSF based UI.
I have a List of Employees which are showing in the default JSF generated page with proper pagination.
if the no of employees is very hing in DB, and If I want to load in to ehCache / hibernate 2nd level cache during application start up - then how Can I able to do that ?
ehCache provides cache warm up interface to load the data into cache before cache is available to the Application?
How Can i achieve this ?
Spring Roo generates (almost) simple Spring + Hibernate application. So, you just must follow the hibernate documentation to configure 2nd level cache. Roo will not disturb on any Hibernate annotation in your classes or changes in the persistence.xml file.
Here you will find a tutorial about it. Sure there are tons of information about it.
Good luck!

Transitioning to Spring Data

We are currently using Spring 3.2.3 + JPA (Hibernate). We use aspects for transaction support as opposed to annotations. We write out own entity services (read: repositories) to abstract the persistence away from our application.
I've read a lot about Spring Data and feel it would make our code considerably cleaner and more robust. I wonder though, are there any gotchas that I should consider before transitioning?
Thanks
If you're already on JPA the transition should be as easy as it can be: activate the repositories, point the infrastructure to your EntityManagerFactoryBean and off you go.
Transactions should just work fine as well. The annotation based usage within Spring Data is selectively activated for the repository beans only. They are configured to take part in existing transactions by default, so any custom larger scoped transaction setting should be in effect already.

Which is best Spring Cache Abstraction or Hibernate EHCache?

I am planning to implement the Cache in the web application.
I have already used the Hibernate EHCache in one of my previous web application.
Now a days, recently i came to know that in latest Spring release there is Cache Abstraction layer.
Hence i would like to is it just wrapper of Hibernate EHCache or it is Cache features provided by Spring itself.
If different then would like to know which is best or better option to use Cache ?
Also, i came to know from few articles that Hibernate EHCache not supporting clustering, is it ? Because clustering required for big Web Application.
I have used Spring 3.1 and Hibernate 3.3 in Web Application.
Hibernate and EHCache are different things.
EHCache is the cache provider, i.e. the actual implementation of the cache.
Hibernate can use multiple different providers for the L2 cache, including EHCache.
Spring Cache is a framework for caching method calls. It can use multiple different providers, including EHCache.
EHCache offers distribution (clustering) in several modes, from basic JMS-driven synchronization to Terracotta BigMemory distribution. Hibernate L2 cache should support clustering.
Spring Cache has nothing to do with Hibernate, but you can use Hibernate L2 cache and Spring Cache (method caching) in parallel with EHCache as the underlying provider for both.
Just to add, for database-level caching using hibernate, hibernate/JPA second-level cache seems more appropriate. Because it manages data caching at entity level at the persistence context level (JPA APIs), so there are very fewer chances of inconsistency in database and cache, since hibernate manages it well.
But if we use spring cache for database caching, then we always have to ensure every method operating on database need to be annotated with appropriate cache annotation (For example, #CacheEvict for remove), so there are chances of missing annotations and causing inconsistency.
Also, spring cache can only be used on public methods, since it backed my AOP (We can use AspectJ though to solve this).
Hibernate caching continues to work with Spring using EhCache (or another caching provider). It offers a 2nd level cache for storing em.find(key) entities and relationships (#Cache annotations or XML), as well as query caching if you q.setHint("org.hibernate.cacheable",true). These are integrated and well-documented. Spring caching is not needed for this.
But Spring provides method caching which is independent of Hibernate caching, and can still use EhCache as the caching provider (sharing EhCache with Hibernate). This can be a little confusing because the EhCache configurations are overlapping, but essentially Spring Caching allows you to independently cache the results of methods that are marked as #Cacheable.
Note 1: Spring/Method caching is not integrated with Hibernate. Results cached with method caching are not recognized or maintained by Hibernate.
Note 2: Hibernate Query caching is not recommended for highly distributed systems without a good understanding of how the caching is used. It increases the risk of deadlocks due to the use of a shared entity timestamp cache that Hibernate maintains to keep track of when the cached query results should be evicted.

ibatis / mybatis caching within a restful webservice

I am using mybatis within a Jax-RS (Jersey) restful web app. So automatically, I dont have a session or state management.
Question is how can I use the caching features of mybatis ?
Caching in MyBatis is very straight forward. Per the documentation (pg 42 of the user manual http://mybatis.googlecode.com/svn/trunk/doc/en/MyBatis-3-User-Guide.pdf)
By default, there is no caching enabled, except for local session caching, which improves performance and is required to resolve circular dependencies. To enable a second level of caching, you simply need to add one line to your SQL Mapping file:
MyBatis 3 - User Guide
6 June 2011 43
<cache/>
Literally that’s it.
The common pitfalls I had while doing this:
On the mapper you add the cache element to; if you have dependent entities, make sure to explicitly flush the cache when required. Even though flushing is already done for you on insert, update, delete for the elements in the mappings you have set the cache element, sometimes you have to flush a cache due to updates/deletes/etc defined in different xml mappings.
Basically, when you're thinking about your caching, you should ask yourself, "When this entity is changed, do I want it to flush a cache for an entity in a different mapping?" If the answer is yes, use cache-ref element as opposed to just cache.
Ex from page 45 of the doc:
<cache-ref namespace=”com.someone.application.data.SomeMapper”/>

Resources