Hibernate实体存储为HttpSession属性值 [英] Hibernate entities stored as HttpSession attribute values

查看:130
本文介绍了Hibernate实体存储为HttpSession属性值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个带有大量相当混乱的代码库的遗留Java应用程序。有一个相当标准的'User'对象在请求之间存储在HttpSession中,所以servlet在顶部做这样的事情:

I'm dealing with a legacy Java application with a large, fairly messy codebase. There's a fairly standard 'User' object that gets stored in the HttpSession between requests, so the servlets do stuff like this at the top:

HttpSession session = request.getSession(true);
User user = (User)session.getAttribute("User");

旧的用户身份验证层(我不会描述;足以说明,它没有使用数据库)正被替换为使用Hibernate映射到数据库的代码。所以'User'现在是一个Hibernate实体。

The old user authentication layer (which I won't describe; suffice to say, it did not use a database) is being replaced with code mapped to the DB with Hibernate. So 'User' is now a Hibernate entity.

我对Hibernate对象生命周期的理解有点模糊,但似乎在HttpSession中存储'User'现在变成了一个问题,因为它将在下一个请求期间在另一个事务中检索。在这里做什么是正确的?我可以使用Hibernate Session对象的update()方法在下次重新附加User实例吗?我需要吗?

My understanding of Hibernate object life cycles is a little fuzzy, but it seems like storing 'User' in the HttpSession now becomes a problem, because it will be retrieved in a different transaction during the next request. What is the right thing to be doing here? Can I just use the Hibernate Session object's update() method to reattach the User instance the next time around? Do I need to?

推荐答案

假设您正在为每个请求 - 响应周期创建一个新的hibernate会话,则可以将一个分离的对象合并到新的hibernate会话中,但我会完全避免这种方法。

Assuming that you are creating a new hibernate session for each request-response cycle, it is possible to merge a detached object into the new hibernate session, but I would avoid this approach altogether.

而是尝试在HttpSession上存储一个可用于查找用户的密钥通过hibernate为每个传入的请求。如果您担心访问数据库以检索可以存储在HttpSession中的内容的性能影响,请不要担心 - 您可以始终使用hibernate支持的缓存框架来减少数据库访问次数。另一种提高性能的方法是使用乐观锁定。

Instead try storing a key on the HttpSession that can be used to look up a User through hibernate for every incoming request. If you are worried about the performance consequences of visiting the database to retrieve something that can be stored in the HttpSession instead, fear not - you can always use a caching framework supported by hibernate to reduce the number of database visits. Another way to improve performance would be to use optimistic locking.

虽然我没有看过hibernate源代码,但我认为hibernate使用了Identity Map模式。这是一个Map,它使用实体的id作为Map中的键,并将关联的实体对象用作Map中的值。每当从hibernate会话中检索实体时,hibernate将查看会话的身份映射以查看它是否存在。如果它在那里它将从地图返回实体。如果不存在,它将从数据库中检索实体并将其放在地图上,然后返回实体。这意味着,对于给定的休眠会话,使用相同密钥(即id,userId等)访问给定User的连续查询将接收对同一User对象的引用,因此每个查询将能够看到对另一个查询的User对象。因此,为每个传入请求创建一个新的hibernate会话是绝对必要的,这样对给定用户的并发请求就不必将其各自的线程锁定在它们的公共User对象上。不同的hibernate会话将各自拥有自己的身份映射,因此不会返回对同一User对象的引用。

Although I have not looked at the hibernate sources, I think hibernate uses the "Identity Map" pattern. This is a Map that uses the entity's id as a key in the Map and the associated entity object as a value in the Map. Whenever an entity is retrieved from the hibernate session, hibernate will look at session's identity map to see if it is there. If it is there it will return the entity from the map. If it is not there it will retrieve the entity from the database and put it on the map, and then return the entity. This means that consecutive queries that access a given User with the same key (ie id, userId etc) for a given hibernate session will receive a reference to the same User object, and therefore each query will be able to "see" modifications made to the User object by the other query. For this reason it is absolutely imperative to create a new hibernate session for each incoming request, so that concurrent requests for a given User do not have to lock their respective threads on their common User object. Different hibernate sessions will each have their own identity map and therefore will not return references to the same User object.

尝试将HttpSession中的User对象合并到您的hibernate中会话你基本上是试图直接操纵hibernate的IdentityMap,取代任何休眠认为应该与其他东西存在,并且可以理解这可能会导致问题。正如我所说虽然可以将一个分离的对象附加回一个休眠会话,但我会避免它。祝你采取任何方法都好运。

By attempting to merge a User object from the HttpSession into your hibernate session you are basically trying to manipulate hibernate's IdentityMap directly, replacing whatever hibernate "thinks" ought to be there with something else, and understandably this can cause problems. As I said although it is possible to attach a detached object back into a hibernate session I would avoid it. Good luck with whatever approach you take.

我强烈建议您阅读以下内容,特别是关于长谈话和分离对象的部分:

I would highly recommend reading the following, in your case particularly the sections on long conversations and detached objects:

http:/ /docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html

这篇关于Hibernate实体存储为HttpSession属性值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