如果我有许多 Grails 域对象,我还不想保存,但仍然在整个应用程序中访问它们,将它们存储在 Grails/Hibernate session 中是否明智(尤其是在性能方面)?如果没有,有什么替代方案?
最佳答案
grails/hibernate session 是什么意思?
如果您真的指的是 Hibernate session ,那么向其中添加一个对象将在刷新 session 时触发该对象自动保存(除非该对象未验证,在这种情况下,一旦 session 被丢弃,它将丢失)。每个请求都会创建和丢弃一个 session 。
如果您的意思是 session
自动注入(inject) Controller 和 View 的对象,它也不是 Hibernate 特定的,而是来自 Servlet 规范的旧的、普通的 HttpSession(参见 http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html)。
如果您需要访问它们,您可以使用它来存储任何类型的对象跨同一客户端的多个请求 .这意味着 session 对于给定的客户端(通过 jsessionid cookie 标识它)是私有(private)的,并且可以在多个请求中存活。如果您不需要多个请求位,将它们添加为请求属性就足够了。
把东西放在 session 中通常很好而且很快(因为默认情况下是基于内存的),但是如果滥用它会增加应用程序的内存占用,并且会阻止水平扩展(即在多个实例中部署相同的应用程序),除非粘性使用 session 机制(或 session 被持久化)。
请记住,尽管 grails 每个请求都使用一个新的 Hibernate session (不是 Http session :),所以如果您将附加到 Hibernate session 的对象添加到 Http session ,然后关闭 Hibernate session ,您可能会遇到问题.这不应该影响未保存的对象(它们不是来自 Hibernate session ),但可能会影响它们的关联(来自数据库的其他域类,因此来自 Hibernate session )。如果是这种情况,您可能需要重新连接它们。见 https://grails.github.io/grails-doc/latest/ref/Domain%20Classes/attach.html
此外,如果 session 无效(因为用户注销或重新部署服务器),存储在其中的所有内容都将消失。
如果您根本不想依赖 session ,可以创建自己的 MemoryBasedStoreService
服务和使用 ConcurrentHashMap
或类似的机制来存储和检索对象。由于服务在 Grails 中是单例的,因此您可以在整个应用程序中使用它,而不管请求或客户端如何——当然,只要您的应用程序部署在单个实例中 :)。
关于performance - 我可以使用 Grails session 来存储整个域对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31786363/