The Dark Side of Java Annotations

More and more tools are taking the train to Java Annotations. Most of them to ease code and xml descriptors generation. Look at XDoclet. It was supporting dozens of tools way before the introduction of metatadata annotations in Java 5 with JSR 175.

The main reason why we, developpers, like to use these annotations is that they help us concentrate on the Business logic, not on the framework, not on the proxies, implementations, descriptors, pick any… Code becomes clearer, safer and faster to write.

However, we have to be very careful on what we are using these annotations for. We shouldn’t express runtime information here. By runtime information, I mean data that one could change to adapt to its runtime environment. Let’s take an example : It’s ok to say which fields of you classes have to be saved in the database. It’s not ok to say which table to use. If we put the table name in the annotations, we’ll have to recompile and redeploy the application to change the table names. With standard XML descriptors and a dynamic implementation of our framework, we can change only the xml file.

If the future is to put everything in the code with annotations, maybe we should give the sources to the application server and let it choose between recompile or impact changes in the annotations.

11 thoughts on “The Dark Side of Java Annotations”

  1. your point is correct – annotations should be used wisely (that is true for any technology), but the conclusion is wrong.

    Using annotations does not mean it cannot be overwritten by something external – like a xml descriptor or similar.


  2. You’re right, the annotations can generate a xml descriptor which can be changed dynamically. However, it means that one has to know what files the annotations will generate. If I need to know the syntax of the generated xml files and if there is a risk that the xml file is not synchronized with the annotations, why use the annotations in that case ?

  3. Why not to use annotations and overwrite it if there is xml descriptor?
    More or less the same way as we have ejb-jar.xml and jboss.xml?

  4. Using annotations to specify the table name is correct when you create the schema automatically at compile time. Then the only way to change the schema is to change the annotation, which necessitates a recompile in any case. Unless trying to work with external schemas outside of one’s control, it is a best practise to design the code iteratively, and derive the schema thereof rather than designing the full schema upfront and then trying to implement persistence to fit.

  5. The best solution is to put all the default stuff in the annotations. The default table names, the default column names, etc. From my experience deployments will rarely diverge from such defaults.

    Then use an XML file to override the defaults as necessary. There’s no problem with the XML becoming out-of-sync with the annotations because the XML contains only the diffs. This allows the XML to be compact yet completely flexible.

  6. David-,
    It is OK to put in annotations references to an “abstract schema” as a layer of indirection to the real DB table. It is not OK to ask the sys. admin (who probably does not know XML and Java) to edit raw XML deployment descriptors. Rather – provide a UI tool to map the abstract schema to table(s)

  7. I think that argument is double-edged, you have the same problem with any XML file regardless of whether it was initially generated from source or not – that is, you need to maintain it in conjunction with the original source AND know where it is. The question is not why use annotations, but, why use XML?

  8. You’re right that annotations shouldn’t replace configuration files. Many Java applications ship with .properties and .xml files embedded in a JAR, with no intention that they be changed when the application is deployed. Many of these files can and should be replaced by annotations or straight Java code.

  9. I think that David raised a good point :
    1) annotations are an easy way to do MDA by introducting metadata directly in the code
    2) annotations cannot contain the whole metadata

    In fact, a distinction should be made, as in MDA, between :
    - PIM (platform independant model) : eg persistent fields, logical type of persistent fields, …
    - PSM (platform specific model) : eg column names, oracle 8 exact sql type mapping, …

    Some projects will be able to define a rule to compute those column names and mapping, some won’t

    Some will be able to generate hibernate mapping files, some will have to manually edit them.

    Strangely, those hibernate mapping files allow… annotations (called meta) :-)

  10. I found an interesting opint in jax rpc 2.0 public draft :

    Java Annotations In conjunction with JAXB[10] and JSR 181[13], the specification will define a set of 4
    standard annotations that may be used in Java source files to specify the mapping from Java artifacts 5
    to their associated WSDL components. The annotations will support mapping to both WSDL 1.1 and 6

    WSDL 2.0. 7
    WSDL Annotations In conjunction with JAXB[10] and JSR 181[13], the specification will define a set of 8
    standard annotations that may be used either within WSDL documents or as in an external form to 9
    specify the mapping from WSDL components to their associated Java artifacts. The annotations will 10
    support mapping from both WSDL 1.1 and WSDL 2.0.

    In this case both java AND conf file are anotated (like my example java AND hibernate)

    1-Each side (java or conf) must be complete (i.e. could generate the front of the other side)
    2-The core point is : are the conf files correctly splited. In hibernate, cfg.xlm files contain database configuration, and hbm.xml files contain object/relationnal mapping (including column names). This is fine for some cases, and not for others.
    In the later, the hibernate files have to be generated from other sources, and so on.

Comments are closed.