jayjay
jayjay

Reputation: 351

Different ways of getting the EntityManager

The usual idiom I see for creating the EntityManager is something like this:

public class BaseDao {
    private static final String PERSISTENCE_UNIT_NAME = "Employee";

    EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

    public EntityManager getEntityManager() {
      return factory.createEntityManager();
    } 
}

Then it is used like this:

Employee emp = new Employee();
emp.setName("Joe M");
getEntityManager().persist(emp);

Question is why not do it this way:

public class BaseDao{
    private static final String PERSISTENCE_UNIT_NAME = "Employee";
    EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    private EntityManager entityManager = null;


public void setEntityManger() {
    EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    this.entityManager = factory.createEntityManager();

    }

    public EntityManager getEntityManager() {
        return this.entityManager;
    }
}

In other words is there a need to always get the entity manager through factory.createEntityManager()? or can it be created as an instance (or even static) variable and retrieved like that?

To clarify, I am talking about an environment that doesn't use EJB or Spring containers.

Thanks.

Upvotes: 35

Views: 85891

Answers (2)

Mansour
Mansour

Reputation: 687

There are two ways to create EntityManager instances.

One way is for SDK applications, and I use this way a lot in unit testing. This is what you have in your example:

EntityManagerFactory factory = 
  Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

In Enterprise applications you let the container create them for you and inject them when needed.

EntityManager is just a wrapper around a JDBC connection. It's very light weight and can be created and destroyed without performance penalty.

Keep in mind that the EntityManager is not thread safe, so if you have one instance, you may need to synchronize access to it. See transaction basics for details.


Here's how I would do it (roughly):

public class BaseDao{
  private static final String PERSISTENCE_UNIT_NAME = "Employee";
  private static EntityManagerFactory factory = 
    Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

  public void create(MyEntiy person){
    EntityManager em = factory.createEntityManager();
    em.getTransaction().begin();
    // do what ever you need 
    em.getTransaction().commit();
    em.close();
  }

  // add more methods to the dao.
}

Once you get this protoyped and ready, you can use a generic DAO.

Upvotes: 21

Klaus Groenbaek
Klaus Groenbaek

Reputation: 5035

Today you should probably look at sometime like spring-data and @PersistanceUnit for managing your EntityManager.

An EntityManager is more than just a wrapper a wrapper for a JDBC connection. It defines the scope of a persistence context, which defines the unit of work that should be performed when a transaction is committed (of when you flush queries to the database). Within a persistence context you are also guaranteed that a given entity in the database will result in the same Java object, regardless if you load it directly, or access it through a OneToMany relation of another entity.

With regards to the original question about obtaining an EntityManagerFactory in a non-spring setting. You simply call

Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

This method is a static factory method, depending on your JPA implementation you either get the same instance for the same PU, or a shallow wrapper that wraps the underlying persistence session (of which there is one per PU).

Upvotes: 1

Related Questions