java 在 TomEE 中注入 EntityManager 导致 NullPointerException?

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

Injecting EntityManager results in NullPointerException in TomEE?

javaejbopenejb

提问by akaine

Here's my MovieBean.java:

这是我的 MovieBean.java:

@Stateless
public class MovieBean {

@PersistenceContext
private EntityManager em;

/**
 * Default constructor. 
 */
public MovieBean() {
    // TODO Auto-generated constructor stub
}

public List<Movie> getAllMovies() {
    Query query = em.createQuery("SELECT m FROM Movie m");
    return query.getResultList();
}

My MoviesServletuses this MovieBean like this:

MoviesServlet像这样使用这个 MovieBean:

@WebServlet("/MoviesServlet")
public class MoviesServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

@EJB
private MovieBean mb;

private List<Movie> getMovies() {
    return mb.getAllMovies();
}

And in my doGetmethod I use the getMoviesmethod to get a list of all movies. However, I get the following exceptions:

在我的doGet方法中,我使用该getMovies方法来获取所有电影的列表。但是,我得到以下例外:

javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is: 
java.lang.NullPointerException
org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:363)
org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:283)
bg.cinemate.beans.MovieBean$LocalBeanProxy.getAllMovies(bg/cinemate/beans/MovieBean.java)
bg.cinemate.servlets.MoviesServlet.getMovies(MoviesServlet.java:27)
bg.cinemate.servlets.MoviesServlet.doGet(MoviesServlet.java:42)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

java.lang.NullPointerException
bg.cinemate.beans.MovieBean.getAllMovies(MovieBean.java:31)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:601)
org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
org.apache.openejb.cdi.CdiInterceptor.invoke(CdiInterceptor.java:126)
org.apache.openejb.cdi.CdiInterceptor.access
<?xml version="1.0" encoding="UTF-8" ?>
    <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"
            version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
            <persistence-unit name="cinema" transaction-type="RESOURCE_LOCAL">
                    <properties>
                            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/cinema" />
                            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
                            <property name="javax.persistence.jdbc.user" value="root" />
                            <property name="javax.persistence.jdbc.password" value="password" />
                            <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
                            <property name="eclipselink.ddl-generation.output-mode" value="database" />
                    </properties>

            </persistence-unit>
    </persistence>
0(CdiInterceptor.java:42) org.apache.openejb.cdi.CdiInterceptor.call(CdiInterceptor.java:63) org.apache.openejb.cdi.CdiInterceptor.aroundInvoke(CdiInterceptor.java:69) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:601) org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181) org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163) org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:176) org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:95) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:601) org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181) org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163) org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:138) org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:239) org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:191) org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:246) org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:241) org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:83) org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:279) bg.cinemate.beans.MovieBean$LocalBeanProxy.getAllMovies(bg/cinemate/beans/MovieBean.java) bg.cinemate.servlets.MoviesServlet.getMovies(MoviesServlet.java:27) bg.cinemate.servlets.MoviesServlet.doGet(MoviesServlet.java:42) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

My persistance.xmlfile is configured like this:

我的persistance.xml文件配置如下:

    <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
      <persistence-unit transaction-type="RESOURCE_LOCAL" name="cinema">
        <jta-data-source>java:openejb/Connector/Default JDBC Database</jta-data-source>
        <non-jta-data-source>java:openejb/Connector/Default Unmanaged JDBC Database</non-jta-data-source>
        <class>bg.cinemate.beans.MovieBean</class>

        <properties>
          <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
        </properties>
      </persistence-unit>
    </persistence>

I tried changing it (tried with the one shown here) but it does not even start the server (says the time limit has exceeded, even after I tried changing it to 200 seconds). I use Java7, OpenEJB and TomEE.

我尝试更改它(尝试使用此处显示的那个),但它甚至没有启动服务器(说已超过时间限制,即使在我尝试将其更改为 200 秒之后)。我使用 Java7、OpenEJB 和 TomEE。

EDIT 1:I changed my persistence.xmlto this:

编辑 1:我改变了我的persistence.xml

<class>YourPackagePath.Movie</class>

Tried @PersistenceContext(unitName="cinema")and the server started, but it gives me the same exceptions.

试过@PersistenceContext(unitName="cinema")了,服务器启动了,但它给了我同样的例外。

回答by Ravi Trivedi

There can be several reasons to this:

