2016-04-01 12 views
2

Ich benutze Hazelcast 3.6.1, um von einer Map zu lesen. Die in der Map gespeicherte Objektklasse heißt Schedule.Hazelcast 3.6.1 "Es gibt keinen geeigneten Deserializer für den Typ" Ausnahme

Ich habe einen benutzerdefinierten Serializer auf der Clientseite wie folgt konfiguriert.

ClientConfig config = new ClientConfig(); 
SerializationConfig sc = config.getSerializationConfig(); 
sc.addSerializerConfig(add(new ScheduleSerializer(), Schedule.class)); 
... 
private SerializerConfig add(Serializer serializer, Class<? extends Serializable> clazz) { 
    SerializerConfig sc = new SerializerConfig(); 
    sc.setImplementation(serializer).setTypeClass(clazz); 
    return sc; 
} 

Die Karte wie dies

erstellt
private final IMap<String, Schedule> map = client.getMap("schedule"); 

Wenn ich von der Karte mit Zeitplan-ID als Schlüssel zu erhalten, gibt die Karte den korrekt Wert z.B.

return map.get("zx81"); 

Wenn ich versuche, ein SQL-Prädikat zu verwenden, z.

return new ArrayList<>(map.values(new SqlPredicate("statusActive"))); 

dann bekomme ich folgende Fehlermeldung

Exception in thread "main" com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable de-serializer for type 2. This exception is likely to be caused by differences in the serialization configuration between members or between clients and members. 

Die benutzerdefinierte Serializer Kryo (basierend auf diesem Blog http://blog.hazelcast.com/comparing-serialization-methods/) serialisiert wird mit

public class ScheduleSerializer extends CommonSerializer<Schedule> { 

    @Override 
    public int getTypeId() { 
     return 2; 
    } 

    @Override 
    protected Class<Schedule> getClassToSerialize() { 
     return Schedule.class; 
    } 

} 

Die CommonSerializer ist definiert als

public abstract class CommonSerializer<T> implements StreamSerializer<T> { 

    protected abstract Class<T> getClassToSerialize(); 

    @Override 
    public void write(ObjectDataOutput objectDataOutput, T object) { 
     Output output = new Output((OutputStream) objectDataOutput); 
     Kryo kryo = KryoInstances.get(); 
     kryo.writeObject(output, object); 
     output.flush(); // do not close! 
     KryoInstances.release(kryo); 
    } 

    @Override 
    public T read(ObjectDataInput objectDataInput) { 
     Input input = new Input((InputStream) objectDataInput); 
     Kryo kryo = KryoInstances.get(); 
     T result = kryo.readObject(input, getClassToSerialize()); 
     input.close(); 
     KryoInstances.release(kryo); 
     return result; 
    } 

    @Override 
    public void destroy() { 
     // empty 
    } 
} 

Muss ich eine Konfiguration auf der Serverseite vornehmen? Ich dachte, dass die Client-Konfiguration ausreichen würde.

Ich benutze Hazelcast-Client 3.6.1 und habe einen Knoten/Element ausgeführt.

Antwort

2

Abfragen erfordern, dass die Knoten über die Klassen wissen, da der Bytestream deserialisiert werden muss, um auf die Attribute zuzugreifen und sie abzufragen. Das heißt, wenn Sie Objekte abfragen möchten, müssen Sie die Modellklassen (und Serializer) auch auf der Serverseite bereitstellen.

Wenn Sie dagegen den Schlüssel-basierten Zugriff verwenden, brauchen wir nicht die Werte zu prüfen (und auch nicht die Schlüssel, da wir die Byte-Arrays des Schlüssels vergleichen) und senden einfach das Ergebnis. Auf diese Weise müssen weder Modellklassen noch Serialisierer auf den Hazelcast-Knoten verfügbar sein.

Ich hoffe, dass das Sinn macht.

+1

Gibt es also eine Möglichkeit, die Konfiguration auf Server/Instanzen programmgesteuert festzulegen? –

+0

Konfig config = new XmlConfigBuilder(). Build(); SerializationConfig serializationConfig = config.getSerializationConfig(); serializationConfig.add ...(); So etwas? – noctarius