Part 7b – Defining the App

At this point we just want to collect some data and store it.  There’s no real benefit to our crawler than before.  Rather than storing names in a flat file, we’ll store the names in Neo4j.

You might be asking, “Why bother with something so uninteresting?”  Good question.  My preference is to evolve code from the painful to the fun(ctional). Here I just want to make sure the pom file, configuration, and wiring are functioning.  Once part 7 is proven to work, we can set it aside, assured that it all works.

Entity Objects

In Spring Data we create certain POJOs to define what gets stored in the database.  In SQL there is normally a Data Definition Language (DDL) that corresponds to each of these POJOs.  Spring uses the POJO with it’s annotations to perform the Object Relational Mapping (ORM).

Neo4j’s data storage is rather simplistic compared to SQL.  Each node has an identity, type, and a collection of key/value pairs.  So the mapping between the POJO and the Node is pretty simple.  Actually, there’s no need to have the equivalent of a DDL.  Spring Data Neo4j looks at the class definition and creates a key/value pair for each member in the class.  (We’ll save the more interesting bits of relationships in a later lesson.)

There it is, a node definition in all it’s boring glory.  About all you need is @NodeEntity, @GraphId, and a no-argument constructor.

BTW, if you leave out the no-argument constructor you get a helpful exception.  The system starts up, the wiring is handled successfully, everything looks great until you try to save the NodeEntity.  Then you get this failure:

Missing @GraphId also produces a well-written message and it fortunately fails while initializing the system.

If you forget the main annotation, @NodeEntity, you’ll see during startup.

My goodness, I love @Repository.  It works for Neo4j, SQL, and Mongodb.  It works the same for all Spring Data modules.  This little interface pulls in all sorts of boilerplate code for CRUD operations and other things we’ll use later.

Here is where we connect our page crawler to the Neo4j repository.

Line 13: @Service tells the Spring framework that this is a service bean.  It will allow us to @Autowire it in our application level code.  There’s too much going on with this to document here.  Please see the Spring Documentation.

Line 19: @Autowired tells Spring to look for a PageRepository bean and add it to our service.

Line 38: This is where we create a Neo4j node and save it into the repository.

Last but not least is our application.  This is the top level of the program and as you can see, it’s designed to run from the command line and not as a web app or something.

Line 12 @SpringBootApplication  Somewhere you have to tell Spring where to find the starting point for the whole business.  Without this notation, Spring won’t build our beans.  You’ll get this odd message:

Somewhere in every Java application has to have ‘main()’.  This is true for Spring applications as well.  Being that we are making a command line program we have to specify it ourselves.  You can do what you want in there, except use any spring features.  Here we’ll just nuke the prior database while we are in development mode.

Line 26 is the launching point for the Spring Framework.

Line 13 is interesting.  We are actually defining our application bean here.  By implementing CommandLine runner, Spring will invoke the class’s ‘main()’ function after all the wiring is complete. When you watch the log of a Spring Boot application start, you’ll see it’s doing quite a big of work.  It all has to be done before our application can start.

In fact, you can have multiple @SpringBootApplication’s that implement CommandLineRunner and Spring will invoke them all.  I’m not sure why you’d want to, but it demonstrates what’s happening.

mvn spring-boot:run

Now that everything is live, let’s run our application.  The simplest way to do that is to use the Spring Boot maven plugin.  And now we get to see:

OK I’ll admin it, that was a whole lot of code and execution that really didn’t do anything.  However, it does pave the way for making our very interesting application.