spring boot整合redis:http://www.cnblogs.com/sxdcgaq8080/p/8028970.html

首先,明确一下问题的场景

之前在spring boot整合redis,关于redis的使用都是在repository层上再封装一层service层,在service层上使用的。

现在如果直接将redis的注解放在repository上使用,是个什么情况呢?

代码如下:

  1.首先我有一个实体XxAdmin,主键为id

  2.Xxadmin我写了一个AdminRepository

  1. package com.agen.myagen.repository;
  2.  
  3. import com.agen.myagen.entity.XxAdmin;
  4. import org.springframework.cache.annotation.Cacheable;
  5. import org.springframework.data.jpa.repository.JpaRepository;
  6.  
  7. /**
  8. * admin持久化层
  9. *
  10. * @author SXD
  11. * @date 2017/12/26
  12. */
  13. public interface AdminRepository extends JpaRepository<XxAdmin,Integer> {
  14.  
  15. /**
  16. * 查找机构信息
  17. * 并缓存到redis,键为id 值为XxAdmin
  18. * @param adminId
  19. * @return
  20. */
  21. @Cacheable(value="admins", key="#adminId")
  22. @Override
  23. XxAdmin findOne(Integer adminId);
  24. }

  3.我在controller直接调用

  1. package com.agen.controller;
  2.  
  3. import com.agen.myagen.entity.XxAdmin;
  4. import com.agen.myagen.repository.AdminRepository;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7.  
  8. import javax.annotation.Resource;
  9.  
  10. @Controller
  11. public class MainController {
  12.  
  13. @Resource
  14. private AdminRepository adminRepository;
  15.  
  16. @RequestMapping("index")
  17. public String getOrder(String adminId){
  18. Integer adminID = Integer.parseInt(adminId);
  19. XxAdmin admin = adminRepository.findOne(adminID);
  20. return null;
  21. }
  22.  
  23. }

【报错】 

启动之后,报错如下:Null key returned for cache operation (maybe you are using named params on classes without debug info?)

  1. java.lang.IllegalArgumentException: Null key returned for cache operation (maybe you are using named params on classes without debug info?) Builder[public abstract com.agen.myagen.entity.XxAdmin com.agen.myagen.repository.AdminRepository.findOne(java.lang.Integer)] caches=[admins] | key='#adminId' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false'

报这个错,原因就是redis认定这个key是Null的,没办法存入,所以报错了。

但是之前咱们上一篇就是这么用的呀,查看上一篇,可以发现,redis是使用在service层,是在repository的再封装层使用的,那redis就不能直接使用在repository层了么?

【这里因为项目原因,不赘述为什么不封装一层service层使用,而是直接在repository层使用】【最后具体为什么key在这里会认定为null也没有找到原因,若知情,恳请告知!!!谢谢了】

【解决方法】

翻来覆去之后,发现redis的@Cacheable注解放在repository方法上,key会被认定为null,导致存不进redis缓存。

所以,换一种思路来解决这个问题,就是提前设定一种key的生成策略,即在RedisConfig类中指定一种KeyGenerator。【这一步骤的解释,可以查看http://www.cnblogs.com/sxdcgaq8080/p/8028970.html

具体的解决方法如下:

  在RedisConfig中,设定仅取第一个参数作为key的key生成策略

  1. /**
  2. * 生成key的策略【自定义第三种】
  3. * 使用范围:仅适用于选取第一个参数做键的情况
  4. * 由于reposotory上不能直接使用spel表达式作key,故而采用key的生成策略的方式来替换
  5. *
  6. * 使用时在注解@Cacheable(value = "admins",keyGenerator = "firstParamKeyGenerator")中指定
  7. * @return
  8. */
  9. @Bean(name = "firstParamKeyGenerator")
  10. public KeyGenerator firstParamKeyGenerator(){
  11. return new KeyGenerator() {
  12. @Override
  13. public Object generate(Object target, Method method, Object... params) {
  14. StringBuilder sb = new StringBuilder();
  15. sb.append(params[0].toString());
  16. return sb.toString();
  17. }
  18. };
  19. }

然后在AdminRepository中更换@Cacheable中的属性

  1. public interface AdminRepository extends JpaRepository<XxAdmin,Integer> {
  2.  
  3. /**
  4. * 查找机构信息
  5. * 并缓存到redis,键为id 值为XxAdmin
  6. * @param adminId
  7. * @return
  8. */
  9. @Cacheable(value="admins", keyGenerator = "firstParamKeyGenerator")
  10. @Override
  11. XxAdmin findOne(Integer adminId);
  12. }

然后再去访问一次,

控制台成功从数据库查询了Xxadmin对象

查看redis中,已经将本对象存入缓存

再次访问,发现并未执行SQL语句,直接从缓存中取出本对象。

OK,直接在spring boot的repository层使用redis注解成功。

==============================================================================================================================================

最后,可以将AdminRepository类上使用

  1. @CacheConfig(cacheNames = "admins")

指定本类中所有的方法,操作的缓存都是名为admins的缓存!!

  1. package com.agen.myagen.repository;
  2.  
  3. import com.agen.myagen.entity.XxAdmin;
  4. import org.springframework.cache.annotation.CacheConfig;
  5. import org.springframework.cache.annotation.Cacheable;
  6. import org.springframework.data.jpa.repository.JpaRepository;
  7.  
  8. /**
  9. * admin持久化层
  10. *
  11. * @author SXD
  12. * @date 2017/12/26
  13. */
  14. @CacheConfig(cacheNames = "admins")
  15. public interface AdminRepository extends JpaRepository<XxAdmin,Integer> {
  16.  
  17. /**
  18. * 查找机构信息
  19. * 并缓存到redis,键为id 值为XxAdmin
  20. * @param adminId
  21. * @return
  22. */
  23. @Cacheable(keyGenerator = "firstParamKeyGenerator")
  24. @Override
  25. XxAdmin findOne(Integer adminId);
  26. }

具体可以参考:http://www.cnblogs.com/sxdcgaq8080/p/7228163.html查看这几个注解的使用场景

==============================================================================================================================================

本系列的源代码,可以从GitHub上获取查看:https://github.com/AngelSXD/myagenorderdiscount,类名及方法名都是对应的。所以想查看这部分使用的,可以直接在项目中查看即可!!

【redis】5.spring boot项目中,直接在spring data jpa的Repository层使用redis +redis注解@Cacheable直接在Repository层使用,报错问题处理Null key returned for cache operation的更多相关文章

  1. Spring Boot项目中使用Mockito

    本文首发于个人网站:Spring Boot项目中使用Mockito Spring Boot可以和大部分流行的测试框架协同工作:通过Spring JUnit创建单元测试:生成测试数据初始化数据库用于测试 ...

  2. 在Spring Boot项目中使用Spock测试框架

    本文首发于个人网站:在Spring Boot项目中使用Spock测试框架 Spock框架是基于Groovy语言的测试框架,Groovy与Java具备良好的互操作性,因此可以在Spring Boot项目 ...

  3. Spring Boot项目中如何定制拦截器

    本文首发于个人网站:Spring Boot项目中如何定制拦截器 Servlet 过滤器属于Servlet API,和Spring关系不大.除了使用过滤器包装web请求,Spring MVC还提供Han ...

  4. Spring Boot项目中如何定制PropertyEditors

    本文首发于个人网站:Spring Boot项目中如何定制PropertyEditors 在Spring Boot: 定制HTTP消息转换器一文中我们学习了如何配置消息转换器用于HTTP请求和响应数据, ...

  5. Spring Boot项目中如何定制servlet-filters

    本文首发于个人网站:Spring Boot项目中如何定制servlet-filters 在实际的web应用程序中,经常需要在请求(request)外面增加包装用于:记录调用日志.排除有XSS威胁的字符 ...

  6. 你真的理解 Spring Boot 项目中的 parent 吗?

    前面和大伙聊了 Spring Boot 项目的三种创建方式,这三种创建方式,无论是哪一种,创建成功后,pom.xml 坐标文件中都有如下一段引用: <parent> <groupId ...

  7. Spring Boot项目中使用Swagger2

    Swagger2是一款restful接口文档在线生成和在线接口调试工具,Swagger2在Swagger1.x版本的基础上做了些改进,下面是在一个Spring Boot项目中引入Swagger2的简要 ...

  8. 在Spring Boot项目中使用Spock框架

    转载:https://www.jianshu.com/p/f1e354d382cd Spock框架是基于Groovy语言的测试框架,Groovy与Java具备良好的互操作性,因此可以在Spring B ...

  9. Spring Boot2 系列教程(三)理解 Spring Boot 项目中的 parent

    前面和大伙聊了 Spring Boot 项目的三种创建方式,这三种创建方式,无论是哪一种,创建成功后,pom.xml 坐标文件中都有如下一段引用: <parent> <groupId ...

随机推荐

  1. HBase0.94.2-cdh4.2.0需求评估测试报告1.0之五

    根据以上图分析得出以下结论: 1. 在上面的hbase配置下,顺序和随机写记录(每条记录1K),每写入86-87M(大小可配)左右数据生成一个磁盘文件(store file). 2. 在上面的hbas ...

  2. JAVA-基础(三)

    Character 类型字符(Character)是围绕字符型(char)的一个简单的包装器.字符(Character)的构造函数如下:Character(char ch)这里ch指定了被创建的字符( ...

  3. Jquery+Ajax+asp.net+sqlserver-编写的通用邮件管理(源码)

    开始 邮件管理通常用在各个内部系统中,为了方便快捷的使用现有的代码开发一个邮件管理系统而诞生的. 准备条件 这是我的设计表结构,大家一看就懂了   --邮件接收表CREATE TABLE [dbo]. ...

  4. 使用 Button 类在 XNA 中创建图形按钮(九)

    平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...

  5. Selenium WebDriver- 操作JavaScript的prompt弹窗(使用率低)

    #encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...

  6. python week08 并发编程之多线程--实践部分

    一. threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.pytho ...

  7. 算法理论——Linear SVM

    问题引入 下面的三个超平面都起到分类的效果,哪个最好? 答案显然是第三个.为什么? 直觉上,如果现在我们有个测试点,非常靠近右下角的那个红叉叉,也就是说这个点的特征与那个红叉叉非常接近,这时候,我们希 ...

  8. [uiautomator篇][9]遇到问题

    1 (1) 修改apk的存储权限,不要创建文件会提示:文件找不到 (2) 退出应用 mDevice.executeShellCommand("am force-stop com.antutu ...

  9. 【bzoj1043】[HAOI2008]下落的圆盘 计算几何

    题目描述 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. 输入 第一行为1个整数n,N<=1000接下来n行每行3个实 ...

  10. Intellij IDE使用 ideavim,不能复制文档到系统粘贴板

    vim的yank命令默认不会复制到系统粘贴板,而是粘贴到寄存器.你可以使用* 或 +寄存器来访问系统粘贴板. 在~/.ideavimrc (如果不存在就创建) 中添加下列选项 set clipboar ...