java 为什么 EntityManager 关闭?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28031318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why the EntityManager is closed?
提问by JavaBaby
I'm developing a small stock control application using Java-SE8, JPA and Hibernate and this is my first contact with ORMs and the Persistence API. All was fine, but my tests failed when I created a method to retrieve things on the database(MySQL) and I get an:
我正在使用 Java-SE8、JPA 和 Hibernate 开发一个小型股票控制应用程序,这是我第一次接触 ORM 和 Persistence API。一切都很好,但是当我创建一个方法来检索数据库(MySQL)上的内容时,我的测试失败了,我得到了一个:
"IllegalStateException: Entity Manager is closed."
“IllegalStateException:实体管理器已关闭。”
I really don't know what is happening and spent almost two days trying to fix this. Can anyone help me, please?
我真的不知道发生了什么,花了将近两天的时间试图解决这个问题。任何人都可以帮助我吗?
Here are the pieces of code that trigger the error.
以下是触发错误的代码段。
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();
}
And the StackTrace I've got:
还有我得到的 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##代码##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)
采纳答案by Neil Stockton
So you created an EntityManagerFactory
(EMF), then an EntityManager
(from the EMF), and then closed the EntityManagerFactory
… which will close allof the EntityManager
that it owns. Don't close the EMF!!
所以,你创建了一个EntityManagerFactory
(EMF),那么EntityManager
(从EMF),然后关闭了EntityManagerFactory
......这将关闭所有的EntityManager
它拥有。不要关闭EMF!!