0

I want to be able to use one entity manager to commit multiple transactions for CRUD actions concerning different entity objects. For example I want to be able to delete a cat entity object and create a new dog entity object all during one entity manager session. I achieve this by having the catService and dogService (the objects that can CRUD objects) extend a GenericService:

public abstract class GenericService<T> {
private Class<T> type;
protected static EntityManager entityManager;

public GenericService() {
    Type t = getClass().getGenericSuperclass();
    ParameterizedType pt = (ParameterizedType) t;
    type = (Class) pt.getActualTypeArguments()[0];
    if (entityManager == null || !entityManager.isOpen()) entityManager = GetEntityManager.getInstance(); // zo kunnen meerdere services gebruik maken van dezelfde entitymanager sessie. 1 operation per sessie is een antipattern namelijk. Beter meerdere operations in 1 sessie doen.
}

// sluit entityManager en daarmee dus ook de sessie af.
public void close(){
    entityManager.close();
}

Now both services share the same entitymanager. Now I can make multiple transactions and call the inherited close() method only on the last Service object, which then closes the shared entity manager.

I intend to make a webapplication so I was wondering if using entity manager sessions more efficiently by having them be shared by different serviceObjects that are operating upon different entity objects would have a performance gain compared to opening and closing a new session(entity manager) for just one transaction.

Thank you.

Maurice
  • 6,698
  • 9
  • 47
  • 104

1 Answers1

1

Session-per-operation is an anti-pattern but not for performance reasons. You can do a lot of extra calculations (like creating sessions) and not notice any performance difference because waiting for a database to complete a transaction takes a long time compared to doing extra calculations (database I/O operations take milliseconds to complete, calculations take nanoseconds to complete).

Since you intend to make a web-application, try using Hibernate's sessionFactory.getCurrentSession() which sort of does what you do now in the constructor of the GenericService - more info in the user guide, this answer and javadocs.

Community
  • 1
  • 1
vanOekel
  • 6,358
  • 1
  • 21
  • 56
  • woulden't it increase performance by reducing the amount of active session objects (or Entity manager objects) that are stored in memory? – Maurice May 21 '17 at 06:30
  • 1
    I doubt you would notice the increase in performance. Try measuring the increase in performance in a production-like setup (e.g. using a real database, not an in-memory database) for the two scenario's (re-using a session versus creating new ones each time). I think you will find that the increase in performance is barely measurable. My main point here is to focus on good quality code first (doing the right thing) and not worry about performance too much until the need arises (e.g. when a web-request's response is too slow). – vanOekel May 21 '17 at 09:43