Java 为什么 EntityManager 为空?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18846709/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:35:56  来源:igfitidea点击:

why EntityManager is null?

javaentitymanageropenjpapersistence.xmltomee

提问by kuba44

In my web applicaton I use OpenJPA on Apache Tomcat (TomEE)/7.0.37 server. I use Netbeans to auto generate class ("Entity Class from database..." and "Session Beans From Entity Class..."). At SessionBean (for example UserFacade) i want to get EntityManager:

在我的 Web 应用程序中,我在 Apache Tomcat (TomEE)/7.0.37 服务器上使用 OpenJPA。我使用 Netbeans 自动生成类(“来自数据库的实体类...”和“来自实体类的会话 Bean...”)。在 SessionBean(例如 UserFacade)我想获得 EntityManager:

@Stateless
public class UserFacade extends AbstractFacade<User> {
  @PersistenceContext(unitName = "CollDocPU")
  private EntityManager em;

  @Override
  protected EntityManager getEntityManager() {
    return em;
  }
}

but when i get it by above way I get null. When I make it by:

但是当我通过上述方式得到它时,我得到了空值。当我做到时:

@Override
protected EntityManager getEntityManager() {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("CollDocPU");
    EntityManager ecm = emf.createEntityManager(); 
    return ecm;
}    

ecm is not null and it ok

ecm 不为空,没关系

my persistence.xml:

我的持久性.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="CollDocPU" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>model.entity.StudentAddSolution</class>
<class>model.entity.Lecturer</class>
<class>model.entity.Solution</class>
<class>model.entity.Student</class>
<class>model.entity.Course</class>
<class>model.entity.File</class>
<class>model.entity.CourseHasLecturer</class> 
<class>model.entity.Mail</class>
<class>model.entity.StudentAtCourse</class>
<class>model.entity.Roles</class>
<class>model.entity.Task</class>
<class>model.entity.User</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
   <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:11080/myBase?zeroDateTimeBehavior=convertToNull"/>
   <property name="javax.persistence.jdbc.password" value="pass,"/>
   <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
   <property name="javax.persistence.jdbc.user" value="myBase"/>
   <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
  </properties>
 </persistence-unit>
</persistence>

采纳答案by kuba44

To get not null EntityManager from

从不为空的 EntityManager

@PersistenceContext(unitName = "CollDocPU")
private EntityManager em;

i have to change my persistance.xml, change transaction-type to "JTA" and add:

我必须更改我的persistance.xml,将事务类型更改为“JTA”并添加:

<jta-data-source>java:openejb/Resource/myDatabase</jta-data-source>
<non-jta-data-source>java:openejb/Resource/myDatabaseUnmanaged</non-jta-data-source>

after that, i have to declare resources in my server configuration: at [tomee installation folder]/conf/tomee.xml file:

之后,我必须在我的服务器配置中声明资源:在 [tomee 安装文件夹]/conf/tomee.xml 文件中:

<?xml version="1.0" encoding="UTF-8"?>
 <tomee>
  <Resource id="myDatabase" type="DataSource">
     JdbcDriver com.mysql.jdbc.Driver
     JdbcUrl jdbc:mysql://localhost:11080/jkitaj?zeroDateTimeBehavior=convertToNull
     UserName jkitaj
     Password pass,
  </Resource>

  <Resource id="myDatabaseUnmanaged" type="DataSource">
     JdbcDriver com.mysql.jdbc.Driver
     JdbcUrl jdbc:mysql://localhost:11080/jkitaj?zeroDateTimeBehavior=convertToNull
     UserName jkitaj
     Password pass,
     JtaManaged false
  </Resource>
 </tomee>

Look there:

看这里:

http://openejb.979440.n4.nabble.com/org-apache-openjpa-lib-jdbc-ReportingSQLException-type-not-found-or-user-lacks-privilege-td4665124.html

http://openejb.979440.n4.nabble.com/org-apache-openjpa-lib-jdbc-ReportingSQLException-type-not-found-or-user-lacks-privilege-td4665124.html

http://mobiarch.wordpress.com/2012/12/07/configuring-a-mysql-data-source-in-tomee/

http://mobiarch.wordpress.com/2012/12/07/configuring-a-mysql-data-source-in-tomee/

回答by Gaurav

The persistence.xmlfile should be under META-INF folder. Check thisdocumentation to understand the structure.

的persistence.xml文件应该是在META-INF文件夹中。查看文档以了解结构。

回答by Prakhar Agrawal

I was facing the same problem, as i am using Jersey Rest with the JPA/Hibernate and Spring,in my project, and getting entity manager as null everytime while using

我遇到了同样的问题,因为我在我的项目中使用 Jersey Rest 和 JPA/Hibernate 和 Spring,并且每次使用时都将实体管理器设置为 null

@PersistenceContext(name = "JPA_DEMO", type = PersistenceContextType.TRANSACTION)
 EntityManager em;

and if i was creating it manually like the syntax below it is working fine.

如果我像下面的语法一样手动创建它,它工作正常。

EntityManagerFactory ENTITY_MANAGER_FACTORY = Persistence.createEntityManagerFactory("JPA_DEMO");//
EntityManager em = ENTITY_MANAGER_FACTORY.createEntityManager();

After some research i found the problem is, that though we are using the @PersistenceContext who is responsible to inject the entity manager object, but it doesn't had the class from which it will get the object i.e the Class which is used by the Spring to create and get the Entity Manager Object from and inject it to our EntityManager object defined under @PersistenceContext. The responsible class is LocalContainerEntityManagerFactoryBeanwhich is defined in my application.xml(used for loading my spring beans). So i defined it and it worked. Below is the syntax for defining it and it is for the transaction manager, so u can use transactions also.

经过一些研究,我发现问题是,虽然我们使用负责注入实体管理器对象的@PersistenceContext,但它没有从中获取对象的类,即Spring 创建并从中获取实体管理器对象并将其注入我们在 @PersistenceContext 下定义的 EntityManager 对象。负责的类是LocalContainerEntityManagerFactoryBean,它在我的 application.xml 中定义(用于加载我的 spring bean)。所以我定义了它并且它起作用了。下面是定义它的语法,它用于事务管理器,因此您也可以使用事务。

<tx:annotation-driven transaction-manager="transactionMgr" />

<bean id="transactionMgr" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="MgrFactory"/>
</bean>

    <bean id="MgrFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="com.restDemo"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
            <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
        </props>
    </property>
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>