这可能有几个原因:

  1. Your class Movieis not an entity. In this case, post your Movieclass code. Check if it is annotated with @Entity. Or define Movieinside your persistence.xml.

    I am looking at your persistence.xmland I am seeing MovieBeaninside the file. This is wrong. You don't need EJB inside your file. You need to define class which is entity like Movie.

    Change it like this:

    <class>YourPackagePath.Movie</class>
    
  2. Your EJB is not managed. Means your EJB fails to deploy properly. In this case, it will not be managed by container and annotation lookup will fail. Check if your EJB is mapped to a JNDI name. You can check this through Server GUI, Server Startup Log or 3rd party App.

  3. The name of your DataSourceis wrong.

    In this line <jta-data-source>java:openejb/Connector/Default JDBC Database</jta-data-source>, you don't need to prefix java:. Only use JNDI name of your DataSource. Again check if the JNDI name of your DataSourceis correct. You can check this as mentioned in Point#2.

  4. Don't use JTA and Non-JTA dataSources together. JTA is used when you don't handle transaction manually and Non-JTA is used when you need to handle transaction manually in your code. Use JTA. That should be fine.

  1. 你的班级Movie不是一个实体。在这种情况下,请发布您的Movie课程代码。检查它是否带有注释@Entity。或者Movie在你的persistence.xml.

    我正在查看您的文件persistence.xml,我正在查看MovieBean文件内部。这是错误的。您的文件中不需要 EJB。您需要定义类似于Movie.

    像这样改变它:

    <Resource id="mydatabaseDS" type="DataSource">
        JdbcDriver org.postgresql.Driver
        JdbcUrl jdbc:postgresql://localhost:5432/mydatabase
        UserName myuser
        Password mypassword
        JtaManaged true
    </Resource>
    
  2. 您的 EJB 不受管理。意味着您的 EJB 无法正确部署。在这种情况下,它不会被容器管理并且注解查找将失败。检查您的 EJB 是否映射到 JNDI 名称。您可以通过服务器 GUI、服务器启动日志或 3rd 方应用程序进行检查。

  3. 你的名字DataSource是错误的。

    在这一行中<jta-data-source>java:openejb/Connector/Default JDBC Database</jta-data-source>,您不需要前缀java:。仅使用您的DataSource. 再次检查您的 JNDI 名称DataSource是否正确。您可以按照第 2 点中所述进行检查。

  4. 不要同时使用 JTA 和非 JTA 数据源。当您不手动处理事务时使用 JTA,当您需要在代码中手动处理事务时使用 Non-JTA。使用 JTA。那应该没问题。

回答by akaine

I Had exactly the same problem while using OpenJPA2 with similar structure. The one that solved my NullPointer problem was changing transaction-type="RESOURCE_LOCAL"to transaction-type="JTA". Though in this case I get this exception: org.apache.openjpa.persistence.PersistenceException: user lacks privilege or object not found.

我在使用具有类似结构的 OpenJPA2 时遇到了完全相同的问题。解决我的 NullPointer 问题的那个正在更改transaction-type="RESOURCE_LOCAL"transaction-type="JTA". 虽然在这种情况下我得到了这个例外:org.apache.openjpa.persistence.PersistenceException: user lacks privilege or object not found.

Correction: The last exception is solved and all transactions are running perfectly after I mapped correctly the datasource from tomee to the persistence.xml

更正:在我将数据源从 tomee 正确映射到persistence.xml 后,最后一个异常已解决,所有事务都在完美运行

tomee.xml:

tomee.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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" version="2.0">

    <persistence-unit name="myPU" transaction-type="JTA">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <jta-data-source>mydatabaseDS</jta-data-source>
    </persistence-unit>
</persistence>

persistence.xml:

持久性.xml:

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

Don't forget to add you jdbc driver lib into the {tomee}/lib dir.

不要忘记将 jdbc 驱动程序库添加到 {tomee}/lib 目录中。

回答by JamesB

Try this in your EJB:

在你的 EJB 中试试这个:

<provider> org.apache.openjpa.persistence.PersistenceProviderImpl </provider>

Also, your file should be called persistence.xml, not persistance.xml and needs to be under the folder META-INF.

此外,您的文件应命名为persistence.xml,而不是persistance.xml,并且需要位于META-INF 文件夹下。

When using a RESOURCE_LOCAL datasource, the names of your entity classes must be provided in this file.

使用 RESOURCE_LOCAL 数据源时,必须在此文件中提供实体类的名称。

The name of the persistence provider should also be given in this file:

此文件中还应提供持久性提供程序的名称:

protected static EntityManagerFactory
 em=Persistence.createEntityManagerFactory("cinema");

Edit: Ensure the PersistenceProviderImpl class is on the classpath when your code runs on the server

编辑:当您的代码在服务器上运行时,确保 PersistenceProviderImpl 类位于类路径上

回答by user2280897

I am working on a project with a similar structure to yours. Here is the major difference between mine and yours

我正在做一个与你的结构相似的项目。这是我的和你的主要区别

@PersistenceContext(unitName = "cinema", type = PersistenceContextType.EXTENDED)
 private EntityManager em;

You might be getting the null pointer exception in your MovieBean class as you have not created the entitymanager factory. It has not been instansiated and that is why you are getting the null pointer exception. This code has not been tested in your case. It just stands out to me so I said I would say it.

您可能会在 MovieBean 类中收到空指针异常,因为您尚未创建 entitymanager 工厂。它尚未实例化,这就是您收到空指针异常的原因。此代码尚未在您的情况下进行测试。它对我来说很突出,所以我说我会说。

EDIT: After looking at the tomcat site via your link there is also

编辑:通过您的链接查看 tomcat 站点后,还有

##代码##