While developing my Java EE application I’ve encountered two situations in which my entities were prematurely created in the DB; They were inserted before their referenced rows were inserted, resulting in a violation of a foreign key.
At first I thought I got it wrong, creating the rows in the DB in the wrong order.
But no, this was not the case. Then I started thinking there are bugs in my JPA provider*, or maybe they just got it wrong.
But then I realised that the EntityManager wasn’t aware of the connection between the tables.
Let me explain:
In both situtation table A references table B using a foreign key.
Situtation #1:
My code:
1. Creates an entity of table B.
2. Creates a row of table A using JDBC (there's no entity for table A).
JPA provider:
1. Runs the JDBC first (inserts a row into table A).
2. SQLException is thrown, because B isn't created yet.
Why use JDBC?
Because it’s not my code.
Situtation #2:
My code:
1. Creates an entity of table B.
2. Creates an entity of table A. The thing is, A only holds B's ID.
JPA provider:
1. Creates entity A.
2. SQLException is thrown, because B isn't created yet.
Why B doesn’t have A as a member?
Because B has a big blob in it, and it takes a lot of memory, and I want to minimize references to B objects.
I need a solution. Maybe there’s someway to tell the EntityManager to run the SQL exactly in the same order I invoked it.
While in the toilets I also thought about using ‘flush’ after creating entity B, but I can’t test it now because our developement DB is down for maintenance (DBA working their magic).
* I’m using TopLink which comes with Oracle WebLogic 12.1.1.0.
Good way to solve is to have relationship between A and B. What can be done to make that more efficient is:
If because of some reason that cannot be done, then you should flush entitymanager after each operation that is required to be done before later operations.