Annotations with Grails

December 29th, 2009 by Mike Leave a reply »

Recently I’ve been heads down writing a Grails Solr plugin for using Solr to index and search Grails domain objects, content and other documents. I share more on that in the next several day and weeks.  While doing so I implement annotations for the first time. In this example, I create an annotation type that lets you annotate a class property to specify a custom Solr index field name.  In usage it looks like this:

import org.grails.plugins.solr.Solr
class aDomain {
  @Solr(field="thedomainstitle")
  String title
}

The imported class above is actually an interface that defines the annotation:

package org.grails.plugins.solr
import java.lang.annotation.*

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Solr {
  String field();
}

This is fairly self explanatory. The name of the annotation is “Solr” and there is one propery field with a value of String. Almost identical to the java equivalent.

Now to access the annotation value for the field, you simply need the get a reference to the annotation and call the method on it defined above: field(). So with a bit of context below, I define an indexSolr() method for each domain class, loop through each property and check if there is an annotation of Solr defined for the field, if so I set the value of field() to the docKey which is used as the Solr field name for the property.

application.domainClasses.each { dc ->
  dc.metaClass.indexSolr < < { ->
    //.......
    application.getArtefact(DomainClassArtefactHandler.TYPE, delegate.class.name).getProperties().each {
      //.......
      def theField = delegate.class.declaredFields.find{ field -> field.name == it.name}

      if(theField.isAnnotationPresent(Solr)) {
        docKey = theField.getAnnotation(Solr).field()
      }
      //........
    }
    //........
  }
}

Powerful, yet simple.

This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.

14 comments

  1. BjoernKW says:

    Nice, will you share the plugin via grails release-plugin once it's done? It'd be really interested in that one because although Searchable is an awesome plugin having separate apps for serving content and search results is more scalable. I recently had problems with Searchable since it had to re-index 100,000 or so domain objects upon app startup which took like half an hour so Solr would have been a much better solution in that case.

    • Mike says:

      Yes, it will be released into the grails plugin repo. So what's important to you with regards to functionality?

      Thanks! Mike

      • BjoernKW says:

        It'd be great if the plugin automatically indexed every String field (or any other type that makes sense). Something like Searchable's components would be great too, e.g.:

        class Playlist {

        static hasMany = [songs:Song]

        static searchable = {

        songs component: true

        }

        }

        class Song {

        String title

        }

        which allows you to search for playlists by the songs it contains.

        It should bundle Solr and by default automatically fire up a Solr server upon app start but optionally allow you to use your own Solr server.

      • cease says:

        im also really interested in the solr plugin, if possible definitely submit article to dzone about it . thanks

  2. duc tung vu says:

    ability to configure multiple analyzer for multiple languages, for example, would be also very cool. Configurable on Field Level and Domain Level.

  3. Roshan Shrestha says:

    Can't wait for this plugin to be released!

    Will it be released under the Apache license?

    Thanks
    Roshan

  4. Mike says:

    Yes, it will be licensed under Apache 2.0

  5. Eduardo says:

    I wish your plugin had been available a few months ago!
    I used solr in my project but what I have not been able to figure out is: if your grails app and solr reside on the same Tomcat server, how do you make sure solr is up and running before you start making calls from your app?

  6. BjoernKW says:

    I haven't heard any news about the development of this plugin for quite some time. If you need any help just drop me a message. Having done some work with Solr before, I might be able to help.

    • Mike Brevoort says:

      Thanks for the nudge, been crazy busy and just keeps getting bumped. I started back up today a little and I'm going to try and spend an hour a day on it. I just want to get it to a place where I can release it with good docs and such. Definitely up for help after that!

  7. developer says:

    hi mike!
    i love your plugin :)
    but can you put in a protection for npe ?
    we are getting a npe on line 285 if SolrGrailsPlugin.groovy
    when clazzProp is null.

    if(clazzProp && clazzProp.isAnnotationPresent(Solr) && clazzProp.getAnnotation(Solr).asTextAlso()) {
    doc.addField("${prefix}${prop.name}_t", docValue)
    }

    vs

    if(clazzProp.isAnnotationPresent(Solr) && clazzProp.getAnnotation(Solr).asTextAlso()) {
    doc.addField("${prefix}${prop.name}_t", docValue)
    }
    would you mind posting an update with this fix?
    or would you mind we post a version .1.1 as a bug fix plugin version?

  8. Mike says:

    Thanks! I'll get a new release out this weekend. There are a few other fixes I need to get out there as well.

  9. Mike says:

    had a chance to do this now so I just released v0.2 which included your fix and another that occurred when using using java objects.

  10. developer says:

    you are pretty amazing mike :D thanks!

Leave a Reply

Powered by Web Design Company Plugins

Switch to our mobile site