Annotations, to do or not to do?

It goes without saying that annotations have been something of a massive boon to enterprise Java developers. In fact, we can safely say that it is one of the key weapons in a developer's arsenal when battling the complexity of various deployment descriptor and mapping specifications.

All that said though, is it possible that annotations can actually be considered a bad thing? Specifically, when should we use annotations and when should we avoid them? To focus on a basic example, consider the case of OR mapping, e.g. Hibernate or Entity Beans. Is there a case for not using annotations when mapping POJOs to database entities?

This is a question that has perplexed me all week, and I have spent an inordinate amount of time soliciting opinions for and against. To date, the case for the pro camp can be summarised as follows:

  • Annotations reduce configuration source files, and in a lot of cases mean that you no longer require XML configuration.
  • They provide transparency, so that it easy to observe a type's intended use from simply examining the source file
  • Annotations are self-documenting and condense a large amount of information into simple constructs

So far so good. When presented with these arguments though, the naysayers retort with the following:

  • Annotations add deployment context to classes. A POJO, which models a domain concept, arguably should be generic enough that it can be used throughout that domain (e.g. web application, GUI, mid-tier web-service, server side) without any reference to how it is persisted, or how it should behave in a particular context.
  • They can also introduce imports (library dependencies) which reduce the flexibility of the solution. For example, using OR annotations can introduce import statements into your code which you do not necessarily want. This not only reduces deployment scope, but also can interfere with design principles such as IOC and dependency injection.
  • Annotations can limit reuse. Now this is a fairly controversial one, and it took me a while to appreciate where the contributor was coming from. It is best appreciated with a very simple and straight to the point example: how do you cleanly map the same POJO to two different persistence stores using annotations? Or even better, how do you specify two different transaction contexts for the same service implementation using annotations?

This has all the makings of a controversial topic and will probably take on religious fervour as time goes on. In the meantime, please feel free to contribute your penny's worth to the debate!