问题描述
我们目前正在开发一个使用JPA作为数据访问层的J2EE Web应用程序。我们目前正在采用几种不同的策略来在应用程序中使用缓存。
EntityManager 每个请求-
在请求范围内获取缓存,但在请求结束时丢失缓存
-
使得从整个请求中回滚任何更改变得容易
为每个Http Session创建一个 EntityManager 实例,该实例(至少在spring中)绑定到 ThreadLocal (=本例中的请求)
更新:功能,然后使用cglib / javassist / JDK代理并将其注入放置 @PersistenceContext 的地方。请求=线程。在每个需要数据访问的请求上,创建一个新的 EntityManager 并将其存储在 ThreadLocal 中。请记住最后清理它,因为servlet容器会重用线程。从代理中你可以获得当前的 ThreadLocal 值。
但是如果你不在项目中,那么我会建议转向更稳定的东西,比如spring,cdi或者guice。
We're currently developing a J2EE web app using JPA as our data access layer. We're currently entertaining a couple different strategies to utilizing caching within our applications.
- Create an EntityManager per request
- Get caching within the request scope, but lose the cache at the end of the request
- Makes it easy to rollback any changes from an entire request
- Create an EntityManager per Http Session
- Get caching within the session scope
- Makes things more complicated with transactions, would have to create a new transaction per request, then would be able to rollback changes per request
I've seen both strategies in the Hibernate documentation. My question is which is more widely used and if we do the EntityManager per session, will we run into synchronization issues by using the same EntityManager across different request threads?
The more widely used approach is to create an EntityManager per request. However this should remain hidden from you. You should use some dependency-injection mechanism (spring/CDI/EJB) that will inject the proper EntityManager where @PersistenceContext is placed.
If you are interested how this is achieved in the common case where your beans are some sort singletons (one stateless bean / one spring bean of scope singleton) - the container actually injects a proxy in the target object. And each time the proxy is consulted, it gets the current EntityManager instance, which is (in the case of spring at least) bound to a ThreadLocal (= request in this case)
Update: If you want to implement this functionality in a home-grown framework, then use cglib / javassist / JDK proxy and inject it where @PersistenceContext is placed. A request = thread. On each request that needs data access, create a new EntityManager and store it in a ThreadLocal. Remember to clean it in the end because servlet containers reuse threads. From the proxy you can obtain the current ThreadLocal value.
But in case you are not far into the project, then I'd suggest moving to something more stable, like spring, cdi or guice.
这篇关于JPA Web应用程序管理策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!