Giter Site home page Giter Site logo

neo4j / neo4j-jdbc Goto Github PK

View Code? Open in Web Editor NEW
127.0 27.0 53.0 5.4 MB

Official Neo4j JDBC Driver

Home Page: http://neo4j.github.io/neo4j-jdbc/

License: Apache License 2.0

Java 99.49% Shell 0.31% Dockerfile 0.18% Smarty 0.03%
neo4j neo4j-driver jdbc integration etl business-intelligence driver java sql2cypher

neo4j-jdbc's Issues

JDBC Prefix different to 2.x

The previous JDBC prefix was jdbc:neo4j:.... I like the new Prefix with jdbc:bolt:.. and jdbc:http:.. however I'm not sure that jdbc:http:.. without any neo4j hint feels right. Maybe using jdbc:neo4j:http:.. would be better?

Connection.getWarnings not implemented

java.lang.UnsupportedOperationException: Method getWarnings in class org.neo4j.jdbc.Connection is not yet implemented.
at org.neo4j.jdbc.utils.ExceptionBuilder.buildUnsupportedOperationException(ExceptionBuilder.java:41)
at org.neo4j.jdbc.Connection.getWarnings(Connection.java:277)

Should at least return NULL

debug mode

Debug mode was removed in RC1, because we were using mockito, and we don't want to have a test library into the package.

This is a list of solution:

  1. Cglib : work is already done with a few code modification, but Cglib is common lib so we should discovered libs conflicts with some products
  2. Javassist : Same as cglib for conflicts
  3. Java proxy class : It's possible to use native java proxy class, but to implement it, we need to make some code modification (ie. using interface into InstanceFactory.debug, with all impacts needed)
  4. Using p6spy : P6spy makes a proxy class but only on a little number of class (Connection, Statement, PreparedStatement and CallableStatement) , and on each proxy class, they log only a little number of methods (commit, rollback, execute). So it's a good start, but it's not enough to debug the driver
  5. Implement logger when we needed into the code with java logger interface or slf4j

My preference go to 3 or 5, and I prefer 3 to have something generic.

What do you think ?

ResultSetMetaData.getTableName not implemented

java.lang.UnsupportedOperationException: Method getTableName in class org.neo4j.
jdbc.ResultSetMetaData is not yet implemented.
at org.neo4j.jdbc.utils.ExceptionBuilder.buildUnsupportedOperationException(ExceptionBuilder.java:41)
at org.neo4j.jdbc.ResultSetMetaData.getTableName(ResultSetMetaData.java:166)

Could return a tablename like "CypherQuery" or else

Shading of all artefacts by design

I just discovered that all artefacts are shaded by default. I personally would prefer to not doing that to not conflict with potentially other Neo4J artefacts on the classpath. But to provide a single JAR that can be used by a SQL tool that is a nice feature.

This ticket is primarily to document the decision that was taken by you and why. :-)

In memory db with JDBC

It seems that with the new JDBC driver for Neo4j 3.0.x, the in memory database is not working:
jdbc:neo4j:mem:mydb
jdbc:neo4j:file:/home/user/neo/graph.db
as described in https://github.com/neo4j-contrib/neo4j-jdbc-2x.

Is there any plan to support these? They are very convenient for unit/integration testing.

Thanks

Improve HTTP driver URL validation error message

The error message when the JDBC connection string is not correct is weirdly phrased:

Caused by: java.sql.SQLException: JDBC url is not bad
    at org.neo4j.jdbc.http.HttpDriver.connect(HttpDriver.java:59)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)

Best would be to give a few examples of correct connection strings.

Possible bug: possible HTTP connection pool exhaustion

https://github.com/fbiville/liquigraph/issues/82 reveals that for the last Liquigraph changeset insertion into Liquigraph history graph, the main thread hangs forever because it forever waits for a connection from Apache HTTP connection pool (you can see the actual main thread dump in the original issue).

This happens with the legacy JDBC driver.

Maybe it happens with the new one as well.

To emulate Liquigraph behaviour, the idea would be to hold a single JDBC connection and commit several transactions during that time. The test input Liquigraph data roughly inserts ~100 nodes and connections (via MERGE) in ~30 transactions when the exhaustion kicks in.

I can share the input data privately if it helps.

ResultSet#close cannot be called multiple times

Instead, an exception will be thrown if called when it's already closed.
Therefore, the following code used to work with the legacy JDBC driver, won't work now:

try (Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery(query)) {
    // do something with resultset
}

Statement closes ResultSet first and ResultSet explicit close will fail.

Performance Test Numbers

relative numbers compare with neo4j-java-driver

  • large cypher statement with lots of results
  • many concurrent small queries

some absolute numbers for the publication

Squirrel error on connect

Error: Neo4j 3.0 Bolt: java.lang.UnsupportedOperationException: Method supportsStoredProcedures in class org.neo4j.jdbc.DatabaseMetaData is not yet implemented.

Test with Eclipse

Step 1: Create a new connection profile

  • Open the Database Developement perspective:

screen shot 2016-06-08 at 12 17 40

screen shot 2016-06-08 at 12 17 56

- Click on the icon **New Connection Profile**:

screen shot 2016-06-08 at 12 18 12

- Choose **Generic JDBC** (and optionally type "Neo4j 3.0 JDBC Bolt Driver" in "name" and "description" fields. Then click **Next**:

screen shot 2016-06-08 at 12 20 05

# Step 2: Create a new driver definition - Click on the icon **New Driver Definition**:

screen shot 2016-06-08 at 12 22 25

- Choose "Generic JDBC Driver" in folder **Name/Type** (and optionally re-type "Neo4j 3.0 JDBC Bolt Driver" in the "Driver Name" field):

screen shot 2016-06-08 at 12 22 46

- In Folder **JAR List**, click **Add JAR/Zip** and choose the new **Neo4j JDBC Bolt Driver**:

screen shot 2016-06-08 at 12 23 26

- In Folder **Properties** choose the **Driver Class**" by clicking the icon **[..]**:

screen shot 2016-06-08 at 12 24 21

- Choose **org.neo4j.jdbc.bolt.BoltDriver** as the Driver class:

screen shot 2016-06-08 at 12 24 32

- Set the **Connection URL** to "jdbc:neo4j:bolt://localhost" and the **User ID** to "neo4j", then click **OK**:

screen shot 2016-06-08 at 12 25 00

- Set the **Password** and click **Test Connection**:

screen shot 2016-06-08 at 12 25 20

- You should get **Ping Succeeded!** message (with your database online). Click **OK** and then **Finish**:

screen shot 2016-06-08 at 12 28 09

# Step 3: Test the connection (match and create) - Open an **SQL Scrapbook** and execute your statement (i.e. **match (n) return n**):

screen shot 2016-06-08 at 12 31 47

- Create statements should work as well:

screen shot 2016-06-08 at 12 35 48

as you can see on the neo4j browser:

screen shot 2016-06-08 at 12 36 41

Squirrel error on 2nd connect (after disconnect)

org.neo4j.driver.v1.exceptions.ClientException: You cannot begin a transaction on a session with an open transaction; either run from within the transaction or use a different session.
at org.neo4j.driver.internal.InternalSession.ensureNoOpenTransactionBeforeOpeningTransaction(InternalSession.java:196)
at org.neo4j.driver.internal.InternalSession.ensureConnectionIsValidBeforeOpeningTransaction(InternalSession.java:167)
at org.neo4j.driver.internal.InternalSession.beginTransaction(InternalSession.java:135)
at org.neo4j.jdbc.bolt.BoltDatabaseMetaData.(BoltDatabaseMetaData.java:40)
at org.neo4j.jdbc.bolt.BoltDatabaseMetaData.(BoltDatabaseMetaData.java:54)
at org.neo4j.jdbc.bolt.BoltConnection.getMetaData(BoltConnection.java:80)
at org.neo4j.jdbc.bolt.BoltConnection.getMetaData(BoltConnection.java:34)
at net.sourceforge.squirrel_sql.fw.sql.SQLDatabaseMetaData.privateGetJDBCMetaData(SQLDatabaseMetaData.java:1926)
at net.sourceforge.squirrel_sql.fw.sql.SQLDatabaseMetaData.supportsSchemasInDataManipulation(SQLDatabaseMetaData.java:339)
at net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectInfo.generateQualifiedName(DatabaseObjectInfo.java:197)
at net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectInfo.(DatabaseObjectInfo.java:77)
at net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTreeModel$RootNode.createDbo(ObjectTreeModel.java:381)
at net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTreeModel$RootNode.(ObjectTreeModel.java:376)
at net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTreeModel.createRootNode(ObjectTreeModel.java:271)
at net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTreeModel.(ObjectTreeModel.java:87)
at net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTree.(ObjectTree.java:125)
at net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTreePanel.createGUI(ObjectTreePanel.java:906)
at net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTreePanel.(ObjectTreePanel.java:131)
at net.sourceforge.squirrel_sql.client.session.mainpanel.ObjectTreeTab.getComponent(ObjectTreeTab.java:83)
at net.sourceforge.squirrel_sql.client.gui.session.MainPanel.addMainPanelTab(MainPanel.java:202)
at net.sourceforge.squirrel_sql.client.gui.session.MainPanel.(MainPanel.java:109)
at net.sourceforge.squirrel_sql.client.gui.session.MainPanelFactory.createMainPanel(MainPanelFactory.java:27)
at net.sourceforge.squirrel_sql.client.gui.session.SessionPanel.createGUI(SessionPanel.java:466)
at net.sourceforge.squirrel_sql.client.gui.session.SessionPanel.initialize(SessionPanel.java:116)
at net.sourceforge.squirrel_sql.client.gui.session.SessionInternalFrame.createGUI(SessionInternalFrame.java:123)
at net.sourceforge.squirrel_sql.client.gui.session.SessionInternalFrame.(SessionInternalFrame.java:53)
at net.sourceforge.squirrel_sql.client.gui.WindowManager.createInternalFrame(WindowManager.java:405)
at net.sourceforge.squirrel_sql.client.mainframe.action.ConnectToAliasCommand$Runner.run(ConnectToAliasCommand.java:394)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at net.sourceforge.squirrel_sql.client.Main$1.dispatchEvent(Main.java:99)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:109)
at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:184)
at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:229)
at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:227)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:227)
at java.awt.Dialog.show(Dialog.java:1084)
at javax.swing.JOptionPane.showOptionDialog(JOptionPane.java:869)
at javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:666)
at javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:637)
at net.sourceforge.squirrel_sql.client.session.Session$3.run(Session.java:1054)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at net.sourceforge.squirrel_sql.client.Main$1.dispatchEvent(Main.java:99)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

