Configuring L2 Caching

First, we need to modify our Spring boot project dependency to add Apache Ignite support. Edit the build.gradle and add the following dependencies:

 compile group: 'org.apache.ignite', name: 'ignite-core', version: '2.5.2'
compile group: 'org.apache.ignite', name: 'ignite-spring', version: '2.5.2'
compile group: 'org.apache.ignite', name: 'ignite-indexing', version: '2.5.2'
compile group: 'org.apache.ignite', name: 'ignite-hibernate_5.1', version: '2.5.2'
compile group: 'com.h2database', name: 'h2', version: '1.4.195'

The ignite-hibernate_5.1 is required for L2 caching, but this jar is not available in Maven central due to a licensing issue. We need to add the gridgain Maven repo in our build.gradle to bring this jar. Modify the repositories section in your build.gradle and add the following highlighted lines:

repositories {
maven{
url "http://www.gridgainsystems.com/nexus/content/repositories/external/"
}
mavenCentral()
}

The ignite-hibernate_5.1 supports hibernate 5.1, but Spring boot brings in hibernate 5.2 jars, so we need to instruct Gradle to only consider hibernate 5.1 jars. Add the following hibernate dependencies:

//Ignite 2.5 supports hibernate 5.1, but spring boot brings in 5.2 dependencies
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.1.0.Final'
compile group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.1.0.Final'
compile group: 'org.hibernate', name: 'hibernate-validator', version: '5.1.0.Final'
compile group: 'org.hibernate.common', name: 'hibernate-commons-annotations', version: '5.0.4.Final'

Hibernate properties need to be set to enable the query and L2 cache. Spring boot's way of setting properties is to define them in application.peroperties. Add the following properties to application.properties under the resources folder:

spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.apache.ignite.cache.hibernate.HibernateRegionFactory

The second_level_cache=true enables the 2nd level cache, the use_query_cache=true enables the query cache, and finally the region.factory_class=org.apache.ignite.cache.hibernate.HibernateRegionFactory sets Ignite's implementation as the hibernate region factory. You need to tell ignite about the access type and the name of the ignite instance where the hibernate objects will be stored:

 spring.jpa.properties.org.apache.ignite.hibernate.default_access_type=READ_ONLY
spring.jpa.properties.org.apache.ignite.hibernate.ignite_instance_name=MyGrid121

Before running the application, we need to start the Ignite instance MyGrid121. Modify the DatagridApplication and add the following lines to start the ignite node and also configure the caches where the objects will be stored.

The name of each cache should be the fully qualified class name, such as com.datagrid.entity.Club:

@SpringBootApplication
public class DatagridApplication {

public static void main(String[] args) {
//Start the ignite node MyGrid121
try {
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setIgniteInstanceName("MyGrid121");
Ignite ignite = Ignition.start(cfg);

ignite.getOrCreateCache("org.hibernate.cache.spi.UpdateTimestampsCache");
ignite.getOrCreateCache("org.hibernate.cache.internal.StandardQueryCache");

CacheConfiguration<Integer, Club> clubConfig = new
CacheConfiguration<>();
clubConfig.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
clubConfig.setIndexedTypes(Integer.class, Club.class);
clubConfig.setName("com.datagrid.entity.Club");
ignite.getOrCreateCache(clubConfig);

CacheConfiguration<Integer, Player> playerConfig = new
CacheConfiguration<>();
playerConfig.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
playerConfig.setIndexedTypes(Integer.class, Player.class);
playerConfig.setName("com.datagrid.entity.Player");
ignite.getOrCreateCache(playerConfig);
} catch (Exception e) {
}

SpringApplication.run(DatagridApplication.class, args);
}
}

The clubConfig and playerConfig are the used to define the cache configuration. An Ignite cache can store a key-value pair. CacheConfiguration<Integer, Club> clubConfig defines a cache configuration for an integer key and a Club object value. Default the cache atomicity mode is atomic but to make it transactional (ACID compliant), we need to pass the atomicity mode. Index types are used to create faster object queries. Finally, the cache is created using the getOrCreateCache method of ignite.

We also need to annotate the entity class (both Player and Club) with two annotations:

  • @Cacheable: Enables hibernate caching.
  • @Cache: Defines the concurrency strategy; available options are READREAD_WRITE, and TRANSACTIONAL. Ignite's CacheConfiguration atomicity must be transactional to set the concurrency mode—READ_WRITE, a trasaction manager needs to be defined to set the concurrency mode TRANSACTIONAL. 

The Player class will be changed as follows:

@Entity
@Table(name = "player")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Player {

Now, start the spring boot application and hit the REST endpoint to fetch a player's details. It will make a database query to fetch them. Check that it took 329 milliseconds to fetch the data from the database:

The Eclipse console will show the query:

Now, hit the same endpoint again; it will take less time: 26 ms is taken to return the object from the cache. You can compare the times: 329 ms to 26 ms. You can verify that in the Eclipse console, you wont find any SQL trace:

That's the beauty of L2 caching with Apache Ignite. You can use Apache Ignite as a hibernate L2 cache store and improve the performance of your application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.146.176.88