34

我看到的用于创建 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 容器的环境。

谢谢。

4

2 回答 2

19

两种创建EntityManager实例的方法。

一种方法是用于 SDK 应用程序,我在单元测试中经常使用这种方法。这就是您的示例中的内容:

EntityManagerFactory factory = 
  Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

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

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。

于 2012-06-24T01:12:53.367 回答
1

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

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

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

Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);

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

于 2016-11-24T11:49:12.650 回答