session - 服务器集群中的 JPA 实体
问题描述
我们开始使用 JSF(TomEE 上的 MyFaces)和 JPA(Eclipselink)开发一个新的 Web 应用程序。
为了加快开发速度,我们计划不开发 DTO 层,主要是因为我们不需要它。遵循 JSF 和 Java EE 专家的建议,如 Bauke Scholtz如何在 JSF + Spring + Hibernate 中使用 DTO和 Adam Bien数据传输对象有多邪恶,我们将直接在表示层中使用 JPA 实体。
然而,这个应用程序必须在具有粘性会话的服务器集群中运行。当服务器因维护而停机或被排除在集群之外以进行应用程序部署时,该服务器的用户会话必须由其他服务器提供服务,而不会丢失会话。
我们面临的问题是保存在会话中的 JPA 实体(例如在 @ViewScoped bean 中)没有“完全”复制到其他服务器上。事实上,使用延迟加载的 JPA 实体的集合属性在其他服务器上不可用。在具有会话副本的服务器上访问集合属性(使用延迟加载的@OneToMany)时,异常
org.eclipse.persistence.exceptions.ValidationException
Exception Description: An attempt was made to traverse a relationship
using indirection that had a null Session.
This often occurs when an entity with an uninstantiated LAZY
relationship is serialized and that relationship is traversed
after serialization.
To avoid this issue, instantiate the LAZY relationship
prior to serialization
被抛出。
我知道 EntityManager 不可序列化,并且 JPA 实体在会话迁移期间序列化时完全分离,请参阅Struberg 的博客。
所以问题是,有没有办法在服务器集群中以一致的方式维护 JPA 实体,而不使用 EAGER 加载?
解决方案
您只能为某些实体配置缓存(一旦更改非常罕见)
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="name" transaction-type="JTA">
<!-- disable shared cache because we are in multi instance environment -->
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<validation-mode>CALLBACK</validation-mode>
<properties>
<!-- disable object caching because we are in multi instance environment -->
<property name="eclipselink.cache.shared.default" value="true"/>
<property name="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE"/>
</properties>
</persistence-unit>
</persistence>
您还可以在此处查看如何在共享环境中执行此操作 https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Query_Cache
推荐阅读
- ios - 如何从 JSON iOS swift 中解决字符周围的未终止字符串或字符周围的无效字符串?
- c# - 如何根据字符串值使用 UWP Frame.Navigate()
- c - 在一个套接字上接收来自多个组的多播流量时出现问题
- javascript - 注册或未注册 HTML 自定义 URL 方案检测
- java - Android后台HTTP请求不起作用?
- java - TCP Java Socket 自定义超时不适用于 docker
- javascript - 当字段为字段不工作时,Sweetalert 弹出消息
- swift - 调用中的额外参数“where”
- android - 在颤振中热重载后更新更改?
- mysql - 在 datetimefield 中记录两种不同的日期格式 - 我们想要一种格式