EntityManager在@PersistenceContext中始终为null

时间:2019-04-02 14:27:30

标签: java jpa java-ee

我正在使用Wildfly创建一个简单的Crud应用程序来管理书籍(查找并保存)

但是EntityManager总是返回null。

我尝试了Persistence.createEntityManagerFactory(“ PU”)方法,效果很好。

我需要知道为什么我的代码无法正常工作。什么缺失或错误?

谢谢

  

Jee中的人员级别=初学者

     

Wildfly版本14

     

IDE Intellij

     

Java 7

     

JEE 7

     

ORM EclipseLink

Book.java:

package Model;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Book {

    @Id
    private Long id;
    private String title;
    private String description;
    private Float unitCost;
    private String isbn;

    public Book(Long id) {
        this.id = id;
    }

    public Book() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Float getUnitCost() {
        return unitCost;
    }

    public void setUnitCost(Float unitCost) {
        this.unitCost = unitCost;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
}

BookService.java

package Service;

import Model.Book;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.transaction.Transactional;


@Transactional
public class BookService {

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

    public void persist(Book book) {
        em.persist(book);
    }

    public Book find(long id) {
        return em.find(Book.class, id);
    }
}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">

    <persistence-unit name="applicationCDBookStorePU" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <properties>
            <property name="eclipselink.jdbc.url" value="jdbc:postgresql://localhost/book"/>
            <property name="eclipselink.jdbc.driver" value="org.postgresql.Driver"/>
            <property name="eclipselink.jdbc.user" value="postgres"/>
            <property name="eclipselink.jdbc.password" value="root"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

测试主线

package Service;

public class Test {
    public void displayBook(long id) {
        BookService bookService = new BookService();
        System.out.println(bookService.find(id));
    }
}

index.jsp

<%@ page import="Service.Test" %><%--
  Created by IntelliJ IDEA.
  Date: 02/04/2019
  Time: 15:07
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>
    <%
    Test test = new Test();
    test.displayBook(1);
    %>
< /body>
</html>

StackTrace:

org.apache.jasper.JasperException: java.lang.NullPointerException
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:473)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:403)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:347)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.jsp.JspFileHandler.handleRequest(JspFileHandler.java:32)
    at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
    at Service.BookService.find(BookService.java:22)
    at Service.Test.displayBook(Test.java:6)
    at org.apache.jsp.index_jsp._jspService(index_jsp.java:102)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:433)
    ... 46 more

代码结构: image here

2 个答案:

答案 0 :(得分:1)

要使用由findChild注入的EntityManager,它需要由您的容器(Widlfly)进行管理。

因此,您必须让您的容器负责借助@PersistenceContext注释创建这些类。

  • 要使事情变得轻松而不是使用JSP文件,请创建一个JSF(index.xhtml),如下所示:
@Inject
  • 您的Test类需要使用@Named(“ test”)进行注释,以便可以从jsf访问:

重要:请确保使用正确的导入。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">


<h:body>
    Message is: #{test.displayBook(1)}
</h:body>
</html>

  • 您的BookingService可能如下所示:
package Service;

import javax.inject.Inject;
import javax.inject.Named;

@Named("test")
public class Test {

    @Inject
    private BookService bookService;

    public String displayBook(long id) {
        bookService.find(id);
        return "Done!";
    }
}

  • 保持您的Book模型不变。

  • 重新排列文件夹,如以下屏幕截图所示:

Project tree structure

  • 如图所示创建一个bean.xml,其中包含以下内容,这使CDI(JavaEE依赖注入器)可以扫描类。
package Service;


import Model.Book;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.transaction.Transactional;

@Transactional
public class BookService {

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

    public void persist(Book book) {
        em.persist(book);
    }

    public Book find(long id) {
        System.out.println("EntityManager: " + em.toString());
        return em.find(Book.class, id);
    }

}

部署您的应用程序,转到http://localhost:PORT/CONTEXT/index.html

如果您在wildfly日志中看到如下条目:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="all">
</beans>

EntityManager已正确注入。

PS::遵循Java命名约定,程序包必须为小写,以避免与类或接口的名称https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html

冲突

PS2:用于maven项目的标准目录布局,更多信息:https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

答案 1 :(得分:0)

您需要添加

      <class>Model.Book</class> 

以持久性单元为单位。