获取EntityManager的不同方法

我在创建EntityManager时看到的常用习惯是这样的:

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

然后就像这样使用:

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

问题是为什么不这样做:

 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; } } 

换句话说,是否需要始终通过factory.createEntityManager()获取实体管理器? 或者它可以创建为实例(甚至静态)变量并像这样检索?

为了澄清,我在谈论一个不使用EJB或Spring容器的环境。

谢谢。

有两种方法可以创建EntityManager实例。 一种方法是SDK应用程序,我在unit testing中使用这种方式很多。 这是你的例子中的内容:

 EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 

在Enterprise应用程序中,您让容器为您创建它们并在需要时注入它们。

EntityManager只是JDBC连接的包装器。 它的重量非常轻,可以创建和销毁而不会降低性能。

请记住, EntityManager不是线程安全的,因此如果您有一个实例,则可能需要同步对它的访问。 有关详细信息,请参阅事务基础


这是我将如何做到(大致):

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

一旦你得到这个原型并准备就绪,你可以使用通用的DAO。

今天你应该看看像spring-data和@PersistanceUnit来管理你的EntityManager。

EntityManager不仅仅是一个包装器,用于JDBC连接的包装器。 它定义了持久化上下文的范围,该上下文定义了在提交事务时(当您将查询刷新到数据库时)应该执行的工作单元。 在持久化上下文中,您还可以保证数据库中的给定实体将产生相同的Java对象,无论您是直接加载它还是通过另一个实体的OneToMany关系访问它。

关于在非弹簧设置中获取EntityManagerFactory的原始问题。 你只需打电话

 Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 

此方法是一个静态工厂方法,根据您的JPA实现,您可以获得相同PU的相同实例,或者包装底层持久性会话的浅包装器(每个PU有一个)。