传奇:
在应用程序中,存在具有下一类级别注释的实体:
@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的会话工厂的其他情况下,它将反序列化。因为缺少会话工厂,将引发异常。
有办法避免这种异常吗?
Hibernate和相关的lib版本是下一个:
<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>
在您的Hibernate配置中,包括以下属性:
<property name="hibernate.session_factory_name">some_sf_name</property>
使用复合主键时,它被映射到具有对SessionFactory的引用的org.hibernate.usertype.UserType
。这就是为什么另一个实例在找不到合适的SF时会引发错误的原因。
从休眠doc:
hibernate.session_factory_name(例如,JNDI名称):用于命名Hibernate SessionFactory的设置。只要为每个JVM使用相同的名称,对SessionFactory进行命名就可以在JVM之间对其进行正确的序列化。