This is what happens when people try to add too much "magic." It's a side effect of many things, the most obvious being the lack of the language support for expressing these types of things. It is the same sort of issue that plagued C++ with the ability to override operators while limiting which operators could be overridden. This kind of annotation hell is indicative of the inflexible and unextensible nature of Java.
By the way, I'm not hating on JVM languages. Both Scala and Clojure have a means to handle this issue with grace and without sacrificing the readability of the code.
I don't know, annotations are what you make of them and can be abused like anything else. I miss being able to do things like this when I'm not working on Java code
>This kind of annotation hell is indicative of the inflexible and unextensible nature of Java.
This line made me think a lot, it reminded me of this amazing talk by Guy Steele[1], an absolute must for every language developer (or software developer in general, really). It's ironic that he's mostly referring to Java the language itself when he talks about "flexiblity" and "growing the language", where ~10 years later we all know that Java is becoming a messy inflexible deprecation hell. Still a solid talk nonetheless!
To me, it looks like this happens when you can't easily build new things by reusing old ones (in this case annotations). If a developer was able to combine multiple annotations into one easily, they would be better able to express themselves in the typical cases
sketchy example:
@SerializableTo(name='orders', exclude='json');
@BelongsTo('customer')
private List orders;
then @BelongsTo is implemented using @ManyToMany, @Fetch, @JoinTable.
Can you do that with annotations in Java without rewriting them from scratch?
I don't get what the problem is here. Each of those annotations modifies the field somehow - if you take one out, then you get less functionality. Is the problem really "my code does too much"? He says:
> I can't even see the damn property under this bloat.
To me, all those annotations are the property, so you're seeing exactly what you need to see. You could put it all in an XML file if you really want to, but they're still going to be there, and you'll still have to read around them.
Actually, the property is just a value of a type having a name. The property has the responsibility to hold and provide access to its value. It's definitely not the properties responsibility to know how it is being stored in a database, this is a so called 'mapping'. If you'd change the table name, you should not have to change the property, but the mapping. Another important aspect is readability.
and maybe has_many or belongs_to on customer for the inverse.
and the xml translation is pretty transparent too, under the hood it's not very different, but it's a lot simpler to write/read. It is possible to get rid of a lot of this sort of boilerplate by adopting conventions about naming etc and then specifying the exceptions where necessary. I do think these would be better moved to methods rather than being object attributes like this (which read like a translation of XML into text annotations on the object, rather than convention + code when convention isn't enough).
I agree with the author that the Single Responsibility Principle is being violated with all these annotations, but I disagree that the resolution is to move the annotations into hbm.xml files (or similar).
I would, in the limited example given, prefer to have a 'storage' POJO (annotated with the hibernate annotations), and an 'API' POJO (annotated with the JSON and XML perhaps).
Then it seems to make sense that if you're changing the underlying storage you would update the storage POJO.
I very rarely want to return the exact object as stored in my database to the API layer - there's business logic and the like that needs to be applied, and transforming the object into something the next layer requires means you can generally implement tighter interfaces.
I don't think that style of code is wide-spread in the real world; this feels like a total straw-man. Annotations are normally much better than any alternative we've come up with (e.g. XML), but the extreme case where you use every annotation is less appealing.
To me, this feels like a serious code-smell. Do you want to link your API data representation (XML/JSON) with your DB representation? Why does your JSON have a different structure to your XML?
If I'm wrong (it happens) and this is wide-spread, IDEs could implement folding for annotations to make this more manageable. The XML annotations would fold together, the JSON together, the ORM together. Or we could have different views, like LightTable. There just aren't that many sets of annotations.
By the way, I'm not hating on JVM languages. Both Scala and Clojure have a means to handle this issue with grace and without sacrificing the readability of the code.