Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating vertices from case class with nested case class fields #82

Closed
ecausarano opened this issue Jul 26, 2016 · 7 comments
Closed

Creating vertices from case class with nested case class fields #82

ecausarano opened this issue Jul 26, 2016 · 7 comments

Comments

@ecausarano
Copy link

Hi,

I'm trying to persist a case class containing several other case classes. TinkerGraph tests work alright whereas when switching to OrientGraph causes a

com.orientechnologies.orient.core.exception.ODatabaseException: Error on deserialization of Serializable
...
Caused by: java.lang.ClassNotFoundException: ...

Seems that in org.apache.tinkerpop.gremlin.orientdb.OrientElement#property(java.lang.Object...) the property is passed on as-is to the ODocument without mapping it first to another ODocument.

@mpollmeier
Copy link
Collaborator

you don't provide much context so I can only guess, but let me guess that you're trying to persist one of your own classes via a remote connection to orientdb? that wouldn't work because orient doesn't know your classes

@ecausarano
Copy link
Author

ecausarano commented Jul 26, 2016

Yup, that's the situation, eventually the ODocument sent off for saving contains an ODocumentEntry with the raw instance of my domain class. I think it should be also wrapped into an ODocument.

Would it be a big deal to wrap embedded classes in the orientdb-gremlin driver?

@mpollmeier
Copy link
Collaborator

maybe i wasn't clear enough - you cannot send your own classes via a remote connection to orientdb. you need to transform them into a vertex first. gremlin-scala e.g. has a macro that does that job for you: https://github.com/mpollmeier/gremlin-scala/#mapping-vertices-fromto-case-classes

@ecausarano
Copy link
Author

ecausarano commented Jul 29, 2016

Hi,

sorry for not being mistaken, but I was under the impression that this would work:

import org.apache.tinkerpop.gremlin.orientdb.OrientGraphFactory
import org.scalatest.{Matchers, WordSpec}
import gremlin.scala._
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph

class SerializeNestedSpec extends WordSpec with Matchers {
  "Classes with Nested members" must {
    "be correctly serialized" in new Fixture {
      val foo = Foo("a string")
      val bar = Bar("another string", foo)

      val vertex = graph + bar

      val bar1 = vertex.toCC[Bar]
      bar1.should(equal(bar))
    }
  }

  case class Foo(string: String)
  case class Bar(string: String, foo: Foo)
  trait Fixture {
//    val graph = TinkerGraph.open.asScala
    val graph = new OrientGraphFactory(s"memory:test-${math.random}").getNoTx().asScala
  }
}

The problem is that the macro doesn't recur. If you step into the addVertex it'll eventually call org.apache.tinkerpop.gremlin.orientdb.OrientElement#property(java.lang.Object...) with a Foo object in the properties. The TinkerGraph implementation doesn't mind, but Orient does as it expects nested documents to be wrapped in ODocuments, not ODocumentEntries.

I don't know if it would be a good approach but the Orient driver (in com.orientechnologies.orient.core.record.impl.ODocument#field(java.lang.String, java.lang.Object, which is eventually called) supports nested fields using . interpolation: fromCC could flatten the foo instance fiends in bar as a foo.string, while toCC would de-interpolate the fields and rebuild the objects accordingly. I think this could also help the Neo4J backend, since it doesn't support nested documents at all!

@jCalamari
Copy link

This is general issue with scala classes/types. Funny part is, this works for memory storage, whereas remote doesn't.

@ecausarano
Copy link
Author

I guess it's because when running "in memory" the JVM knows how to serialize the CCs because they're in the classpath.

@mpollmeier
Copy link
Collaborator

exactly - the in memory instance knows all your classes, but in production you're unlikely to run it this way. and yeah, quite possible that the macro doesn't support nesting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants