Today I released the first version of the Neo4j Grails plugin. The plugin’s goal is to provide an alternative approach for storing Grails domain classes: in the Neo4j database.
Neo4j is a relative new and very interesting approach for persitence in a non-SQLish way. Neo4j is a graph database and uses the concept of
Nodes
A node is the basic building block. It normally represents a “something”, a entity.
Relationships
Relationsships are associations between nodes. Each relationship connects exactly two nodes. Relationsships have a direction: incoming, outgoing or both.
Properties
Each node or relationship might contain a set of properties. A property has a name (String) and a value (primitive datatype). Complex value are not allowed for properties.
This is completely different from the SQL approach. There are no tables, columns, indexes, and other stuff we’ve dealt with for years. Somewhat crucial is the way how to organize the node space. Neo4j gives some advice here.
Neo4j itself uses the AGPL license, the plugin is licensed the WTFPL.
How the plugin works
Using Groovy’s metaprogramming capabilities, the basic CRUD-methods list, save, get and delete are added transparently to each domain class. In addition, each domain instance gets a ‘node’ property referencing the associated Neo4j Node.
For each domain class a subreference node is created related to the reference aka root node. Each domain instance holds a relation to it’s subreference node. For non-primitive properties, either relations to other domain nodes are used or they are converted to strings using the Spring’s PropertyEditor approach.
Aside from this, the plugin starts up and closes the Neo4j database. The database’s path is configured using the grails.neo4j.storeDir property in Config.groovy.
Howto use the plugin
The plugin can be used transparently in a Grails application. The only thing you have to do is to remove the hibernate plugin and install the neo4j plugin:
grails uninstall-plugin hibernate
grails install-plugin neo4j
Add some domain classes and controllers with scaffolding – they should work.
What currently works
- basic CRUD operations on domain classes
- one-to-one, one-to-many, many-to-one and many-to-many relations of domain classes
- the current implementation supports scaffolding
- Together with the acegi plugin, you can store your user, role and requestmap information in neo4j. Since the default UserDetailsService relies on Hibernate’s SessionFactory you have to use a custom UserDetailsService to get this working.
What’s still missing (and hopefully will be added in upcoming releases)
- currently all constraints are ignored
- only a subset of the domain methods are implemented
- dynamic finders have only a very basic support: just DomainClass.findBy[Property](value) works so far
New planned features
- SVG controller/views to display the complete object graph, just like Neoclipse does.
- Gant scripts for automatically snapshotting and restoring the database
- Criteria queries implemented using Neo4j traversers
Any feedback is appreciated.
9 replies on “Neo4j Grails Plugin”
[…] Dieser Eintrag wurde auf Twitter von Peter Neubauer und darthvader42 erwähnt. darthvader42 sagte: just release the initial version of the #neo4j #grails plugin: http://bit.ly/d74uQ […]
[…] reply to my today’s annoncement of the Neo4j Grails plugin, @StigLau asked me to provide an example for using the Neo4j Grails […]
[…] This post was Twitted by groovyblogs […]
[…] This post was Twitted by groovytweets […]
[…] This post was Twitted by grailspodcast […]
Very nice, worked like a charm.
The next question is; do you have an example of what the code has to look like when you write it in “grails console” or grails-app/conf/BootStrap?
My test:
new Car(colour:”Blue”).save()
Results in:
Exception thrown: No transaction found for current thread
org.neo4j.api.core.NotInTransactionException: No transaction found for current thread
at org.neo4j.impl.persistence.PersistenceManager.getCurrentTransaction…
I believe this has to be done in the context of a transaction, and Grails doc does not tell me how.
Every call to the Neo API has to be done within a transaction. During normal requests the plugin uses a similar approach to Hibernate’s OpenSessionInView with the difference that it opens a Transaction. This works fine so far, but I think there might be a better solution. Regarding your question, here’s a Bootstrap.groovy from one of my internal projects:
This is more elegant, does it work too?
http://grails.org/doc/1.1.x/ref/Domain%20Classes/withTransaction.html
withTransaction is part of the domain class extensions being provided by the persistence plugin. The Neo4j plugin currently does not implement this.