I've switched my Hibernate cache from EHCache to Infinispan and I am now encountering an exception when modifying an entity with a composite primary key. The entity is as follows:
@Entity
@Table(name="Company_Message_Type")
@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)
public class CompanyMessageType implements Serializable
{
private static final long serialVersionUID = 1L;
@EmbeddedId private final CompanyMessageTypeId id = new CompanyMessageTypeId();
@Column(name="FL_EXTERNAL_ACCESS", nullable=false)
private boolean externalAccess;
@Column(name="FL_VIEW_CONTENT", nullable=false)
private boolean viewContent;
@MapsId("companyId")
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID_COMPANY", nullable=false)
private Company company;
@MapsId("messageTypeId")
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ID_MESSAGE_TYPE", nullable=false)
private MessageType messageType;
}
The embedded Id class is as follows:
@Embeddable
public class CompanyMessageTypeId implements Serializable
{
private static final long serialVersionUID = 1L;
@Column(name="ID_COMPANY", nullable=false)
private Long companyId;
@Column(name="ID_MESSAGE_TYPE", nullable=false)
private Long messageTypeId;
}
Both classes have sensible equals() and hashCode() methods.
The exception only occurs when there is more than one server in the cluster. The exception appears on the server(s) that are being updated. The stack trace is as follows:
ISPN000220: Problems un-marshalling remote command from byte buffer
java.io.InvalidObjectException: Could not find a SessionFactory [uuid=0d0cdf26-dfe6-4285-9725-dfaa4821ecba,name=null]
at org.hibernate.internal.SessionFactoryImpl.locateSessionFactoryOnDeserialization(SessionFactoryImpl.java:1781)
at org.hibernate.internal.SessionFactoryImpl.readResolve(SessionFactoryImpl.java:1761)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jboss.marshalling.reflect.SerializableClass.callReadResolve(SerializableClass.java:413)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1270)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:209)
at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1711)
at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1627)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1269)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:209)
at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1711)
at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1627)
at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1591)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1269)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:209)
at org.jboss.marshalling.river.RiverUnmarshaller.readFields(RiverUnmarshaller.java:1711)
at org.jboss.marshalling.river.RiverUnmarshaller.doInitSerializable(RiverUnmarshaller.java:1627)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1269)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:272)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:209)
at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
at org.infinispan.marshall.exts.ReplicableCommandExternalizer.readParameters(ReplicableCommandExternalizer.java:100)
at org.infinispan.marshall.exts.ReplicableCommandExternalizer.readObject(ReplicableCommandExternalizer.java:83)
at org.infinispan.marshall.exts.ReplicableCommandExternalizer.readObject(ReplicableCommandExternalizer.java:30)
at org.infinispan.marshall.core.ExternalizerTable$ExternalizerAdapter.readObject(ExternalizerTable.java:389)
at org.infinispan.marshall.core.ExternalizerTable.readObject(ExternalizerTable.java:205)
at org.infinispan.marshall.core.JBossMarshaller$ExternalizerTableProxy.readObject(JBossMarshaller.java:152)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:351)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:209)
at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
at org.infinispan.marshall.exts.ReplicableCommandExternalizer.readParameters(ReplicableCommandExternalizer.java:100)
at org.infinispan.marshall.exts.CacheRpcCommandExternalizer.readObject(CacheRpcCommandExternalizer.java:146)
at org.infinispan.marshall.exts.CacheRpcCommandExternalizer.readObject(CacheRpcCommandExternalizer.java:59)
at org.infinispan.marshall.core.ExternalizerTable$ExternalizerAdapter.readObject(ExternalizerTable.java:389)
at org.infinispan.marshall.core.ExternalizerTable.readObject(ExternalizerTable.java:205)
at org.infinispan.marshall.core.JBossMarshaller$ExternalizerTableProxy.readObject(JBossMarshaller.java:152)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:351)
at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:209)
at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
at org.infinispan.commons.marshall.jboss.AbstractJBossMarshaller.objectFromObjectStream(AbstractJBossMarshaller.java:136)
at org.infinispan.marshall.core.VersionAwareMarshaller.objectFromByteBuffer(VersionAwareMarshaller.java:101)
at org.infinispan.commons.marshall.AbstractDelegatingMarshaller.objectFromByteBuffer(AbstractDelegatingMarshaller.java:80)
at org.infinispan.remoting.transport.jgroups.MarshallerAdapter.objectFromBuffer(MarshallerAdapter.java:28)
at org.infinispan.remoting.transport.jgroups.CommandAwareRpcDispatcher.handle(CommandAwareRpcDispatcher.java:206)
at org.jgroups.blocks.RequestCorrelator.handleRequest(RequestCorrelator.java:460)
at org.jgroups.blocks.RequestCorrelator.receiveMessage(RequestCorrelator.java:377)
at org.jgroups.blocks.RequestCorrelator.receive(RequestCorrelator.java:247)
at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.up(MessageDispatcher.java:665)
at org.jgroups.JChannel.up(JChannel.java:708)
at org.jgroups.stack.ProtocolStack.up(ProtocolStack.java:1015)
at org.jgroups.protocols.RSVP.up(RSVP.java:187)
at org.jgroups.protocols.FRAG2.up(FRAG2.java:165)
at org.jgroups.protocols.FlowControl.up(FlowControl.java:381)
at org.jgroups.protocols.FlowControl.up(FlowControl.java:370)
at org.jgroups.protocols.tom.TOA.up(TOA.java:121)
at org.jgroups.protocols.pbcast.GMS.up(GMS.java:1010)
at org.jgroups.protocols.pbcast.STABLE.up(STABLE.java:234)
at org.jgroups.protocols.AUTH.up(AUTH.java:118)
at org.jgroups.protocols.UNICAST3.handleDataReceived(UNICAST3.java:694)
at org.jgroups.protocols.UNICAST3.up(UNICAST3.java:381)
at org.jgroups.protocols.pbcast.NAKACK2.up(NAKACK2.java:600)
at org.jgroups.protocols.VERIFY_SUSPECT.up(VERIFY_SUSPECT.java:147)
at org.jgroups.protocols.FD.up(FD.java:255)
at org.jgroups.protocols.FD_SOCK.up(FD_SOCK.java:301)
at org.jgroups.protocols.MERGE2.up(MERGE2.java:209)
at org.jgroups.protocols.Discovery.up(Discovery.java:379)
at org.jgroups.protocols.MPING.up(MPING.java:181)
at org.jgroups.protocols.TP.passMessageUp(TP.java:1399)
at org.jgroups.protocols.TP$MyHandler.run(TP.java:1585)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: an exception which occurred:
in object of type org.hibernate.internal.SessionFactoryImpl
in field factory
in object of type org.hibernate.type.TypeFactory$TypeScopeImpl
in field typeScope
in object of type org.hibernate.type.EmbeddedComponentType
in field type
in object of type org.hibernate.cache.spi.CacheKey
Has anyone seen this error before? It seems like infinispan might not be serializing the embedded id class correctly.
I'm using Hibernate 4.3.5 and Infinispan 6.0.2
EDIT:
The problem is that Infinispan is sending a serialized version of the CacheKey over the network. This key indirectly references the SessionFactoryImpl on the initiating machine, but the remote machine can't deserialize the SessionFactoryImpl and so throws this exception. I believe that the problem is specific to entities with composite primary because if the key is just a Long, the type of the CacheKey would be something else that doesn't indirectly reference the SessionFactoryImpl.
In summary, I'm not sure if it's an Infinispan problem or a Hibernate problem.
As discussed on the pull request, apparently the SessionFactory is serializable across JVMs as long as it is named (see HHH-6822). To fix my problem, I just needed to set the following Hibernate properties on the session factory:
hibernate.session_factory_name = MySessionFactory
hibernate.session_factory_name_is_jndi = false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With