Legend:
In application exists entity with next class level annotations:
@Entity
@Cache( usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE )
@Table( name = "entity", catalog = "main" )
@IdClass( EntityPK.class )
When update for this entity performed to database on first instance, Exception com.hazelcast.nio.serialization.HazelcastSerializationException: org.hibernate.HibernateException: Could not find a SessionFactory [uuid=ee9f3ccd-1f7e-4345-83ed-e58440a52123,name=null]
is thrown on second instance.
After debug I located cause of this exception - it thrown by org.hibernate.type.spi.TypeConfiguration.Scope#readResolve
method during deserialization. Instance of this class is part of default Hibernate cache key object.
From what I found out. Object that cause problem is "session scoped". In other words it is bounded to specific SessionFactory and contain in its fields session factory UUID and reference to factory itself. During serialization factory UUID is preserved. When deserialization is performed, object tries to restore link to its factory but it deserializaed in other instance where session factory with specified UUID not exists. Because session factory is missing exception is thrown.
Is there are way to avoid this exception?
Hibernate and related libs versions is next:
<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>
In your Hibernate configuration, include the following property:
<property name="hibernate.session_factory_name">some_sf_name</property>
When a composite primary key is used it's mapped to org.hibernate.usertype.UserType
which has a reference to a SessionFactory. That's why the other instance raises error when it cannot find the proper SF.
From the Hibernate doc:
hibernate.session_factory_name (e.g. A JNDI name): Setting used to name the Hibernate SessionFactory. Naming the SessionFactory allows for it to be properly serialized across JVMs as long as the same name is used on each JVM.