首页 > 解决方案 > 休眠 - Hazelcast。二级缓存。找不到 SessionFactory 异常

问题描述

传奇:

在应用程序中存在具有下一个类级别注释的实体:

@Entity
@Cache( usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE )
@Table( name = "entity", catalog = "main" )
@IdClass( EntityPK.class )

当在第一个实例上对该实体执行更新时, com.hazelcast.nio.serialization.HazelcastSerializationException: org.hibernate.HibernateException: Could not find a SessionFactory [uuid=ee9f3ccd-1f7e-4345-83ed-e58440a52123,name=null]在第二个实例上抛出异常。

org.hibernate.type.spi.TypeConfiguration.Scope#readResolve调试后,我找到了此异常的原因 - 它在反序列化期间由方法抛出。此类的实例是默认 Hibernate 缓存键对象的一部分。

从我发现的。导致问题的对象是“会话范围”。换句话说,它绑定到特定的 SessionFactory 并在其字段中包含会话工厂 UUID 和对工厂本身的引用。在序列化过程中,工厂 UUID 被保留。执行反序列化时,对象尝试恢复到其工厂的链接,但它在不存在具有指定 UUID 的会话工厂的其他实例中反序列化。因为 session factory is missing 抛出异常。

有没有办法避免这个异常?

接下来是 Hibernate 和相关的库版本:

<hibernate.version>5.3.14.Final</hibernate.version>
<hibernate-types-52.version>2.5.0</hibernate-types-52.version>
<hazelcast.version>3.11.5</hazelcast.version>
<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast-hibernate53</artifactId>
    <version>1.3.2</version>
</dependency>
        <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jpamodelgen</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-envers</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

    <dependency>
        <groupId>com.vladmihalcea</groupId>
        <artifactId>hibernate-types-52</artifactId>
        <version>${hibernate-types-52.version}</version>
    </dependency>

标签: hibernatehazelcast

解决方案


在您的 Hibernate 配置中,包括以下属性:

<property name="hibernate.session_factory_name">some_sf_name</property>

当使用复合主键时,它会映射到org.hibernate.usertype.UserType对 SessionFactory 的引用。这就是为什么另一个实例在找不到合适的 SF 时会引发错误的原因。

从休眠文档

hibernate.session_factory_name(例如一个 JNDI 名称): 用于命名 Hibernate SessionFactory 的设置。只要在每个 JVM 上使用相同的名称,命名 SessionFactory 就可以跨 JVM 正确序列化它。


推荐阅读