【问题标题】:RESTful Web Services connecting to database, Entity Manager is null连接到数据库的 RESTful Web 服务,实体管理器为空
【发布时间】:2014-11-01 19:39:37
【问题描述】:

我正在创建一个 RESTful Web 服务,它使用 NetBeans 8.0、Java EE 7、Tomcat 8.0.12、Maven 和 Microsoft SQL Server 2012 与数据库交互。我按顺序使用了 NetBeans 的“来自实体类的 RESTful Web 服务”功能创建必要的文件来连接数据库并与之交互。当我测试应该返回表中所有内容的 url 时,我得到一个空指针异常。

我查看了 AbstractFacade 的第 43 行,发现 getEntityManager 返回 null,从而导致 NullPointerException。我四处搜索,似乎无法弄清楚如何解决这个问题。任何帮助将不胜感激,如果需要,我们会发布更多信息。

这是完整的堆栈跟踪:

java.lang.NullPointerException
    service.AbstractFacade.findAll(AbstractFacade.java:43)
    service.TestTableFacadeREST.findAll(TestTableFacadeREST.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:606)
    org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
    org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151)
    org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171)
    org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:195)
    org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
    org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:387)
    org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:331)
    org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:103)
    org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:271)
    org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
    org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254)
    org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1030)
    org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:373)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
    org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

这里是persistence.xml文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
   <persistence-unit name="com.madejekz_RestTest2_war_1.0-SNAPSHOTPU" transaction-type="RESOURCE_LOCAL">
      <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
      <class>com.madejekz.resttest2.TestTable</class>
      <exclude-unlisted-classes>false</exclude-unlisted-classes>
      <properties>
         <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://IP_ADDRESS_HERE;databaseName=test_ford"/>
         <property name="javax.persistence.jdbc.password" value="PASSWORD"/>
         <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
         <property name="javax.persistence.jdbc.user" value="sa"/>
      </properties>
   </persistence-unit>
</persistence>

这里是 AbstractFacade.java:

package service;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;

public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0] + 1);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

}

最后是TestTableFacadeREST.java:

package service;

import com.madejekz.resttest2.TestTable;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;


@Stateless
@Path("com.madejekz.resttest2.testtable")
public class TestTableFacadeREST extends AbstractFacade<TestTable> {
    @PersistenceContext(unitName = "com.madejekz_RestTest2_war_1.0-SNAPSHOTPU")
    private EntityManager em;

    public TestTableFacadeREST() {
        super(TestTable.class);
    }

    @POST
    @Override
    @Consumes({"application/xml", "application/json"})
    public void create(TestTable entity) {
        super.create(entity);
    }

    @PUT
    @Path("{id}")
    @Consumes({"application/xml", "application/json"})
    public void edit(@PathParam("id") String id, TestTable entity) {
        super.edit(entity);
    }

    @DELETE
    @Path("{id}")
    public void remove(@PathParam("id") String id) {
        super.remove(super.find(id));
    }

    @GET
    @Path("{id}")
    @Produces({"application/xml", "application/json"})
    public TestTable find(@PathParam("id") String id) {
        return super.find(id);
    }

    @GET
    @Override
    @Produces({"application/xml", "application/json"})
    public List<TestTable> findAll() {
        return super.findAll();
    }

    @GET
    @Path("{from}/{to}")
    @Produces({"application/xml", "application/json"})
    public List<TestTable> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
        return super.findRange(new int[]{from, to});
    }

    @GET
    @Path("count")
    @Produces("text/plain")
    public String countREST() {
        return String.valueOf(super.count());
    }

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

}

【问题讨论】:

    标签: java rest tomcat netbeans sql-server-2012


    【解决方案1】:

    您必须在 JavaEE 环境中将事务类型定义为JTA。所以改成

    <persistence-unit name="com.madejekz_RestTest2_war_1.0-SNAPSHOTPU" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    

    请注意RESOURCE_LOCAL 应在JavaSE 环境中提及。

    【讨论】:

    • 做到了,但不幸的是仍然遇到同样的问题。
    • 您使用哪个版本的 EclipseLink JPA?
    • EclipseLink JPA的版本是2.5.1
    • 更正我之前的评论,EclipseLink JPA 的版本是 2.1
    【解决方案2】:

    去掉线解决:

    @PersistenceContext(unitName = "com.madejekz_RestTest2_war_1.0-SNAPSHOTPU")
    

    来自 TestTableFacadeREST.java 文件并添加以下行:

    em = Persistence.createEntityManagerFactory("com.madejekz_RestTest5_war_1.0-SNAPSHOTPU").createEntityManager();
    

    到 TestTableFacadeREST.java 文件中的 getEntityManager 方法。

    【讨论】:

      猜你喜欢
      • 2011-10-12
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-20
      • 1970-01-01
      • 2011-06-08
      相关资源
      最近更新 更多