An annotation nightmare
beabetterdeveloper.com
beabetterdeveloper.com
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.
>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!
@GET
@Path("/users/{userId}")
public Page userPage(@PathParam("userId") UUID userId, @QueryParam("blub-filter") String filter) {
...
}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 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.
@JoinTable(
name = "customer_order",
joinColumns = {
@JoinColumn(name = "customer_id", referencedColumnName = "id")
},
inverseJoinColumns = {
@JoinColumn(name = "order_id", referencedColumnName = "id")
}
)
In rails, this would be: belongs_to :customer
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 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.
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.