Simple Blog Using jo4neo and Stripes

January 3rd, 2010 § 0

neoblog is a simple application I built to test drive jo4neo.  You are welcome to browse the code here for details not covered in this post. It demonstrates the feasibility of utilizing view tier objects to persist graph relationships.

neoblog with 3 posts

neoblog with 3 posts

Stripes, Struts, and other Java MVC frameworks all hinge off of a domain model expressed as Java Beans.  An obvious approach to integration with an embedded neo4j instance would be to convert view objects to nodes and relations at some stage.  This boilerplate code would need to be written for each class, and include conversion from objects to nodes and edges and vice versa.  Indeed, it’s perfectly reasonable to expect that there will always be an impedance mismatch between the view model and the graph it’s persisted to/manifested from, however, in some instances it might be possible for the view, it’s model, and graph to all share a single model or some subset thereof.

neoblog’s model consists of four primary classes; User, Post, Tag, and Comment.  After utilizing the blog tool to create a few posts, you’ll end up with a graph similar to this one:

A graph with two users, two posts, and two tags

A graph with two users, two posts, and two tags

Post is a good place to start as it’s directly related to the other three classes:

@neo(recency=true)
public class Post extends NeoBean
 {
	@neo private Collection<Comment> comments =
           new LinkedList<Comment>();
	@neo("hasTag") private Collection<Tag> tags =
           new HashSet<Tag>();
	@neo private User author;
	@neo private Date createdAt;
	@neo private String title;
	@neo private String content;

As you can see it’s all straight ahead java except the @neo annotations. I have extended a base class, however, this is not a requirement placed on you by jo4neo. At the field level we’re indicating to jo4neo that we’d like it to create a relationship between the post and another entity, or perhaps just apply a node property. Primitive types including java.util.Date are treated as Node properties. Complex types (User, Tag, Comment) are treated as nodes within the graph.

Now let’s consider what needs to happen when a user creates a new blog post.

  1. The post must be associated with the logged in user (relationship between the post node and user nodes).
  2. The post along with it’s title, content must be persisted in the neo graph store.
  3. The post must be associated with any tags.

Nothing too complex, however, the actual code necessary to accomplish this might surprise you:

@HandlesEvent("save")
public Resolution post() {
	Transaction t = pm().beginTx();
	try {
		post.setAuthor(context.getLogin());
		for (String tagname : splitTags())
			post.addTag(forName(tagname));
		post.save();
		t.success();
	} finally {
		t.finish();
	}
	return new RedirectResolution(HubAction.class);
}

PostAction.java

Finding Nodes

The code for saving a post is brief, however, you may have noticed some places where complexity was delegated elsewhere.  For instance, context.getLogin() returns the current user.  At some point, the code has queried the neo database, checked the user’s credentials, and placed the user information into session.  jo4neo is able to index entities by one or more of their properties, provided they’ve been annotated appropriately.  For the neoblog app, I’ve annotated User.screenName as being indexed:

public class User extends NeoBean{

	@neo(index=true)
	public String screenName;
...

@neo(index=true) causes the screenName field to be indexed. Now we can take a look at how a user is authenticated and placed into session:

User user = new User();
user = pm().
   find(user).where(user.screenName).is(screenName).result();
if (user==null || !e.equals(user.getEncryptedPassword()) )
   errors.addGlobalError(new LocalizableError("loginmsg"));
else
   context.setLogin(user);

LoginAction.java

This is an example of utilizing jo4neo’s “fluent” query api. There’s no mystery here. It serves one simple use case; query the index for node matching a given value. There is no wildcard support or free text indexing, and you cannot combine multiple query clauses. “What?” you may ask, “you mean it’s not SQL or some redundant manifestation of SQL in a different syntax?”. To which I reply, nope, it’s not SQL…it’s just a way to find a node via a given key. Key lookup with a pretty api. neo4j is powerful, and yet we find ourselves needing to enter the graph at certain specific points. In this case we want to enter the graph at a particular node representing a particular user, given their authentication information. jo4neo makes it fairly simple. First you annotate a bean, and 2nd you find it using a key value.

Tagged: , ,

§ Leave a Reply

What's this?

You are currently reading Simple Blog Using jo4neo and Stripes at The Web Semantic.

meta