迁移到版本 3 后,Neo4j OGM 在 Play Framework HTTP GET 中不起作用

Neo4j OGM doesn't work in Play Framework HTTP GET after migration to version 3

今天我将 neo4j-ogm 迁移到最新版本 (3.0.1)。我遵循了所有建议,但现在当我尝试查询一个实体时,我得到一个 MappingException,因为系统似乎无法找到该实体 class。在进一步调查和阅读 之后,我尝试在 HTTP POST 响应中查询并且它工作正常所以使用 neo4j-ogm Session 在 GET HTTP 响应中查询似乎确实是一个问题在另一个问题的答案中建议。关于这里可能发生的事情的任何想法?

异常看起来像:

play.api.http.HttpErrorHandlerExceptions$$anon: Execution exception[[MappingException: Error mapping GraphModel to instance of nodes.UserNode]]
        at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:255)
        at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:180)
        at play.core.server.AkkaHttpServer$$anonfun$$anonfun$apply.applyOrElse(AkkaHttpServer.scala:251)
        at play.core.server.AkkaHttpServer$$anonfun$$anonfun$apply.applyOrElse(AkkaHttpServer.scala:250)
        at scala.concurrent.Future$$anonfun$recoverWith.apply(Future.scala:346)
        at scala.concurrent.Future$$anonfun$recoverWith.apply(Future.scala:345)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
        at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:70)
        at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40)
        at scala.concurrent.impl.Promise$DefaultPromise.scala$concurrent$impl$Promise$DefaultPromise$$dispatchOrAddCallback(Promise.scala:280)
Caused by: org.neo4j.ogm.exception.core.MappingException: Error mapping GraphModel to instance of nodes.UserNode
        at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:206)
        at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:135)
        at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:89)
        at org.neo4j.ogm.session.delegates.LoadOneDelegate.load(LoadOneDelegate.java:70)
        at org.neo4j.ogm.session.delegates.LoadOneDelegate.load(LoadOneDelegate.java:46)
        at org.neo4j.ogm.session.Neo4jSession.load(Neo4jSession.java:155)
        at controllers.UsersController.getUserMetrics(UsersController.java:372)
        at controllers.UsersController.index(UsersController.java:66)
        at router.Routes$$anonfun$routes$$anonfun$applyOrElse$$anonfun$apply.apply(Routes.scala:891)
        at router.Routes$$anonfun$routes$$anonfun$applyOrElse$$anonfun$apply.apply(Routes.scala:891)
Caused by: org.neo4j.ogm.exception.core.MappingException: Unable to load class with FQN: nodes.UserNode
        at org.neo4j.ogm.metadata.reflect.EntityFactory.instantiateObjectFromTaxa(EntityFactory.java:109)
        at org.neo4j.ogm.metadata.reflect.EntityFactory.newObject(EntityFactory.java:58)
        at org.neo4j.ogm.context.GraphEntityMapper.mapNodes(GraphEntityMapper.java:217)
        at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:203)
        at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:135)
        at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:89)
        at org.neo4j.ogm.session.delegates.LoadOneDelegate.load(LoadOneDelegate.java:70)
        at org.neo4j.ogm.session.delegates.LoadOneDelegate.load(LoadOneDelegate.java:46)
        at org.neo4j.ogm.session.Neo4jSession.load(Neo4jSession.java:155)
        at controllers.UsersController.getUserMetrics(UsersController.java:372)
Caused by: java.lang.ClassNotFoundException: nodes.UserNode
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at org.neo4j.ogm.metadata.reflect.EntityFactory.instantiateObjectFromTaxa(EntityFactory.java:106)
        at org.neo4j.ogm.metadata.reflect.EntityFactory.newObject(EntityFactory.java:58)
        at org.neo4j.ogm.context.GraphEntityMapper.mapNodes(GraphEntityMapper.java:217)
        at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:203)
        at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:135)

neo4j 调试日志如下所示:

[info] o.n.o.d.b.r.BoltRequest - Request: MATCH (n:`UserNode`) WHERE ID(n) = { id } WITH n RETURN n,[ [ (n)<-[r_p1:`PEER`]-(u1:`UserNode`) | [ r_p1, u1 ] ] ] with params {id=1}
[debug] o.n.o.d.b.d.BoltDriver - No current transaction, starting a new one
[debug] o.n.o.d.b.d.BoltDriver - Native transaction: org.neo4j.driver.internal.ExplicitTransaction@6acdd993
[debug] o.n.o.d.b.t.BoltTransaction - Committing native transaction: org.neo4j.driver.internal.ExplicitTransaction@6acdd993
[debug] o.n.o.t.Transaction - Thread 62: Commit transaction extent: 0
[debug] o.n.o.t.Transaction - Thread 62: Committed
[debug] o.n.o.t.Transaction - Thread 62: Close transaction extent: 0
[debug] o.n.o.t.Transaction - Thread 62: Closing transaction
[debug] o.n.o.m.MetaData - looking for concrete class to resolve label: UserNode
[debug] o.n.o.m.MetaData - concrete class found: org.neo4j.ogm.metadata.ClassInfo@7abf416c. comparing with what's already been found previously...
[debug] o.n.o.m.MetaData - UserNode resolving class: org.neo4j.ogm.metadata.ClassInfo@7abf416c
[error] application -

我正在使用

核心问题好像是ClassNotFoundException。看起来 neo4j-ogm 正在尝试加载 nodes.UserNode class,但找不到它。

可能 neo4j-ogm 没有使用正确的 ClassLoader。这是 Play 中的一个常见问题,因为 "dev mode" 中使用了多个 ClassLoader,而默认的通常不正确。

要解决此问题,首先通过注入 play.Environment(Play 的 Java API)或 play.api.Environment(Play 的 Scala API).然后在Environment上调用classLoader属性得到Play的ClassLoader.

接下来,将 ClassLoader 提供给 neo4j-ogm,将其显式传递给 neo4j-ogm(如果API 支持它)或使用 Thread.setContextClassLoader() 设置当前线程的默认值 ClassLoader(确保在完成后恢复旧的 ClassLoader)。

建议的 ClassLoader 问题实际上是问题所在。然而,neo4j-ogm 有办法自行解决。正如所建议的那样 here neo4j-ogm 在加载类型时可能也不依赖于 class 加载器。代码已修复,下一个版本的 ogm 应该没问题(当前版本是 3.0.1)。