问题代码:

    @Override
    @CachePut(value = "books",key = "#book.id")
    public Boolean update(Book book) {
        bookDao.updateById(book);
        return bookDao.updateById(book)>0;
    }
    
    @Override
    @Cacheable(value = "books" ,key = "#id")
    public  Book getById(Integer id) {
        Book book= bookDao.selectById(id);
        return  book;
    }

    @Override
    @CacheEvict(value="books",key="#id")
    public Boolean delete(Integer id) {
        return bookDao.deleteById(id)>0;
    }

报错信息:

DBC Connection [com.mysql.cj.jdbc.ConnectionImpl@32958439] will not be managed by Spring
==>  Preparing: UPDATE book SET name=?, type=?, description=? WHERE id=?
==> Parameters: test12(String), test12(String), testtesttesttest12..(String), 44(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6f794706]
java.lang.ClassCastException: class java.lang.Boolean cannot be cast to class com.zd.domain.Book (java.lang.Boolean is in module java.base of loader 'bootstrap'; com.zd.domain.Book is in unnamed module of loader 'app')
	at com.zd.service.impl.BookNoMPServiceImpl$$EnhancerBySpringCGLIB$$f375a421.getById(<generated>)
	at com.zd.controller.BookController.getById(BookController.java:36)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)

分析过程:为类型转化异常,如果不使用修改方法,从Redis缓存取是没有问题的,那么问题出现在修改方法存缓存的过程中。我查看使用修改方法前后Redis缓存存储的对象值,完全不一样。

后又查看下别人写的方法,试着修改如下,就可以了:

 /**
     * 要注意的是@Cacheable注解和@CachePut注解两个方法的返回类型要一致,@CachePut才能生效
     * 也是折磨了很久
     * @param book
     * @return
     */
    @Override
    @CachePut(value = "books",key = "#book.id")
    public Book update(Book book) {
        bookDao.updateById(book);
        return book;
    }

    @Override
    @Cacheable(value = "books" ,key = "#id")
    public  Book getById(Integer id) {
        Book book= bookDao.selectById(id);
        return  book;
    }
@Cacheable注解和@CachePut注解两个方法的返回类型要一致,@CachePut才能生效

@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中,当调用update方法时,该方法体会被执行,并且执行的结果会返回写入到缓存中,所以返回类型必须要一致

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