Maybe annotations aren't that bad after all

Two years ago I blogged about annotations and that I considered them to be A Bad Thing. It seems I will have to eat my words. I am actually using them to the hilt in my current project.

We use JPA and specific Hibernate annotations on our entities. See for example these annotations on a field:
@OneToMany(mappedBy = "changePlan", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@org.hibernate.annotations.Sort(type = org.hibernate.annotations.SortType.COMPARATOR,
    comparator = PositionableComparator.class)
private SortedSet steps = new TreeSet(new PositionableComparator());

We use JUnit 4 and Spring 2.0 annotations on our test classes:
@ContextConfiguration(locations = { "/spring/ad-core-context-common.xml",
    "/spring/ad-core-context-test.xml", "/spring/ad-cli-context-test.xml" })
@TransactionConfiguration(defaultRollback = true)
@TestExecutionListeners(value = { TransactionalTestExecutionListener.class,
    DependencyInjectionTestExecutionListener.class })
public class AutomatedDeploymentServicesComponentTest {

And we even introduced our own annotation to describe the fields in our database:
@ConfigurationItemProperty(required = true,
    description = "Name of the WebSphere Application Server. Valid examples; MyServer, Server01")
private String name;

It turns out that while annotations may clutter your code and may bind your code to specific framework etc., they do have a few useful properties:

  • Annotations relieve you from having to write (more) XML metadata, such as Hibernate mapping files and Spring context files.
  • Annotations allow people reading the code to immediately see the metadata, without having to hunt for it in other files.
  • Annotations are automatically moved when you refactor code.
  • Annotations are automatically removed when you remove code.
  • When you rename a class or a field, there is no need to change the external metadata.

In short, annotations reduce the distance between your code and its metadata. And that is A Good Thing. 😉

And as for the disadvantages I mentioned in my blog:

  • Needing the annotation classes to compile your code doesn't seem so bad. Why wouldn't you have the frameworks you use in your classpath?
  • So the syntax isn't that great? It's not as bad as XML. And at least Eclipse provides nice syntax colouring.
  • Most of the configuration data stored in annotations is pretty static, so recompiling when it changes it not that bad. For example, how often do you remap your entities without also releasing a new version of your software?
  • Using the same classes with multiple configurations is still a problem. For example, JPA also has the orm.xml file to supply/override the entity configuration. But that is not a generic solution.

So I guess the real conclusion here is that broad generalizations may embarrass you later. As always, It Depends.

Comments (5)

  1. Erik Pragt - Reply

    January 19, 2009 at 11:19 pm

    Yes, this is much, much better than XML....*kuch* Aren't your examples actually the reasons NOT to (over) use them? And why should your code be bothered with database field descriptions? (note, btw, that this level of documentation is usually wrong anyway after a couple of months. Documentation doesn't really refactor well....)

    Instead of using XML, you are probably also using nested annotations (since you are using JPA...). I fail to see how much better that is?

    I also don't agree with the broad generalizations. For example, my broad generalization is that I think that Dutch code is bad. Always. Though I may think otherwise in 2 years or so 😉 (but I expect not to.....)

  2. Vincent Partington - Reply

    January 20, 2009 at 9:58 am

    The database mapping is interesting for the people working on the code, so that's why I think it's nice that that metadata is close to the code. But yeah, the syntax of annotations isn't that pretty either, especially without the syntax colouring of Eclipse.

    So I agree that me saying that annotation syntax is "not as bad as XML" is a broad generalization and as such not too subtle. We might actually agree that both XML and annotation syntax is ugly. 😉 But what other statement do you think are broad generalizations?

    But I don't understand your statement about "this level of documentaton is usually wrong after a couple of months" and that is doesn't refactor well. The things in the annotations are not actually documentation but part of the system (except for the description field of @ConfigurationItemProperty annotation), and, as I mention in my blog, they do refactor quite nicely. A lot better than external XML files at least.

  3. Erik Pragt - Reply

    January 20, 2009 at 10:28 am

    Hi Vincent, thanks for the reply. I totally agree that both XML and annotations are ugly (and since I'm a big fan of Grails, I even think that DSL's to do this are ugly), though I don't think there are much cleaner solutions to do this mapping, unfortunately.

    What I meant about the documentation part, is that when you have documentation on a that specific level like field level, it's easy to let the documentation get out of sync with the current implementation. For example, a field might be called 'firstName', but after a month or two, you decide to let it contain the full name, so you rename it to 'fullName'. Then there's a big change the documentation will still mention something like: "The field which contains the person's first name". So, in your example, I think the variable name is suboptimal: if the name contains the name of the Websphere Application Server, call the field: 'websphereApplicationServerName'. This name says it all, plus it's easy to refactor (and since the name is the documentation, the documentation will be updated automatically) when, for example, the name could also contain a weblogic application server.

  4. Vincent Partington - Reply

    January 20, 2009 at 10:46 am

    Aha, you were talking about the description field of @ConfigurationItemProperty annotation. The field is called name because it is actually a member of the WebSphereServer class. So calling it websphereApplicationServerName would be kinda redundant.

    The user documentation would be more resistant to change (for example, if the class were to be renamed) if it were more generic like "Name of this configuration item", but then it would be less helpful to the end user.

    One advantage of having the documentation here instead of in a separate document is that the chance that is noticed when the field is moved or renamed is bigger, I think.

    And then we're back at my liking annotations for their proximity to the thing they are metadata (or documentation) for. 🙂

  5. Walkie Talkie - Reply

    November 25, 2010 at 11:51 am

    you write in a lucid manner and I have no difficulty to understand what you have said, even though I am a novice.

Add a Comment