title: spring boot use redis as cache, I can use keyGenerator but use key fails
body: <p>When I use redis as my spring boot project's cache ,I found that if I use @Cacheable(value = "user",keyGenerator="keyGenerator") it does work,BUT I switch to @Cacheable(value = "user",key = "#p0"), it doesn't work!! I try my best to solve the problem, but I fail... So I need you help!
  Thank you first!
  RedisConfig:</p>
  
  <pre><code>import cn.limbo.utils.HashValueRedisObjectSerializer;
  import cn.limbo.utils.SampleKeyGenerator;
  import com.fasterxml.jackson.annotation.JsonAutoDetect;
  import com.fasterxml.jackson.annotation.PropertyAccessor;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.cache.CacheManager;
  import org.springframework.cache.annotation.CachingConfigurerSupport;
  import org.springframework.cache.annotation.EnableCaching;
  import org.springframework.cache.interceptor.KeyGenerator;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.data.redis.cache.RedisCacheManager;
  import org.springframework.data.redis.connection.RedisConnectionFactory;
  import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
  import org.springframework.data.redis.core.RedisTemplate;
  import org.springframework.data.redis.core.StringRedisTemplate;
  import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
  import org.springframework.data.redis.serializer.StringRedisSerializer;
  
  /**
   * redis 配置
   * Created by limbo on 2017/4/21.
   */
  
  @Configuration
  @EnableCaching(proxyTargetClass = true)
  public class RedisConfig extends CachingConfigurerSupport {
  
      @Value("${spring.redis.host}")
      private String host;
  
      @Value("${spring.redis.port}")
      private int port ;
  
      @Value("${spring.redis.timeout}")
      private int timeout;
  
      @Bean(name = "keyGenerator")
      public KeyGenerator KeyGenerator(){
          return new SampleKeyGenerator();
      }
  
      @Bean
      public JedisConnectionFactory redisConnectionFactory(){
          JedisConnectionFactory redisConnectionFactory = new 
          JedisConnectionFactory();
          redisConnectionFactory.setHostName(host);
          redisConnectionFactory.setPort(port);
          return redisConnectionFactory;
      }
  
  
      @Bean
      public CacheManager cacheManager(RedisTemplate redisTemplate){
          RedisCacheManager cacheManager = new 
          RedisCacheManager(redisTemplate);
          return cacheManager;
      }
  
      @Bean(name = "redisTemplate")
      public RedisTemplate&lt;String,String&gt; redisTemplate(RedisConnectionFactory cf){
          StringRedisTemplate template = new StringRedisTemplate(cf);
          Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new 
          Jackson2JsonRedisSerializer(Object.class);
          ObjectMapper om = new ObjectMapper();
  
    om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
          om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
          jackson2JsonRedisSerializer.setObjectMapper(om);
  
          template.afterPropertiesSet();
          template.setValueSerializer(jackson2JsonRedisSerializer);
          template.setKeySerializer(new StringRedisSerializer());
          template.setHashKeySerializer(new StringRedisSerializer());
          template.setHashValueSerializer(new HashValueRedisObjectSerializer());
  
          return template;
      }
  
  }
  </code></pre>
  
  <p>User.java</p>
  
  <pre><code>import java.io.Serializable;
  
  /**
   * Created by limbo on 2017/4/21.
   */
  public class User implements Serializable {
  
  
      private static final long serialVersionUID = -1L;
  
      private Long id;
  
      private String name;
  
      private String description;
  
      public User() {
      }
  
      public User(Long id, String name, String description) {
          this.id = id;
          this.name = name;
          this.description = description;
      }
  
      public Long getId() {
          return id;
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public String getDescription() {
          return description;
      }
  
      public void setDescription(String description) {
          this.description = description;
      }
  
      @Override
      public String toString() {
          return "User{" +
              "id=" + id +
              ", name='" + name + '\'' +
              ", description='" + description + '\'' +
              '}';
      }
  
  }
  </code></pre>
  
  <p>UserService.java</p>
  
  <pre><code>import cn.limbo.domain.User;
  
  import java.util.List;
  
  /**
   * Created by limbo on 2017/4/21.
   */
  public interface UserService {
  
      /**
       * @param id
       * @return
       */
      User findUserById(Long id);
  
      /**
       * @return
       */
      List&lt;User&gt; findAllUser();
  
      /**
       * @param user
       * @return
       */
      Long saveUser(User user);
  
      /**
       * @param user
       * @return
       */
      Long updateUser(User user);
  
      /**
       * @param id
       * @return
       */
      Long deleteUser(Long id);
  
  }
  </code></pre>
  
  <p>UserServiceImpl.java</p>
  
  <pre><code>import cn.limbo.dao.UserDao;
  import cn.limbo.domain.User;
  import cn.limbo.service.UserService;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.cache.annotation.CacheConfig;
  import org.springframework.cache.annotation.CacheEvict;
  import org.springframework.cache.annotation.CachePut;
  import org.springframework.cache.annotation.Cacheable;
  import org.springframework.stereotype.Service;
  
  import java.util.List;
  
  /**
   * Created by limbo on 2017/4/21.
   */
  @Service
  @CacheConfig(cacheNames = {"userCache"}) //可以指定key的生成器 如：keyGenerator = "keyGenerator" 这个与key是互斥的
  public class UserServiceImpl implements UserService{
  
      private Logger logger = LoggerFactory.getLogger(this.getClass());
  
      @Autowired
      UserDao userDao;
  
      @Override
      @Cacheable(key = "#p0")
      public User findUserById(Long id) {
          return userDao.findById(id);
      }
  
      @Override
      @Cacheable
      public List&lt;User&gt; findAllUser() {
          return userDao.findAllUser();
      }
  
      @Override
      @CachePut(key = "#p0.id")
      public Long saveUser(User user) {
          return userDao.saveUser(user);
      }
  
      @Override
      @CachePut(key = "#p0.id")
      public Long updateUser(User user) {
          return userDao.updateUser(user);
      }
  
      @Override
      @CacheEvict(key = "#p0") //移除指定key的数据
      public Long deleteUser(Long id) {
          return userDao.deleteUser(id);
      }
  }
  </code></pre>
  
  <p>Error Message:</p>
  
  <pre><code>java.lang.ClassCastException: java.lang.Long cannot be cast to        java.lang.String
  
  at org.springframework.data.redis.serializer.StringRedisSerializer.serialize(StringRedisSerializer.java:33)
  at org.springframework.data.redis.cache.RedisCacheKey.serializeKeyElement(RedisCacheKey.java:74)
  at org.springframework.data.redis.cache.RedisCacheKey.getKeyBytes(RedisCacheKey.java:49)
  at org.springframework.data.redis.cache.RedisCache$1.doInRedis(RedisCache.java:176)
  at org.springframework.data.redis.cache.RedisCache$1.doInRedis(RedisCache.java:172)
  at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:207)
  at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:169)
  at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:157)
  at org.springframework.data.redis.cache.RedisCache.get(RedisCache.java:172)
  at org.springframework.data.redis.cache.RedisCache.get(RedisCache.java:133)
  at org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:71)
  at org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:537)
  at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:503)
  at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:389)
  at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
  at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
  at cn.limbo.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$817ccd4.findUserById(&lt;generated&gt;)
  at cn.limbo.ApplicationTests.test(ApplicationTests.java:25)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
  at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
  at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
  at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
  at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
  at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
  at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
  at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
  at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
  at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
  </code></pre>
  
  <p>Now I found above problem cause by using a wrong KeySerializer,BUT here come a new problem.I try to return a pojo written by myself, but IDEA give me wrong message like this:</p>
  
  <pre><code>org.springframework.data.redis.serializer.SerializationException: 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 java.io.EOFException
  
  at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:82)
  at org.springframework.data.redis.cache.RedisCache$CacheValueAccessor.deserializeIfNecessary(RedisCache.java:477)
  at org.springframework.data.redis.cache.RedisCache.lookup(RedisCache.java:323)
  at org.springframework.data.redis.cache.RedisCache.get(RedisCache.java:184)
  at org.springframework.data.redis.cache.RedisCache.get(RedisCache.java:133)
  at org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:71)
  at org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:537)
  at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:503)
  at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:389)
  at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
  at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
  at cn.limbo.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$91b4a11c.findUserById(&lt;generated&gt;)
  at cn.limbo.ApplicationTests.test(ApplicationTests.java:25)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
  at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
  at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
  at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
  at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
  at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
  at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
  at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
  at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
  at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
  Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.EOFException
  at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78)
  at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36)
  at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:80)
  ... 42 more
  Caused by: java.io.EOFException
  at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2353)
  at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2822)
  at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
  at java.io.ObjectInputStream.&lt;init&gt;(ObjectInputStream.java:301)
  at org.springframework.core.ConfigurableObjectInputStream.&lt;init&gt;(ConfigurableObjectInputStream.java:63)
  at org.springframework.core.ConfigurableObjectInputStream.&lt;init&gt;(ConfigurableObjectInputStream.java:49)
  at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:68)
  at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:73)
  ... 44 more
  </code></pre>