在Web应用程序中,我使用JPA实体将我的域对象持久化(并检索)到底层数据库。
这些JPA实体保持热销&#34;在内存缓存结构中(考虑Map<UniqueID, Entity>
),了解Web应用程序的整个运行时间。
所以我正在向我的Web应用程序发出请求,实体从存储库加载。该实体被放入内存缓存结构中。对于此请求的整个生命周期,我可以愉快地访问此实体的任何字段。在第一次请求期间,即使在我的View
中,我也可以很好地使用与其他实体的延迟加载关系:我成功使用 Open-Session-in-View模式(通过春天的OpenEntityManagerInViewInterceptor
)。
第一个请求已经结束。
我正在对我的网络应用程序执行下一个请求。该请求要求另一个实体。 此实体已经在内存缓存结构中,因此从那里加载。从这个实体,我尝试访问一个应该延迟加载与其他实体的关系的字段。不幸的是,这引起了令人讨厌的org.hibernate.LazyInitializationException: could not initialize proxy - no Session
(我使用Hibernate作为我的基础JPA实现)
据我了解,这个例外源于这样的事实:在第一个请求结束后,JPA / Hibernate已经结束了任何JPA会话,但我的内存缓存结构中的实体仍然期望这些会话中的任何一个存在;在下一个请求导致为延迟加载实体启动机制的那一刻,延迟加载机制无法找到任何不再存在的会话。
我的问题的解决方案是什么?
答案 0 :(得分:2)
Session.update()
在第二个请求开始时将实体重新连接到会话。答案 1 :(得分:0)
基本上,您不能在HTTP请求之间保持会话活动,因为这意味着在请求之间保持事务处于打开状态。
我认为唯一的解决方案(除了检测自己加载的内容和不加载的内容)是在将整个实体放入缓存之前获取整个实体。恕我直言,你不应该将部分加载的对象放在缓存中。如果您不想第一次加载整个对象,则可以对对象关系使用单独的缓存。
如果你愿意,你也可以考虑按照@Adam的建议启用Hibernate缓存,但我不认为它适用于女士加载的字段。
答案 2 :(得分:0)