Imagine having a tool that can automatically detect if you are using JPA and Hibernate properly.
Hypersistence Optimizer is that tool!
I like integration testing. As I explained in this article, it’s a good way to check what SQL queries are generated by Hibernate behind the scenes. But integration tests require a running database server, and this is the first choice you have to make.
Using a production-like local database server for Integration Testing
For a production environment, I always prefer using incremental DDL scripts, since I can always know what version is deployed on a given server, and which scripts required to be deployed. I’ve been relying on Flyway to manage the schema updates for me, and I’m very content with it.
On a small project, where the amount of integration tests is rather small, you can employ a production-like local database server for testing as well. This is the safest option since it guarantees you’re testing against a very similar environment with the production setup.
Another option is to choose an in-memory database for integration testing. There are many in-memory databases you could choose from: HSQLDB, H2, Apache Derby, to name a few.
I’ve been using two in-memory schema generation strategies, both of them have pros and cons, which I am going to explain as follows.
Making use of hibernate.hbm2ddl.auto=”update”
When using Hibernate, the database schema generation can be customized using the hibernate.hbm2ddl.auto configuration property.
The simplest way to deploy a schema is to use the update option. This is useful for testing purposes. I wouldn’t rely on it for a production environment, for which incremental DDL scripts is a much better approach.
Let’s start with the JPA configuration, you can found in the persistence.xml file:
Bitronix is a very reliable stand-alone JTA transaction manager. When you are developing Java EE applications, the Transaction Manager is supplied by the Application Server. However, for Spring-based projects, we need to employ a stand-alone Transaction Manager if we need to use XA transactions.
When using JTA, it’s not advisable to mix XA and Local Transactions, since not all XA Data Sources allow operating inside a Local Transaction. Unfortunately, as simple as this DDL generation method is, it has one flaw which I am not too fond of. I can’t disable the allowLocalTransactions setting since Hibernate creates the DDL script and updates it outside of an XA Transaction.
Another drawback is that you have little control over what DDL script Hibernate deploys on your behalf, and in this particular context I don’t like compromising flexibility over convenience.
If you don’t use JTA, and you don’t need the flexibility of deciding what DDL schema would be deployed on your current database server, then the hibernate.hbm2ddl.auto=”update” is probably your rightful choice.
Flexible schema deploy
This method consists of two steps. The former is to have Hibernate generating the DDL scripts, and the latter is to deploy them in a customized fashion.
Based on my book, High-Performance Java Persistence, this workshop teaches you various data access performance optimizations from JDBC, to JPA, Hibernate and jOOQ for the major rational database systems (e.g. Oracle, SQL Server, MySQL and PostgreSQL).