服务器群集中的JPA实体

时间:2019-02-20 10:31:54

标签: session jpa jsf eclipselink

我们开始使用JSF(TomEE上的MyFaces)和JPA(Eclipselink)开发新的Web应用程序。

为了使开发时间更快,我们计划不开发DTO层,基本上是因为我们不需要它。遵循诸如Bauke Scholtz How to use DTO in JSF + Spring + Hibernate和Adam Bien How evil are Data Transfer Objects之类的JSF和Java EE专家的建议,我们将直接在表示层中使用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's Blog

所以问题是,有没有一种方法可以在服务器群集中以一致的方式维护JPA实体,而无需使用EAGER加载?

1 个答案:

答案 0 :(得分:0)

您只能为某些实体(一次更改很少的实体)配置缓存

<?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