In Java, annotations are currently all the rage.

Personally, I think that not all annotations are created equal. Some are quite useful, while others make no sense to me at all. It seems that annotations are a golden hammer, and everything is a nail lately.

Annotations such as those for JUnit make a lot of sense - like @Test - straightforward, useful, and no undue coupling - this is a JUnit annotation, being used in a JUnit test. The Junit test is, and always will be just that - a JUnit test. All is well with the world.

Consider persistence annotations, though, such as those for Hibernate and/or JPA.
To me, these are counter-productive. The whole idea behind Hibernate and JPA is to add persistence to POJOs - "Plain Old Java Objects". But once you add persistence annotations to a POJO, it ceases to be a POJO!

There are actually two coupling issues here:

1. The POJO cannot be compiled without the library that provides the annotation. This is not an issue for a JUnit test, as it will only ever be used with JUnit. But why would I want to inextricably tie a POJO domain object to Hibernate or JPA? Suppose, for instance, that I want to use the POJO with GWT, or package it into a jar file, and give it to someone who wants to consume it from a web service. In the latter case, this would require the consumer to have the Hibernate/JPA jar files and their dependencies. In the former case...well, it's just not possible.

2. With persistence annotations in a (formerly) POJO domain object, if I want to change some aspect of the database schema, like perhaps changing a table name or a column name, I would have to change and recompile the Java code as well. It seems to me that this is the definition of "tight coupling", and a bad idea.

So, I prefer to steer clear of annotations like this, keep my Hibernate persistence details in hbm.xml files, and keep my POJOs as POJOs. Fortunately, even with Spring integration of Hibernate, this is easy to do.