In a desktop application that runs in a Java SE environment (no DI, no frameworks other than JPA, plain Java) it is better to create a new EntityManager for each operation in the persistence layer or share a single instance of the EntityManager in the entire persistence layer?
Pro/Cons for both the solutions?
Update:
The application uses one DB instance with only one schema.
In JPA, the EntityManager interface is used to allow applications to manage and search for entities in the relational database. The EntityManager is an API that manages the lifecycle of entity instances. An EntityManager object manages a set of entities that are defined by a persistence unit.
EntityManagerFactory vs EntityManager EntityManager: whenever using spring avoid managing/using EntityManagerFactory since Spring manages concurreny for you. The entity manger injected by @PersistenceContext is thread safe. While EntityManagerFactory instances are thread-safe, EntityManager instances are not.
The EntityManager API is used to create and remove persistent entity instances, to find entities by their primary key, and to query over entities. The set of entities that can be managed by a given EntityManager instance is defined by a persistence unit.
If you don't close it your entities will be kept as attached, even after you're done using them. Your context will be kept alive even when you can no longer access your EM. The JPA Specification contains more details.
There are at least three good reasons to have one EM per operation.
If any other process modifies the database (or even if the same process uses JDBC or batch queries to modify the database), the EM will have stale data in its cache. If your EM only lives for the duration of a transaction, you have almost no risk of having to deal with stale data.
If any exception occurs with the EM, then its state is not reliable anymore, and the EM must be closed.
If several threads access the EntityManager, you need one EM per thread because the EM is not thread-safe.
And here's a fourth one: even assuming that everything goes fine always, that only one thread accesses the database, the cache of the EM will grow up an up and will consume memory. You also risk in having an inconsistent object graph in the cache because you forgot to initialize the inverse side of an association. Having one EM per transaction doesn't have this problem.
EntityManager
is an entry point to JPA world. It provides API to access the JPA session and manages the schema. It also holds cache.
So, IMHO there is no reason to hold EntityManager
per operation. There can be reason to hold EntityManager
per DB schema. If for example your application works with 2 absolutely different DB schemas that do not have any shared table you can use EntityManager
per schema.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With