DEV Community

Discussion on: Which contentious opinions in programming actually matter?

Collapse
 
elmuerte profile image
Michiel Hendriks • Edited

Using annotations for dependency injection and ORM is bad.

I prefer to write Spring XML configuration and Hibernate XML mappings instead of using annotations. In fact, I think using annotations are wrong as they will dictate the usage of the entities and thereby limitation their functionality.

Typical case of Data Objects (or POJOs in Java). They define the structure of data. If I would use annotations for persistence, I would also dictate how this and its sub-classes will be persisted. With this the data object no longer just defines the structure of the data, but also how to store it in case of ORM.

How it would get even worse if I also wanted to use that Data Object for data exchange. Should I also add annotations to instruct how to serialize it to JSON and/or XML? It will become a annotation hell.

Collapse
 
jillesvangurp profile image
Jilles van Gurp

I just got rid of hibernate and replaced it with JdbcTemplate and native SQL. Also replaced Java with Kotlin and I now have proper immutable entity classes without annotations, and a very simple DAO that queries the DB directly and does exactly what it says, and some simple service classes that use those with a TransactionTemplate. Not the first time I've done this on a project and hopefully the last time I need to be dealing with that.

IMHO class inheritance in general is something to avoid using and especially inappropriate with things that go in a database. It's called the object impedance mismatch for a reason: databases don't do inheritance and tables are not the same thing as classes. A good rule of thumb is that if you are not querying on it, there is no reason whatsoever for that thing to be a database column. So turning every class field into a column just creates a lot of complexity. Likewise, unless you are pulling it out separately, just shove it in text field in json form instead of creating extra tables. Apply the YAGNI rule with extreme prejudice and keep your schemas simple.

Regarding spring XML, yikes. This stopped being necessary with Spring v3 and as of v5 is not something you should be doing period. IMHO the proper way to do dependency injection is:

  • constructor injection only. That way the only thing you need to slap on your beans is @Component (and maybe a few @Value on constructor args). Even that is optional if you use Kotlin since you can declaratively specify your beans programmatically.
  • restrict use of @Autowired to things like controllers; as of spring 4.x there is no need to use @Autowired anywhere else. Having constructor injected beans means that spring already knows to autowire the constructor and allows you to use private final fields for your dependencies (no setters and getters needed).
  • use @Configuration for initialing things that are not spring beans or that need more complex setup (e.g. thread pools).
  • this completely removes the need for constructors that do work (other than setting private final fields). Constructors MUST not do work.
  • do not allow any .xml files to exist in your project. Just say know. I'm old enough to remember XML being a cool new thing. That's 20 years ago. I've not worked on a project where having XML around desirable or necessary in 10 years.