You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tinkerpop.apache.org by "stephen mallette (JIRA)" <ji...@apache.org> on 2015/03/31 22:59:53 UTC

[jira] [Commented] (TINKERPOP3-581) GraphSONWriter and CustomId issue

    [ https://issues.apache.org/jira/browse/TINKERPOP3-581?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14389398#comment-14389398 ] 

stephen mallette commented on TINKERPOP3-581:
---------------------------------------------

Trying to figure out how to solve this one.  One thing I didn't count on was implementers setting {{embedTypes}} in the default mapper definition.  My intent was for the graphSONMapper() to only register custom serializers.  {{embedTypes}} was more of a user setting - at least that was my intent.  As a first change, i think I intend to enforce that with tests.

Of course, that doesn't fix the problem, but at least it puts everyone on the same playing field for purpose of the tests.

Some options:

1. I could cheat.  I presume that you have {{supportsCustomIds}} set to {{true}}.  I could make it so that graphs that support that feature don't have their ids asserted for lossy tests and implementers become responsible for doing their own serialization tests on "id" for that.
2. I could pass assertion of an ID to the vendor.  On {{GraphProvider}} include a method for id assertion.  It is then the vendor's responsibility to deal with it, but i guess implementers could cheat and just "assert true" and bypass the test.  not a big deal, i guess - i'll assume implementers are good upstanding citizens :)
3. We change the structure of GraphSON so that it forces all IDs {{toString()}}.  Kinda crazy.  Maybe it only happens when {{embedTypes(false)}}.  Not sure if i'm suggesting that so that the test passes or if it is actually a good idea.

thoughts welcome on this one - a choice needs to be made pretty soon.

> GraphSONWriter and CustomId issue
> ---------------------------------
>
>                 Key: TINKERPOP3-581
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP3-581
>             Project: TinkerPop 3
>          Issue Type: Bug
>          Components: test-suite
>            Reporter: pietermartin
>            Priority: Critical
>             Fix For: 3.0.0.GA
>
>
> Hi,
> I have had to change sqlg to use a custom id field but alas am struggling to get the graphson IoTests to pass.
> Sqlg's id now is in json
> {code}
> {"id": {"schema":"public", "table":"Person","id"123}}
> {code}
> I have overriden the folowing Graph.Io methods.
> {code}
>     @Override
>     public GraphSONMapper.Builder graphSONMapper() {
>         final SimpleModule module = new SimpleModule();
>         module.addSerializer(RecordId.class, new RecordId.RecordIdJacksonSerializer());
>         module.addDeserializer(RecordId.class, new RecordId.CustomIdJacksonDeserializer());
>         //return GraphSONMapper.build().addCustomModule(module);
>         return GraphSONMapper.build().addCustomModule(module).embedTypes(true);
>     }
> {code}
> and in RecordId
> {code}
>     static class RecordIdJacksonSerializer extends StdSerializer<RecordId> {
>         public RecordIdJacksonSerializer() {
>             super(RecordId.class);
>         }
>         @Override
>         public void serialize(final RecordId customId, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider)
>                 throws IOException {
>             ser(customId, jsonGenerator, false);
>         }
>         @Override
>         public void serializeWithType(final RecordId customId, final JsonGenerator jsonGenerator,
>                                       final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException {
>             ser(customId, jsonGenerator, true);
>         }
>         private void ser(final RecordId recordId, final JsonGenerator jsonGenerator, final boolean includeType) throws IOException {
>             jsonGenerator.writeStartObject();
>             if (includeType)
>                 jsonGenerator.writeStringField(GraphSONTokens.CLASS, RecordId.class.getName());
>             SchemaTable schemaTable = recordId.getSchemaTable();
>             jsonGenerator.writeObjectField("schema", schemaTable.getSchema());
>             jsonGenerator.writeObjectField("table", schemaTable.getTable());
>             jsonGenerator.writeObjectField("id", recordId.getId().toString());
>             jsonGenerator.writeEndObject();
>         }
>     }
>     static class CustomIdJacksonDeserializer extends StdDeserializer<RecordId> {
>         public CustomIdJacksonDeserializer() {
>             super(RecordId.class);
>         }
>         @Override
>         public RecordId deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
>             String schema = null;
>             String table = null;
>             Long id = null;
>             while (!jsonParser.getCurrentToken().isStructEnd()) {
>                 if (jsonParser.getText().equals("schema")) {
>                     jsonParser.nextToken();
>                     schema = jsonParser.getText();
>                 } else if (jsonParser.getText().equals("table")) {
>                     jsonParser.nextToken();
>                     table = jsonParser.getText();
>                 } else if (jsonParser.getText().equals("id")) {
>                     jsonParser.nextToken();
>                     id = Long.valueOf(jsonParser.getText());
>                 } else
>                     jsonParser.nextToken();
>             }
>             if (!Optional.ofNullable(schema).isPresent())
>                 throw deserializationContext.mappingException("Could not deserialze RecordId: 'schema' is required");
>             if (!Optional.ofNullable(table).isPresent())
>                 throw deserializationContext.mappingException("Could not deserialze RecordId: 'table' is required");
>             if (!Optional.ofNullable(id).isPresent())
>                 throw deserializationContext.mappingException("Could not deserialze RecordId: 'id' is required");
>             return new RecordId(SchemaTable.of(schema, table), id);
>         }
>     }
> {code}
> When using {{.embedTypes(true)}} the serialization works but the lossy tests fail as Jackson then does not upgrade floats to doubles.
> If I omit the {{embedTypes(true)}} then the tests fail as the id is never deserialized to my custom RecordId.
> The test I am currently testing on is {{IoTest.shouldReadWriteVertexWithOUTOUTEdgesToGraphSON}}
> With {{embedTypes(true)}} ommited the test fails with
> {code}
> org.junit.ComparisonFailure: 
> Expected :public.person:::1
> Actual   :{schema=public, table=person, id=1}
> {code}
> With {{embedTypes(true)}} included the test fails with
> {code}
> java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Double
> {code}
> Any ideas as to what to do?
> Thanks
> Pieter



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)