Spring Data Redis - JRedis Hello World Example

In this tutorial, we will show you an example how to integrate and use redis data store (which is a NoSQL  Key Value data store) with Spring Data. At the end of this Hello World example, you will be able to write CRUD operations with Spring data Redis based applications.

Redis is an open source, advanced key-value data store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. Spring Data for Redis is part of the umbrella Spring Data project which provides support for writing Redis applications. This example uses a JRedisa specification and reference implementation of Redis


Following libraries and tools will be required in order to run this example.
  • Download and Install Redis DB
  • spring-data-redis-1.0.1.RELEASE
  • commons-logging-1.1.1.jar
  • commons-pool-1.4.jar
  • jackson-core-asl-1.9.0.jar
  • jackson-mapper-asl-1.9.0.jar
  • jedis-2.1.0.jar
  • org.springframework.asm-3.1.1.RELEASE.jar
  • org.springframework.beans-3.1.1.RELEASE.jar
  • org.springframework.context-3.1.1.RELEASE.jar
  • org.springframework.core-3.1.1.RELEASE.jar
  • org.springframework.expression-3.1.1.RELEASE.jar
  • spring-tx-3.1.1.RELEASE.jar

Spring Configuration File (Must be in classpath)
  
Let's create spring configuration file which configures beans JRedis connection factory, RedisTemplate and Repository classes.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

 <bean id="connectionFactory"
  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
  p:host-name="localhost" p:port="6379" p:password="" />

 <!-- redis template -->
 <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
  p:connection-factory-ref="connectionFactory" />
  
 <bean id="userRepository" class="com.mycompany.redis.repository.UserRepository">
  <property name="redisTemplate" ref="redisTemplate"/>
 </bean>

</beans>



DomainObject.java 

Let's create an interfact DomainObject.java which will be implemented by all domain classes. 

package com.mycompany.redis.domain;

import java.io.Serializable;

public interface DomainObject extends Serializable {

 String getKey();

 String getObjectKey();
}


User.java

Let's create a domain object User.java which represents an user entity. This class implements DomainObject interface.

package com.mycompany.redis.domain;

public class User implements DomainObject {

 public static final String OBJECT_KEY = "USER";

 public User() {
 }

 public User(String id, String name){
  this.id = id;
  this.name = name;
 }
 private String id;
 private String name;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 @Override
 public String toString() {
  return "User [id=" + id + ", name=" + name + "]";
 }

 @Override
 public String getKey() {
  return getId();
 }

 @Override
 public String getObjectKey() {
  return OBJECT_KEY;
 }
}

Repository.java

Let's create an abstract Repository which can be implemented by specific respositories.
package com.mycompany.redis.repository;

import java.util.List;

import com.mycompany.redis.domain.DomainObject;

public interface Repository<V extends DomainObject> {

 void put(V obj);

 V get(V key);

 void delete(V key);
 
 List<V> getObjects();
}


UserRepository.java

Let's create a UserRepository.java which will provide CRUD APIs to be performed on user object.
package com.mycompany.redis.repository;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import com.mycompany.redis.domain.DomainObject;
import com.mycompany.redis.domain.User;

public class UserRepository implements Repository<User>{

 @Autowired
 private RedisTemplate<String,User> redisTemplate;
 
 public RedisTemplate<String,User> getRedisTemplate() {
  return redisTemplate;
 }

 public void setRedisTemplate(RedisTemplate<String,User> redisTemplate) {
  this.redisTemplate = redisTemplate;
 }

 @Override
 public void put(User user) {
  redisTemplate.opsForHash()
    .put(user.getObjectKey(), user.getKey(), user);
 }

 @Override
 public void delete(User key) {
  redisTemplate.opsForHash().delete(key.getObjectKey(), key.getKey());
 }

 @Override
 public User get(User key) {
  return (User) redisTemplate.opsForHash().get(key.getObjectKey(),
    key.getKey());
 }

 @Override
 public List<User> getObjects() {
  List<User> users = new ArrayList<User>();
  for (Object user : redisTemplate.opsForHash().values(User.OBJECT_KEY) ){
   users.add((User) user);
  }
  return users;
 }
}

Running The Example

Now we are set to run this Spring Data Redis example. Let's run it by following code.


package com.mycompany.redis;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mycompany.redis.domain.User;
import com.mycompany.redis.repository.UserRepository;

public class HelloWorld {

 public static void main(String[] args) {
  ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
  UserRepository userRepository = (UserRepository) applicationContext.getBean("userRepository");
  User user1 = new User("1", "user 1");
  User user2 = new User("2","user 2");
  userRepository.put(user1);
  System.out.println(" Step 1 output : " + userRepository.getObjects());
  userRepository.put(user2);
  System.out.println(" Step 2 output : " + userRepository.getObjects());
  userRepository.delete(user1);
  System.out.println(" Step 3 output : " + userRepository.getObjects());
 }
}


And here you go, following is the console output.

Step 1 output : [User [id=1, name=user 1]]
 Step 2 output : [User [id=1, name=user 1], User [id=2, name=user 2]]
 Step 3 output : [User [id=2, name=user 2]]
}
Similarly you can create other domain objects and repositories of the same!!!

7 comments:

  1. Thanks for the post.

    Implemented the same but getting NullPointerException while loading redisTemplate.

    @Autowired
    RedisTemplate redisTemplate;

    Exception in thread "main" java.lang.NullPointerException
    at com.mycompany.redis.repository.UserRepository.put(UserRepository.java:17)
    at com.mycompany.redis.HelloWorld.main(HelloWorld.java:17)

    Any help?

    ReplyDelete
    Replies
    1. Hi,
      Thank you for pointing out this problem. userRepository bean didn't have redisTemplate property in spring configuration file. Also HelloWorld didnt seem to be the updated one. Please update all source files (including spring config file) and that should work. Please let me know in case you run into any issue.

      Regards
      Vijay

      Delete
  2. Thanks for a great article, but i have a question : Does redis manage data store through cache,muitlple cache ? like memcached or ehcache? I have read some articles, but nobody mentioned this concern.

    ReplyDelete
  3. thanks dear friend

    really helpful blog :-)

    ReplyDelete
  4. Hi, I've ran this example but all I'm getting is this:

    Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is org.springframework.core.NestedIOException: Failed to deserialize object type; nested exception is java.lang.ClassNotFoundException: com.mycompany.redis.domain.User

    ReplyDelete
  5. Exception in thread "main" java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.patronpath.cache.entity.Order
    at com.patronpath.cache.service.OrderRepository.getObjects(OrderRepository.java:43)
    at com.patronpath.cache.test.OrderCacheTest.main(OrderCacheTest.java:17)

    ReplyDelete
  6. how to work with redisTemplate

    like i am able to do with add order, removeOrder

    but, i what to know based on Customer Id,

    like add Orders1,2,3 to Customer 1
    add Orders 4 to Customer 2
    delete Order 2 from customer 1

    findOrder based on Customer Id

    ReplyDelete