问题
I used neo4j-rest-binding in my project, but I face some transaction issue, so I want to control transaction by my self. I found neo4j-jdbc is a good option, and it sounds have more pros than neo4j-rest-binding from the article in google forum. (https://groups.google.com/forum/#!topic/neo4j/4DG_R5Yh2BM)
I used neo4j-rest-binding to do query and I can transform the result to Node object.
QueryResult<Map<String, Object>> result = engine.query("MATCH (n) RETURN n")
Iterator<Node> nodeIter = result.to(Node.class).iterator();
// if I want to get the relationship of the node
Iterator<Relationship> outRelIter = node.getRelationships(Direction.OUTGOING).iterator();
...
But when I use neo4j-jdbc to do query, I don't know how to get Node object...
ResultSet rs = stmt.executeQuery("MATCH (n) RETURN n");
while(rs.next()) {
Map<String, Object> res = (Map<String, Object>) rs.getObject("n");
// how to get Node object?
}
Another question is if I use tx.fail()
, tx.success()
and tx.finish()
, how could I know when the transaction fail? I know it will rollback if tx.success
is not called, but since I combine MongoDB and Neo4j, I want to rollback MongoDB when Neo4j fail. such like:
//Do some MongoDB operation...
...
//Do some Neo4j operation...
tx.begin();
try {
...
if(???) // if transaction fail
// rollback MongoDB
else
tx.success();
} finally {
tx.close();
}
Does it work when I use neo4j-jdbc? (I have answered this question by myself)
try {
conn.setAutoCommit(false); // for Neo4j
//Do some MongoDB operation...
...
//Do some Neo4j operation...
conn.commit();
} catch(SQLException e) {
conn.rollback(); // for Neo4j
// rollback MongoDB
}
Many thanks!
回答1:
If you return a node from cypher it will be returned as a Map in the remote case, so you can use (Map)rs.getObject("n")
to access the property.
If you use getString() you get a JSON representation instead.
If you need node-id's or -labels you have to return them explicitely, like this:
MATCH (n)
RETURN { id : id(n), labels : labels(n), data: n } as node
Then again, you get a map back with the id
, labels
and the node-properties as data
fields.
For controlling the transaction you use connection.setAutoCommit(false)
and connection.commit()
or connection.rollback()
.
回答2:
Cypher JDBC does not return nodes, instead it returns the properties of a node as you've seen. To get the node as a object:
ResultSet rs = stmt.executeQuery("MATCH (n) RETURN id(n)");
while(rs.next()) {
long nodeId = (long) rs.getObject("id(n)");
Node n = graphDb.getNodeById(nodeId);
}
However this works only in embedded mode. When using Cypher JDBC remotely there is no notion of nodes. Every operation in the graph should be done solely via Cypher.
回答3:
If you want to control the transaction with Neo4j and MongoDB by yourself. You could use below structure:
try {
conn.setAutoCommit(false); // for Neo4j
//Do some Neo4j operation...
//Do some MongoDB operation...
conn.commit(); // if Mongo and Neo4j both success, data will be committed to Neo4j
} catch(SQLException e) {
conn.rollback(); // for Neo4j
// rollback MongoDB
}
Since MongoDB has it's own way to rollback in same document. If Neo4j success, but MongoDB fail. MongoDB will rollback and it will get an exception and neo4j will rollback too. If Neo4j Fail, it will not execute mongo section.
来源:https://stackoverflow.com/questions/23807691/how-to-get-node-object-when-using-neo4j-jdbc