Hot questions for Using Neo4j in neo4j bolt

Top Java Programmings / Neo4j / neo4j bolt

Question:

I am adding the Neo4j Bolt driver to my application just following the http://neo4j.com/developer/java/:

import org.neo4j.driver.v1.*;

Driver driver = GraphDatabase.driver( "bolt://localhost", AuthTokens.basic( "neo4j", "neo4j" ) );

Session session = driver.session();
session.run( "CREATE (a:Person {name:'Arthur', title:'King'})" );

StatementResult result = session.run( "MATCH (a:Person) WHERE a.name = 'Arthur' RETURN a.name AS name, a.title AS title" );

while ( result.hasNext() )

{
    Record record = result.next();
    System.out.println( record.get( "title" ).asString() + " " + record.get("name").asString() );
}
session.close();
driver.close();

However, always from the official documentation unit testing is made using:

GraphDatabaseService db = new TestGraphDatabaseFactory()
            .newImpermanentDatabaseBuilder()

So if I want to test in some way the code above, I have to replace the GraphDatabase.driver( "bolt://localhost",...) with the GraphDatabaseService from the test. How can I do that? I cannot extract any sort of in-memory driver from there as far as I can see.


Answer:

The Neo4j JDBC has a class called Neo4jBoltRule for unit testing. It is a junit rule starting/stopping an impermanent database together with some configuration to start bolt.

The rule class uses dynamic port assignment to prevent test failure due to running multiple tests in parallel (think of your CI infrastructure).

An example of a unit test using that rule class is available at https://github.com/neo4j-contrib/neo4j-jdbc/blob/master/neo4j-jdbc-bolt/src/test/java/org/neo4j/jdbc/bolt/SampleIT.java

Question:

I connect neo4j-community-3.1.1 via neo4j-java-driver to a non-local server like this:

    Driver driver = GraphDatabase.driver("bolt://10.209.20.211:7687",
            AuthTokens.basic("username", "xxxx"));
    System.out.println("neo4j driver created..");
    Session session = driver.session();
    System.out.println("session opened..");

but it will never reach "System.out.println("session opened..");" obviously, it is stuck when "driver.session();"

I'm sure that the network is work, I have tested by "telnet 10.209.20.211 7687".

And the neo4j.conf file like this:

   #*****************************************************************
   # Network connector configuration
   #*****************************************************************

   # With default configuration Neo4j only accepts local connections.
   # To accept non-local connections, uncomment this line:
   dbms.connectors.default_listen_address=0.0.0.0

   # You can also choose a specific network interface, and configure a non-default
   # port for each connector, by setting their individual listen_address.

   # The address at which this server can be reached by its clients. This may be the server's IP address or DNS name, or
   # it may be the address of a reverse proxy which sits in front of the server. This setting may be overridden for
   # individual connectors below.
   #dbms.connectors.default_advertised_address=localhost

   # You can also choose a specific advertised hostname or IP address, and
   # configure an advertised port for each connector, by setting their
   # individual advertised_address.

   # Bolt connector
   dbms.connector.bolt.enabled=true
   #dbms.connector.bolt.tls_level=OPTIONAL
   #dbms.connector.bolt.listen_address=:7687

   # HTTP Connector. There must be exactly one HTTP connector.
   dbms.connector.http.enabled=true
   #dbms.connector.http.listen_address=:7474

Now, what's the problem?


Answer:

I resolve this problem by below code:

Config cfg = Config.build().withEncryptionLevel(Config.EncryptionLevel.NONE).toConfig();
Driver driver = GraphDatabase.driver("bolt://10.209.20.211:7687",
        AuthTokens.basic("username", "xxxx"), cfg);
System.out.println("neo4j driver created..");
Session session = driver.session();
System.out.println("session opened..");

Question:

I am using the Java Bolt driver (1.0.1) and I am wondering there is a way to convert the result to Json (possibly the same as in the REST api)?

I tried to use gson in this way:

Result r = null;
try ( Transaction tx = graphDb.beginTx() )
{
    r = graphDb.execute("MATCH...");
    tx.success();
} catch {...}

new Gson().toJson(result);

but what I get is:

java.lang.StackOverflowError
    at com.google.gson.internal.$Gson$Types.canonicalize($Gson$Types.java:98)
    at com.google.gson.reflect.TypeToken.<init>(TypeToken.java:72)
    etc...

Answer:

The API you show is not the Bolt-Driver, it's the embedded Java-API.

In the bolt-driver you can do

Driver driver = GraphDatabase.driver( "bolt://localhost", AuthTokens.basic( "neo4j", "neo4j" ) );
Session session = driver.session();

StatementResult result = session.run( "MATCH (a:Person) WHERE a.name = 'Arthur' RETURN a.name AS name, a.title AS title" );

while ( result.hasNext() ) {
    Record record = result.next();
    gson.toJson(record.asMap());
}
session.close();
driver.close();

Question:

Consider I have a node having Label L1 in Neo4j database. I need to put a constraint on all nodes having label L1 such that there shall be no outgoing edge from these nodes. So whenever user tries to add an outgoing edge from these nodes, a constraint violation occurs. Is it possible to add user defined constraints on nodes and relationships?

If yes, how can I put such constraint(s) on nodes/relationships using Neo4j Java API's?


Answer:

According to the Neo4j constraints documentation there is no way to do this.

I think you should delegate this type of responsibility to the application layer. Alternatively, you can try achieve your goal writing your own user defined procedure.