我正在尝试为neo4j 3.0.0编写插件。为了测试水,我写了这个非常简单的方法来揭示外向度。
public class Utils extends ServerPlugin {
@PluginTarget(value = Node.class)
public int outgoingDegree(@Source Node node) {
return node.getDegree(Direction.OUTGOING);
}
}
注册插件的工作完美无缺:
curl -v http://localhost:7474/db/data/ext/
{
"Utils" : "http://localhost:7474/db/data/ext/Utils"
}
我的小方法就在那里:
curl -v http://localhost:7474/db/data/ext/Utils
{
"node" : {
"outgoingDegree" : {
"extends" : "node",
"name" : "outgoingDegree",
"description" : "",
"parameters" : [ ]
}
}
}
惊人。现在当我尝试调用这种方法时,一切都走下坡路了:
url -XPOST -v http://localhost:7474/db/data/ext/Utils/node/20/outgoingDegree -H "Accept: application/json" -H "Content-type: application/json" -d "{ }"
{
"message" : "The requested operation cannot be performed, because it has to be performed in a transaction. Ensure you are wrapping your operation in the appropriate transaction boilerplate and try again.",
"exception" : "BridgeNotInTransactionException",
"fullname" : "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge$BridgeNotInTransactionException",
"stackTrace" : [ "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.assertInUnterminatedTransaction(ThreadToStatementContextBridge.java:72)", "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.getTopLevelTransactionBoundToThisThread(ThreadToStatementContextBridge.java:105)", "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.getKernelTransactionBoundToThisThread(ThreadToStatementContextBridge.java:113)", "org.neo4j.kernel.impl.core.ThreadToStatementContextBridge.get(ThreadToStatementContextBridge.java:65)", "org.neo4j.kernel.impl.factory.ClassicCoreSPI.currentStatement(ClassicCoreSPI.java:205)", "org.neo4j.kernel.impl.factory.GraphDatabaseFacade$$Lambda$76/46581122.get(Unknown Source)", "org.neo4j.kernel.impl.coreapi.StandardNodeActions.statement(StandardNodeActions.java:56)", "org.neo4j.kernel.impl.core.NodeProxy.getDegree(NodeProxy.java:702)", "com.github.denizco.datascience.neo4jplugin.Utils.outgoingDegree(Utils.java:12)", "java.lang.reflect.Method.invoke(Method.java:483)", "org.neo4j.server.plugins.PluginMethod.invoke(PluginMethod.java:61)", "org.neo4j.server.plugins.PluginManager.invoke(PluginManager.java:158)", "org.neo4j.server.rest.web.ExtensionService.invokeNodeExtension(ExtensionService.java:325)", "org.neo4j.server.rest.web.ExtensionService.invokeNodeExtension(ExtensionService.java:184)", "java.lang.reflect.Method.invoke(Method.java:483)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:144)", "org.neo4j.server.rest.dbms.AuthorizationFilter.doFilter(AuthorizationFilter.java:121)", "org.neo4j.server.rest.web.CollectUserAgentFilter.doFilter(CollectUserAgentFilter.java:69)", "java.lang.Thread.run(Thread.java:745)" ],
"errors" : [ {
"code" : "Neo.ClientError.Request.TransactionRequired",
"message" : "The requested operation cannot be performed, because it has to be performed in a transaction. Ensure you are wrapping your operation in the appropriate transaction boilerplate and try again."
} ]
}
这里发生了什么?为什么我需要在交易中包裹我的电话,我该怎么做?有办法解决这个问题吗?
答案 0 :(得分:1)
Neo4j中的任何操作(读或写)都需要进行交易。如果没有明确管理,唯一的例外graphDb.execute(cypherString)
会在引擎盖下创建交易
所以将你的代码包装成:
try (Transaction tx=graphDb.beginTx()) {
// do your stuff
tx.success();
}
然而,使用“服务器插件”几乎是旧技术。在Neo4j 3.0中,黄金标准是使用程序并使用CALL
从Cypher访问它们。