SheppardDigital
SheppardDigital

Reputation: 3255

JPA, when to open and close entityManager

I've setup a spring MVC application for a web application and I'm using Hibernates implementation of JPA 2.1.

I've created my models and am able to interact with the database just fine.

I've also decided to use service classes which will manage returning the entities. What I've done is created a BaseService class, so all other service classes will expand on this, and they'll have access to common functions such as create(), delete(), update() and list().

My problem is I'm unsure as to when I should be creating the EntityManager and when I should be closing it?

Currently, in my controller I'm initiating the required services when the controller loads;

@Controller
@RequestMapping("/mycontroller")
public class TestController {

    CarService carService = new CarService();
    ShowroomService showroomService = new ShowroomService();
    }
}

Here is the BaseService that each other service extends;

public class Service<Ety> {

    EntityManager em = null;
    public Class<Ety> entityClass;

    public Service(Class<Ety> entityClass) {
        this.entityClass = entityClass;

        em = JPAUtil.getEntityManager();
    }

    public Ety get(int id) {
        Ety object = null;

        em.getTransaction().begin();
        object = em.find(entityClass, id);
        em.getTransaction().commit();

        return object;
    }

    public List list() {
        List<Ety> objects;

        em.getTransaction().begin();
        objects = em.createQuery("SELECT c FROM "+entityClass.getName()+" c").getResultList();
        em.getTransaction().commit();

        return objects;
    }

    public void save(Ety object) {
        em.getTransaction().begin();
        em.persist(object);
        em.getTransaction().commit();
    }

    public void update(Ety object) {
        em.getTransaction().begin();
        em.merge(object);
        em.getTransaction().commit();
    }

    public void delete(Ety object) {
        em.getTransaction().begin();
        em.remove(object);
        em.getTransaction().commit();
    }

}

Here's an example Service which expands the above;

public class CarService extends Service<Car> {

    public CarService() {
        super(Car.class);
    }

}

As you can see, I'm creating an EntityManager when the service is created, but at the moment I'm not closing it anywhere.

I'm I creating the entity manager in the correct place? when should I close it.

I had considered putting the entity manager in a static property and creating it within a filter, and then closing it at the end of the application, however I do believe this wouldn't be thread safe and would cause issues?

Any advice would be appreciated.

Upvotes: 0

Views: 4339

Answers (2)

Nicolas Zozol
Nicolas Zozol

Reputation: 7038

You open a new EntityManager for each transaction.

This EntityManager is like a Bag mapped to the database, but with zero entity managed inside when it's just opened. When you work with it, this Bag will be filled with some entities and Hibernate will work to create the adequate requests.

You will close this Bag to save memory at the end of the transaction.

Of course there is some tricks to have many transactions for a given EntityManager, but you have the most general idea. As always it depends...

If you use a framework like Spring or JavaEE, it will open and close the EntityManager, as well starting and committing transactions for you. You have only your business work to write.

Upvotes: 0

Si mo
Si mo

Reputation: 979

your CarService should be a spring bean and the instance is created from spring. NOT from your code. The same with the EntityManager. You can use the entityManager with the @autowired annotation.

Upvotes: 1

Related Questions