Search code examples
scalagremlintinkerpop3amazon-neptunegremlin-scala

Unsupported property value type: java.util.LinkedHashMap when writing to Neptune


Im using Gremlin-scala 3.4.1.5 against Neptune and I'm unable to add a vertex using a case class with a List or Set like so. Add vertex seems to work when that doesn't exist

//connection
Cluster.build()
      .addContactPoint(endpoint)
      .serializer(new GraphSONMessageSerializerV3d0())
      .port(port)
      .create()

val g = EmptyGraph.instance.asScala().configure(_.withRemote(DriverRemoteConnection.using(cluster)))

// adding vertex

case class Person(name: String, friends: Seq[String])
case class Person(name: String, friends: Set[String]) // also does not work
g + Person

Stack Trace

org.apache.tinkerpop.gremlin.driver.exception.ResponseException: {"requestId":-087f-4868-b4b7-","code":"UnsupportedOperationException","detailedMessage":"Unsupported property value type: java.util.LinkedHashMap"}
java.util.concurrent.CompletionException: org.apache.tinkerpop.gremlin.driver.exception.ResponseException: {"requestId":"-087f-4868-b4b7-","code":"UnsupportedOperationException","detailedMessage":"Unsupported property value type: java.util.LinkedHashMap"}
    at java.util.concurrent.CompletableFuture.reportJoin(CompletableFuture.java:375)
    at java.util.concurrent.CompletableFuture.join(CompletableFuture.java:1934)
    at org.apache.tinkerpop.gremlin.driver.ResultSet.one(ResultSet.java:119)
    at org.apache.tinkerpop.gremlin.driver.ResultSet$1.hasNext(ResultSet.java:171)
    at org.apache.tinkerpop.gremlin.driver.ResultSet$1.next(ResultSet.java:178)
    at org.apache.tinkerpop.gremlin.driver.ResultSet$1.next(ResultSet.java:165)
    at org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteTraversal$TraverserIterator.next(DriverRemoteTraversal.java:140)
    at org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteTraversal$TraverserIterator.next(DriverRemoteTraversal.java:125)
    at org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteTraversal.nextTraverser(DriverRemoteTraversal.java:106)

Solution

  • Neptune does not support List as a property type [1]. If an ordered list is required, one way to do it is to serialize it into a single property (eg: json string of the list). It does need a bit of logic in the application layer to read it back properly. Another common way to do lists is to model your list item as a vertex on its own, and model them as edges in the graph.

    Eg: Instead of having a property for the list of Addresses, make Address a vertex Label, and have edges from your Person to Address1 to Address2. This option is better if you anticipate mutations to your list.

    https://docs.aws.amazon.com/neptune/latest/userguide/access-graph-gremlin-differences.html

    Update

    Accepting this as answer because that's what I ended up using. I would just like to clarify a few things.

    Neptune supports Single and Set cardinality properties when using the Gremlin property() step etc.

    I have opened an issue in Gremlin-scala because I believe the native TinkerPop cardinalities should be supported for List and Set. List would fail in Neptune today but that's fine because the user can switch to Set if it worked for their use case and that would work.