35

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.

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
jayjay
  • 351
  • 1
  • 3
  • 6

2 Answers2

21

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.

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Mansour
  • 614
  • 1
  • 5
  • 13
  • thanks - I added a note to my original post clarifying that I'm not in an Enterprise environment, therefore container injection is not available. I do note your comment about thread-safety though. – jayjay Jun 24 '12 at 01:23
  • RE thread-safety - I assume you refer to my example, since an EntityManager injected and managed by a container would be thread-safe. – jayjay Jun 24 '12 at 01:29
  • No it wont be thread safe, but the container creates new one when needed (I could be wrong), so it looks like it's thread safe. If you are on none Enterprise Environment, then I see no problem in creating one static instance of the factory EntityManagerFactory, and call it to obtain instances of EntityManager when needed. And don't foreget to close them after each transaction. This thread show a code that can be useful to you. http://stackoverflow.com/questions/7329873/how-should-manage-database-transactions-using-entity-manager-in-a-relatively-lar – Mansour Jun 24 '12 at 01:58
  • Mansour, my question was not about a static EMF and then calling createEntityManager() on it (which is the first example in my post and also the example you point to in the link). My question was about creating an instance or static EM and then using that. – jayjay Jun 24 '12 at 02:36
1

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).

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
Klaus Groenbaek
  • 4,820
  • 2
  • 15
  • 30