为什么 EntityManager 关闭了?

Why the EntityManager is closed?

我正在使用 Java-SE8、JPA 和 Hibernate 开发一个小型库存控制应用程序,这是我第一次接触 ORM 和 Persistence API。一切都很好,但是当我创建一个方法来检索数据库中的内容时,我的测试失败了(MySQL),我得到一个:

"IllegalStateException: Entity Manager is closed."

我真的不知道发生了什么,花了将近两天的时间来解决这个问题。谁能帮帮我吗?

以下是触发错误的代码片段。

DAO.java

private EntityManager getEntityManager() {
    EntityManagerFactory factory = null;
    EntityManager entityManager = null;

    try {
      factory = Persistence.createEntityManagerFactory("stockcontrol");
      entityManager = factory.createEntityManager();
    } finally {
      factory.close();
    }

    return entityManager;
}

public <T> List<T> findAllByClass(Class clazz) {
    EntityManager manager = null;

    try{
        manager = getEntityManager();
        String hql = "FROM " + clazz.getName();
        Query hqlQuery = manager.createQuery(hql);
        return hqlQuery.getResultList();
    } finally {
        manager.close();
    }
}

Moneytory.java

DAO dao = new DAO();

public static void registerProduct(String name, int amount, double unitPrice,
        String strCategory) throws RegisterException {

    List<Product> products = dao.findAllByClass(Product.class);
    List<Category> categories = dao.findAllByClass(Category.class);

    if(products.contains(getProductByName(name)))
        throw new RegisterException("The product already exists");


    Product newProduct = null;
    Category newCategory = null;
    try{
        newCategory = new Category(strCategory);
        newProduct = new Product(name, amount, unitPrice, newCategory);
    } catch(IllegalArgumentException e){
        throw new RegisterException(e.getMessage());
    }

    if(!categories.contains(newCategory))
        dao.persist(newCategory);

    dao.persist(newProduct);    
    dao.flush();

}

还有我得到的 StackTrace:

java.lang.IllegalStateException: EntityManager is closed
    at org.hibernate.jpa.internal.EntityManagerImpl.checkOpen(EntityManagerImpl.java:105)
    at org.hibernate.jpa.internal.EntityManagerImpl.checkOpen(EntityManagerImpl.java:96)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:326)
    at br.edu.noorg.moneytory.dao.DAO.findAllByClass(DAO.java:154)
    at br.edu.noorg.moneytory.core.MoneyTory.registerProduct(MoneyTory.java:111)
    at br.edu.noorg.moneytory.test.MoneyToryTest.mustRegisterProduct(MoneyToryTest.java:92)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:53)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

因此您创建了一个 EntityManagerFactory (EMF),然后是一个 EntityManager(来自 EMF),然后关闭了 EntityManagerFactory... 这将 关闭所有它拥有的 EntityManager。不要关闭 EMF!!