Part 2 – Setting up some Spring Queries

What about querying our Mongo database? As we saw in Part 1, it’s really easy to get the system up and running, but it doesn’t do much.  The next evolution is to create queries for specific records.  There are two methods to build queries with Spring Data.  One, to create the query in an annotation.  Two, to create the query with magic method names.  We are going to explore this second method in this post.

This method is very limiting and falls short of many business needs.  You simply can’t express rich semantics in a method name.  That said, it’s super convenient for many document-based applications.

Problem: we want a list of all the people over 77 years old.

Let’s expand our Person Repository:

 List<Person> findByAgeGreaterThan(int age);

Remember PersonRepository is an interface, not a class.  So we are not going to write any code.  The question is, who will write this code?  Spring Data will write the code when the system fires up.  Yeah I know, magic.

Spring looks for methods with “findBy” defined in the interface.  Then it goes to work:

  • “findBy” – signals Spring to create a query
  • “Age” – looks for an attribute of “Person” called age
  • “GreaterThan” – prepares a query to select a value “>” some provided value
  • “int age” – The first parameter passed to the method is matched to the first parameter after “findBy”.

Now we can use this function to find our older friends:

Making Mistakes

I know it looks like too much magic, but it is fine once you get into it.  Still, you would like to understand what’s happening a little better.  Sometimes it is good to see what goes wrong to better understand how something works.  Let’s look at some errors to see how this plays out.  First, we’ll add an extra parameter to our search method.

This doesn’t generate an error at all, the “numberOfChildren” parameter is simply ignored.

Next, we’ll change the name of the parameter to see if that is important.

Likewise, this version doesn’t cause any trouble, because the name of the parameter isn’t magic.  It’s only the method name that counts.  What if we remove the parameter all together?

The error message is very nice and direct: “Invalid parameter index! You seem to have declare too little query method parameters!”  Also, this error does not occur at compile time, or at initialization.  This error happened at runtime, when the method was invoked.

Let’s see if we can make it fail at startup time.

This time we misspelled “Age” as “Agnes”.  Of course there is no Agnes property.  Even if no one called “findByAgnesGreaterThan(int age)” the system will fail and it fails at startup time.  Spring cannot create the repository at all.

Sorting the results

Another common need is sorting the results.  This is done by adding “OrderBy” at the end of the method name.  For example:

This is very simple and does exactly as you would expect.  We can now list all our friends over a certain age, alphabetically.

There are some other operations possible using this method, but not many.  To express more complex queries, we are going to need something else.  That is the subject of our next part.