Spring + Hibernate很少@Transactional类在一个会话中?

时间:2015-11-11 19:51:10

标签: java spring hibernate spring-mvc

我有几个类注释为@Transactional

例如我有第一个类是Spring Resolver

<annotation-driven>            
        <mvc:argument-resolvers>
            <beans:bean class="TestResolver" />
        </mvc:argument-resolvers>
    </annotation-driven>

@Transactional
public class TestResolver implements HandlerMethodArgumentResolver {
            @SuppressWarnings("unchecked")
            public Object resolveArgument(MethodParameter parameter,
                    ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
                    WebDataBinderFactory binderFactory) throws Exception {

                    return testDao.load(Test.class, 1L)

            }    
         }

我的控制器类也注明了 @Transactional

@Controller
@Transactional
@RequestMapping(value = "go")
public class TestController {


    @RequestMapping...
     public Test get() {
         return testDao.load(Test.class, 1);        
     }
}

问题是每次访问testDao.load(Test.class,1)时,hibernate都会向数据库发出查询,并且不会从控制器的缓存中提取Test.class id = 1。

为什么它不使用缓存?这两个调用按单个请求发生,但似乎在不同的会话中。

如果我在控制器中

testDao.load(Test.class, 1);
testDao.load(Test.class, 1);

它第二次使用缓存,但是当两个不同的组件执行它们代码时却没有。

2 个答案:

答案 0 :(得分:0)

我想我需要做

类OpenSessionInViewFilter

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.html

但以前从未使用它,但它应该允许保持会话整个请求

答案 1 :(得分:0)

对整个类的@Transactional注释在这里有点不幸(这并不是说一般来说这是一个坏主意,只是很难以这种方式理解这个问题),把它放在方法上就可以了更明显的是这里发生了什么 - 调用的每个方法都在一个单独的事务中被调用(除非实际调用第二个,但我的理解是它们被顺序调用)。

Hibernate可能确定它不应该在两个事务中使用缓存。