One of the important changes that has occurred over the last 5-10 years is that open source databases such as Postgres have become remarkably mature.
When Java developers started to use Object Relational Mappers, there were several important benefits that we cared about:
- Database independence
- Database specified in Java-land (XML config files or annotations)
- Automatic schema updates
In my opinion, the value of the benefits provided in the list above has declined over time. The consequences of this are non-obvious.
Consider why companies might switch databases. I have seen this happen a number of times during my career. Here are the top reasons for migrating away from your current database.
- Licensing Cost (vendor decides to raise prices)
- Feature limitations (current database sucks at something important)
- Seeking different approach entirely (such as moving to Mongo)
If you are using a database like Postgresql, MariaDB, or Mongo, you are unlikely to switch away from that database on the basis of licensing cost alone.
You may have hosting costs, but, generally, this is money well spent.
If you have a relational model, and you chose Postgres, then your chances of migrating away from Postgres because of feature limits are also fairly slim. The only reason that you might make a switch is because you want a different model entirely, such as a Key Value store, like DynamoDB; or a Document Store like Mongo.
In general, if you have decided to build your app on a relational model, and you chose Postgresql, then the next question is: why work at arms length?
JPA is designed to keep you 'e' the database. With JPA, you define your model using Java classes (generally). This database-neutral model of access does bring with it some important costs, in terms of how you express queries and other database operations.
I continue to believe that for apps with a significant relational model, JPA is old school. If you are using JPA, then there is a good chance you have the rest of the Spring stack, which means Repositories.
JPA is the new COBOL. I am not making this stuff up. Look at the trend:
The modern way to handle database access, IMHO, is to:
- Manage your relational model using native SQL.
- Adopt a migrations facility like Flyway or Liquibase.
- Reverse engineer your model into a data access library that enables highly expressive, native queries, like JOOQ.
Getting all of this working can take some work. Consider how useful it is to have the following:
- Direct access to views and stored procedures within your service tier
- No JPAs
- No Repository boilerplate
And when you change the schema? Here is what you do:
- Write a new migration, test it locally, and then apply it in production
- Re-generate your Data Access Library, and make appropriate changes in your Service tier.
If you are using a typesafe data access facility like JOOQ, then your IDE/compiler will help you find any problems introduced by the most recent schema update.