JMH in provided scope

I expected JMH to be in test scope but found in it provided. Maybe there is a reason for that?
I also dislike the fixing to a scope in dependencyManagement but that is maybe just me.

Test with OpenOffice

Step 1: Adding driver jar to OpenOffice

PLEASE NOTE: It has been tested on MAC OS X El Capitan 10.11.5

  • Open OpenOffice 4.1.1 (4.1.2 has a known bug with java: see OO forum here and release notes here)
  • Open OpenOffice \ Preferences menu
  • In the Options - OpenOffice popup window, select in the tree OpenOffice > Java
  • Choose Java Runtime (if more than once)
  • Click on the button Class Path button
  • Click on Add an archive and select the JDBC driver

screen shot 2016-06-11 at 17 18 35

screen shot 2016-06-11 at 17 19 21

screen shot 2016-06-11 at 17 19 32

# Step 2 : Create a Neo4j database - Create a new database and choose the JDBC connection - Fulfill the datasource url and the driver class - Fulfill the username and test the connection - Save your new OpenOffice database

screen shot 2016-06-11 at 14 54 58

screen shot 2016-06-11 at 14 55 04

screen shot 2016-06-11 at 14 56 04

screen shot 2016-06-11 at 14 56 13

screen shot 2016-06-11 at 14 56 16

screen shot 2016-06-11 at 14 56 39

screen shot 2016-06-11 at 14 57 20

screen shot 2016-06-11 at 14 57 31

screen shot 2016-06-11 at 14 57 48

screen shot 2016-06-11 at 14 58 02

# Step 3: Make some queries - Click on `Queries` tab, and after on `Create a query in SQL mode ...` - The SQL editor should appears. To allow you to make some Cypher queries, click on the button `SQL` (otherwise OpenOffice try to make a SQL validation of your query) - Make a query and execute it !

screen shot 2016-06-11 at 16 43 46

screen shot 2016-06-11 at 16 43 50

screen shot 2016-06-11 at 16 56 39

screen shot 2016-06-11 at 16 56 40

screen shot 2016-06-11 at 16 56 44

# Known Issues - Arrays as a return column aren't working as _r.roles_ on the following statement:

MATCH (a:Person {name: "Tom Hanks"})-[r:ACTED_IN]->(m:Movie)
RETURN a.name, r.roles, m.title:

screen shot 2016-06-11 at 16 56 54

Squirrel SQL array values don't work

returned as nulll

actor.name                                r.roles  movie.title                               
---------------------------------------------------------------------------------------------
Tom Hanks                                 <null>   That Thing You Do                         
Tom Hanks                                 <null>   Joe Versus the Volcano                    
Tom Hanks                                 <null>   Sleepless in Seattle                      
Tom Hanks                                 <null>   You've Got Mail                           
Tom Hanks                                 <null>   Charlie Wilson's War                      
Tom Hanks                                 <null>   The Polar Express      

squirrel sql client version 3 7 1-1

Virtual column for bolt on node & relationship

Compute virtual column for nodes & relations can't be correctly implemented on a JDBC driver, because we will need to make a full scan on the result to compute the list of all column available (a result is a collection of static tuples).

For example if you make this query on the Movie graph MATCH (n)-[r]->(m) RETURN n,r,m you will have on n some Movie & Person nodes, that haven't the same properties (it's the same for m & r).

Moreover, because Neo4j is schemaless, two Movie nodes can have different properties. So it's impossible to compute the ResultSet column, without to make a result full scan before.

From my POV, on complexe object, we need to return an Object : we can cast InternalNode, InternalRelationship & InternalPath to a POJO.

(it's related to #43).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.