我可以使用 Grails 会话来存储整个域对象吗?

Can I use the Grails session to store entire domain objects?

如果我有一些我不想保存的 Grails 域对象,但仍然在我的应用程序中访问它们,将它们存储在 Grails/Hibernate 会话中是否明智(尤其是关于性能) ?如果不能,还有什么选择?

grails/hibernate 会话是什么意思?

如果您真的是指 Hibernate 会话,向其中添加一个对象将导致在刷新会话时自动保存该对象(除非该对象未通过验证,在这种情况下,一旦会话结束,该对象就会丢失)被丢弃)。根据请求创建和丢弃会话。

如果您指的是自动注入控制器和视图的 session 对象,那么它既不是 Hibernate 特定的也不是 grails,而是来自 Servlet 规范的旧的、普通的 HttpSession(参见 http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html) .

如果您需要跨同一客户端的多个请求访问它们,您可以使用它来存储任何类型的对象。这意味着会话对于给定的客户端(通过 jsessionid cookie 识别它)是私有的,并且在多个请求中存活。如果您不需要多个请求位,将它们添加为请求属性就足够了。

将东西放在会话中通常又好又快(因为默认情况下是基于内存的),但如果滥用会增加应用程序的内存占用,并且会阻止水平缩放(即在中部署相同的应用程序)多个实例),除非使用粘性会话机制(或会话持久化)。

请记住,虽然 grails 每个请求都使用一个新的 Hibernate 会话(而不是 Http 会话 :),因此如果您将附加到 Hibernate 会话的对象添加到 Http 会话,然后 Hibernate 会话将关闭,您可能会遇到问题。这不应该影响未保存的对象(它们不是来自 Hibernate 会话),但它可能会影响它们的关联(其他域 类 来自数据库,因此是 Hibernate 会话)。如果是这种情况,您可能需要重新连接它们。参见 https://grails.github.io/grails-doc/latest/ref/Domain%20Classes/attach.html

此外,如果会话无效(因为用户注销,或服务器重新部署),存储在其中的所有内容都将消失。

如果您根本不想依赖会话,您可以创建自己的 MemoryBasedStoreService 服务并使用 ConcurrentHashMap 或类似机制来存储和检索对象。由于服务在 Grails 中是单例的,因此您可以在整个应用程序中使用它,而不管请求或客户端 - 只要您的应用程序当然部署在单个实例中 :).