I’m playing with technologies and framework for a new project: because I’m learning things probably useful for others, I’m gonna write here few notes about what I’ve learned. This is the third article of a series: now it’s time to cache!

Part 3 – Activating the cache

2015-10-09-162228In this article, I will set up a simple Infinispan configuration, enable the caching mechanism in the DAO class, develop a testing standalone application. I will modify the project used in the previous article, whose structure is shown in the figure (except the test classes are in the it.caladyon.bit.dao_test.bita)

Technologies used:

  • Java 8
  • MyBatis 3.3
  • Spring 4.2
  • Mybatis-Spring 1.2.3
  • Infinispan 7.2.5 Final

Step 1 – Project configuration

Let’s have a look at the dependencies of the pom.xml, I’ve added two infinispan libraries:

<properties>
 <spring-framework.version>4.2.1.RELEASE</spring-framework.version>
 <postgresql.group>org.postgresql</postgresql.group>
 <postgresql.artifact>postgresql</postgresql.artifact>
 <postgresql.version>9.4-1201-jdbc41</postgresql.version>
 <mybatis.version>3.3.0</mybatis.version>
 <infinispan.version>7.2.5.Final</infinispan.version>
</properties>

<dependencies>
 <dependency>
 <groupId>it.caladyon.bit</groupId>
 <artifactId>bit-lib-db</artifactId>
 <version>2.0.0-SNAPSHOT</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>${spring-framework.version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>${spring-framework.version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-jdbc</artifactId>
 <version>${spring-framework.version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis</artifactId>
 <version>${mybatis.version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis-spring</artifactId>
 <version>1.2.3</version>
 </dependency>

 <dependency>
 <groupId>org.infinispan</groupId>
 <artifactId>infinispan-embedded</artifactId>
 <version>${infinispan.version}</version>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>org.infinispan</groupId>
 <artifactId>infinispan-spring4</artifactId>
 <version>${infinispan.version}</version>
 <scope>provided</scope>
 </dependency>
</dependencies>

Step 2 – Making the DAO methods cachable

Few modifications to VbitacSegDaoImpl, to cache the selected records:

@Repository("vbitacSegDao")
public class VbitacSegDaoImpl implements VbitacSegDao, Const {

 public static final String REPOSITORY = "vbitacSegDao";

 private final Log log = LogFactory.getLog(getClass()); // TODO: togliere

 @Autowired
 private VbitacSegMapper mapper;

 @Cacheable(value = "${" + REPOSITORY + PROP_SUFFIX_CACHE_NAME + ":" + CACHE_REGISTRY + "}")
 @Override
 public Optional<VbitacSeg> findByCseg(Long cseg) {
 // ...
 }
}

Note that the cache name is taken from a properties file, so every application can modify the cache behaviour.

Step 3 – Spring configuration and test class

These are the modification I’ve made, following the JavaConfig approach.

First, I’ve created a new @Configuration class, called MybatisSpringCachedConfig, that imports MybatisSpringConfig:

@Configuration
@EnableCaching
@Import({ MybatisSpringConfig.class })
public class MybatisSpringCachedConfig {

 @Bean
 public CacheManager cacheManager() {
 SpringEmbeddedCacheManager rv = new SpringEmbeddedCacheManager(infinispanCacheManager());
 return rv;
 }

 private EmbeddedCacheManager infinispanCacheManager() {
 return new DefaultCacheManager();
 }
}

The key point is the @EnableCaching annotation: without it, the previous @Cacheable annotation has no effect whatsoever. Instead, with it, you are compelled to define a Spring cache manager (even a NoOpCacheManager), in this case Infinispan as an embedded cache.

You may customize the infinispanCacheManager() method, in order to define the application specific caches.

The test class, named TestFunc_VbitacSegDaoImpl_WithCache, has a @Configuration inner class that imports MybatisSpringCachedConfig: no other differences respect to the test class of the previous article, TestFunc_VbitacSegDaoImpl_NoCache.

public class TestFunc_VbitacSegDaoImpl_WithCache {

 @Configuration
 @Import({MybatisSpringCachedConfig.class})
 public static class SpringifyConf {

 @Bean
 public DataSource dataSource() {
 PGSimpleDataSource ds = new PGSimpleDataSource();
 // ...
 return ds;
 }

 }
 
 // ...

}

Step 4 – Running the test

Below there is the output of the application.

You can see that the query is executed once, and that the objects returned by findByCseg are the same instance actually.

INFO [TestFunc_VbitacSegDaoImpl_WithCache.execute] BEGIN
INFO [AnnotationConfigApplicationContext.prepareRefresh] Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4d591d15: startup date [Thu Nov 05 09:50:17 CET 2015]; root of context hierarchy
INFO [AutowiredAnnotationBeanPostProcessor.<init>] JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO [TestFunc_VbitacSegDaoImpl_WithCache.execute] DAO: it.caladyon.bit.dao.bita.VbitacSegDaoImpl@79d94571
INFO [GlobalComponentRegistry.start] ISPN000128: Infinispan version: Infinispan 'Insanely Bad Elf' 7.2.5.Final
DEBUG [selectByPrimaryKey.debug] ==> Preparing: select c_seg, c_pnt_ini, c_pnt_fin, n_pos, n_off_ini, n_off_fin, c_dir, c_seg_prv, c_seg_nxt, c_fnc_cls, c_spd_cat, q_var_dis_vel from bita.vbitac_seg where c_seg = ? 
DEBUG [selectByPrimaryKey.debug] ==> Parameters: 648523113755334657(Long)
DEBUG [selectByPrimaryKey.debug] <== Total: 1
INFO [TestFunc_VbitacSegDaoImpl_WithCache.execute] Result : Optional[VbitacSeg [Hash = 1424497441, cSeg=648523113755334657, cPntIni=150996054, cPntFin=150996056, nPos=1, nOffIni=2728, nOffFin=2274, cDir=true, cSegPrv=null, cSegNxt=648523113755334658, cFncCls=0, cSpdCat=4, qVarDisVel=0.2, serialVersionUID=1]]
INFO [TestFunc_VbitacSegDaoImpl_WithCache.execute] Result : Optional[VbitacSeg [Hash = 1424497441, cSeg=648523113755334657, cPntIni=150996054, cPntFin=150996056, nPos=1, nOffIni=2728, nOffFin=2274, cDir=true, cSegPrv=null, cSegNxt=648523113755334658, cFncCls=0, cSpdCat=4, qVarDisVel=0.2, serialVersionUID=1]]
INFO [TestFunc_VbitacSegDaoImpl_WithCache.execute] Result : Optional[VbitacSeg [Hash = 1424497441, cSeg=648523113755334657, cPntIni=150996054, cPntFin=150996056, nPos=1, nOffIni=2728, nOffFin=2274, cDir=true, cSegPrv=null, cSegNxt=648523113755334658, cFncCls=0, cSpdCat=4, qVarDisVel=0.2, serialVersionUID=1]]
INFO [TestFunc_VbitacSegDaoImpl_WithCache.execute] END

 

 

Annunci