Search code examples
javaarraysjsonserializationmapdb

org.mapdb.DBException$SerializationError when storing JSONArray in MapDB using ELSA Serialization


I have a class that store a Long value and JSONArray.

Class SomeClass {
    private Long longValue;
    private JSONArray jsonArray;
    //Default and parameterised constructors.
    //Getters and Setters.
}

I'm storing these values in a NavigableMap<?, SomeClass>. ? - String / Long. I get a treeMap from MapDB as follows:

private DB mapDB = MapDBUtil.getMapDB(); //Opening or creating and getting MapDB DB object
NavigableMap<Long,SomeClass> treeMap = mapDB.treeMap(treeName).keySerializer(Serializer.LONG).valueSerializer(Serializer.ELSA).createOrOpen();

When I try to add some value to the map obtained, say:

SomeClass instance = new SomeClass("Hello", jsonArray);
treeMap.put("test", instance);

I get org.mapdb.DBException$SerializationError. I figured the issue is due to serializing JSONArray. I want to either implement a custom serializer or use some other way to serialize and store this data. I tried implementing Serializable and also ElsaSerializer in 'SomeClass' but both of those don't seem to work. I have also tried to use Serializer.JAVA when Serializable interface is implemented but that doesn't work too. I'm not sure about what I'm doing wrong. Any help would be really appreciated.


Solution

  • I ended up fixing it by implementing a custom serializer and using it as follows:

    Class SomeClassSerialzer extends GroupSerializerObjectArray<SomeClass> {
    @Override
        public void serialize(DataOutput2 dataOutput2, SomeClass someClass) throws IOException {
            dataOutput2.writeLong(someClass.getLong());
            dataOutput2.writeUTF(threatSourceData.getJSONArray().toString());
        }
    
        @Override
        public SomeClass deserialize(DataInput2 dataInput2, int i) throws IOException {
            JSONArray jsonArray = null;
            Long longValue = dataInput2.readLong();
            try {
                categories = new JSONArray(dataInput2.readUTF());
            } catch (JSONException ignored) {
            }
            return new SomeClass(reputation, categories);
        }
    }
    

    When getting BTreeMap from MapDB, use the SomeClassSerialzer as follows:

    NavigableMap<Long,SomeClass> treeMap = mapDB.treeMap(treeName).keySerializer(Serializer.LONG).valueSerializer(new SomeClassSerialzer()).createOrOpen();