1

Given I have entity:

@Entity
public class NotificationType implements Serializable {
    // enum
    private DeliveryPriority deliveryPriority;

    private long sortOrder;

    // TimeStringInterval class implements Serializable
    private TimeStringInterval deliveryTimeWindow;

    // enum
    private DeliveryGroup deliveryGroup = DeliveryGroup.IMMEDIATE;

    protected String code;

    @Id
    public String getCode() {
        return code;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof CodedEntity)) return false;
        CodedEntity<?> that = (CodedEntity<?>) o;
        return Objects.equals(getCode(), that.getCode());
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(getCode());
    }
}

and Spring Data repository in order to look up NotificationType instances

@Repository
@CacheConfig(cacheNames = NOTIFICATION_TYPE_CACHE_NAME)
public interface NotificationTypeRepository extends JpaRepository<NotificationType, String> {

    @Override
    @Cacheable
    List<NotificationType> findAll();
}

and findAll method is cacheable.

My Hazelcast config is:

@Bean(destroyMethod = "shutdown")
public HazelcastInstance hazelcastInstance() {
    HazelcastInstance hazelcastInstance = new HazelcastInstanceFactory(hazelCastConfig()).getHazelcastInstance();
    return hazelcastInstance;
}

@Bean
public Config hazelCastConfig() {
    Config config = new Config("hazelcast")

    config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
    config.getNetworkConfig().getJoin().getAwsConfig().setEnabled(false);
    config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true).setMembers("localhost");

    config.getSerializationConfig().setEnableCompression(true);

    LockConfig lockConfig = new LockConfig();
    lockConfig.setName("locks");
    config.addLockConfig(lockConfig);

    ListConfig listConfig = new ListConfig();
    listConfig.setName("lists");
    config.addListConfig(listConfig);

    return config;
}

When I execute findAll() and hazelcast tries to put the list into the cache, it throws the HazelcastSerializationException:

2019-01-17 16:12:20.762 ERROR --- [hz.ntf-cache.partition-operation.thread-7][][] SetOperation                             : [localhost]:5701 [ntf-cluster-1547735979367] [3.11.1] There is no suitable de-serializer for type 1921036036. This exception is likely to be caused by differences in the serialization configuration between members or between clients and members.

com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable de-serializer for type 1921036036. This exception is likely to be caused by differences in the serialization configuration between members or between clients and members.
    at com.hazelcast.internal.serialization.impl.AbstractSerializationService.newHazelcastSerializationException(AbstractSerializationService.java:238) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.internal.serialization.impl.AbstractSerializationService.readObject(AbstractSerializationService.java:265) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataInput.readObject(ByteArrayObjectDataInput.java:574) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.internal.serialization.impl.ArrayListStreamSerializer.read(ArrayListStreamSerializer.java:49) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.internal.serialization.impl.ArrayListStreamSerializer.read(ArrayListStreamSerializer.java:31) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:187) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.map.impl.record.ObjectRecordFactory.newRecord(ObjectRecordFactory.java:37) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.map.impl.recordstore.AbstractRecordStore.createRecord(AbstractRecordStore.java:111) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.map.impl.recordstore.AbstractEvictableRecordStore.createRecord(AbstractEvictableRecordStore.java:55) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.map.impl.recordstore.DefaultRecordStore.putInternal(DefaultRecordStore.java:701) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.map.impl.recordstore.DefaultRecordStore.set(DefaultRecordStore.java:680) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.map.impl.operation.SetOperation.run(SetOperation.java:39) ~[hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.spi.Operation.call(Operation.java:170) [hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.call(OperationRunnerImpl.java:208) [hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:197) [hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:147) [hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:125) [hazelcast-3.11.1.jar:3.11.1]
    at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.run(OperationThread.java:110) [hazelcast-3.11.1.jar:3.11.1]

What is the reason for that exception?

How should I troubleshoot such a problem?

The exception message is very cryptic.

I was trying to debug list of objects which work and compare it to this list, but I couldn't spot any significant difference.

The issue happens locally on Windows machine, latest hazelcast version

Patrik Mihalčin
  • 3,341
  • 7
  • 33
  • 68
  • This is not related to hazelcast itself but kind of duplication of that question - https://stackoverflow.com/questions/285793/what-is-a-serialversionuid-and-why-should-i-use-it/285809 – Dzmitry Prakapenka Jan 18 '19 at 07:28
  • You are not correct. It is not duplication. This problem can happen to anyone and they can struggle to link it to `serialVersionUID` as it was my case. The question you linked to is general question about `Serializable`. – Patrik Mihalčin Jan 18 '19 at 08:23

1 Answers1

2

I added

private static final long serialVersionUID = 1L;

and it all started working properly.

It is also recommended in official hazelcast documentation:

To eliminate class compatibility issues, it is recommended that you add a serialVersionUID

Patrik Mihalčin
  • 3,341
  • 7
  • 33
  • 68
  • You may want to use different serialization mechanism for hazelcast, since you already have a link to documentation. Serializable is not the best choice for non-binary objects storage. – Dzmitry Prakapenka Jan 18 '19 at 07:30
  • What is the best mechanism? I (re)used `Serializable` because I already use it for `JPA`. My question was not focused on the best serialization technique ever, I just wanted to make things work. – Patrik Mihalčin Jan 18 '19 at 08:26
  • I recommend this easy to setup and fast solution: https://github.com/jerrinot/subzero – Ozan Kılıç Jan 21 '19 at 07:53