【问题标题】:javax.servlet.ServletException: Error instantiating servlet class for bean classjavax.servlet.ServletException:为 bean 类实例化 servlet 类时出错
【发布时间】:2014-07-03 07:26:11
【问题描述】:

我在使用 j7ee ejb 3.1 和 jpa 2.1 在 DB 中插入记录的简单测试应用程序实例化 servlet 类时遇到问题。我是 ejb 和 jpa 的新手,我正在尝试测试解决方案。 我正在使用 NetBeans 8.0。 我为实体类和 ejb 分离了层。

我在 com.tsc.deo.entities 中有实体类 Doctor.java(DEO 是应用程序的名称):

package com.tsc.deo.entities;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author IK
 */
@Entity
@Table(name = "doctor")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Doctor.findAll", query = "SELECT d FROM Doctor d"),
    @NamedQuery(name = "Doctor.findByIDDoctor", query = "SELECT d FROM Doctor d WHERE d.iDDoctor = :iDDoctor"),
    @NamedQuery(name = "Doctor.findBySirname", query = "SELECT d FROM Doctor d WHERE d.sirname = :sirname"),
    @NamedQuery(name = "Doctor.findByName", query = "SELECT d FROM Doctor d WHERE d.name = :name"),
    @NamedQuery(name = "Doctor.findByPatientIDPatient", query = "SELECT d FROM Doctor d WHERE d.patientIDPatient = :patientIDPatient")})
public class Doctor implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "IDDoctor")
    private Integer iDDoctor;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 45)
    @Column(name = "Sirname")
    private String sirname;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 45)
    @Column(name = "Name")
    private String name;
    @Basic(optional = false)
    @NotNull
    @Column(name = "Patient_IDPatient")
    private int patientIDPatient;

    public Doctor() {
    }

    public Doctor(Integer iDDoctor) {
        this.iDDoctor = iDDoctor;
    }

    public Doctor(Integer iDDoctor, String sirname, String name, int patientIDPatient) {
        this.iDDoctor = iDDoctor;
        this.sirname = sirname;
        this.name = name;
        this.patientIDPatient = patientIDPatient;
    }

    public Integer getIDDoctor() {
        return iDDoctor;
    }

    public void setIDDoctor(Integer iDDoctor) {
        this.iDDoctor = iDDoctor;
    }

    public String getSirname() {
        return sirname;
    }

    public void setSirname(String sirname) {
        this.sirname = sirname;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPatientIDPatient() {
        return patientIDPatient;
    }

    public void setPatientIDPatient(int patientIDPatient) {
        this.patientIDPatient = patientIDPatient;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (iDDoctor != null ? iDDoctor.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Doctor)) {
            return false;
        }
        Doctor other = (Doctor) object;
        if ((this.iDDoctor == null && other.iDDoctor != null) || (this.iDDoctor != null && !this.iDDoctor.equals(other.iDDoctor))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return iDDoctor + sirname + name + " | ";
    }

}

我有 bean 类:

package com.tsc.deo.beans;

import com.tsc.deo.entities.Doctor;
import java.io.Serializable;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author IK
 */
@Stateless
@Named
public class DoctorSessionBean implements Serializable, DoctorSession, DoctorSessionLocal {

    public DoctorSessionBean () {}
        // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")

    @PersistenceContext
    private EntityManager em;
//    private Logger log = null;

    public EntityManager getEntityManager() {
        try {

//            Context ctx = (Context) new InitialContext().lookup("java:comp/env");
//            return (EntityManager) ctx.lookup("persistence/LogicalName");
              return em;

        } catch (Exception e) {
//            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", e);
//            throw new RuntimeException(e);
            e.printStackTrace(System.out);
            throw new RuntimeException(e);
        }
    }

    public List<Doctor> getDoctors() {
        return getEntityManager().createNamedQuery("Doctor.findAll").getResultList();
    }

    public void insertDBDoctor(Doctor doc) {

        EntityManager em = getEntityManager();
        em.getTransaction().begin();
        em.persist(doc);
        em.getTransaction().commit();
        em.close();

    }

}

使用远程和本地接口:

package com.tsc.deo.beans;

import com.tsc.deo.entities.Doctor;
import java.util.List;
import javax.ejb.Remote;
import javax.persistence.EntityManager;

/**
 *
 * @author IK
 */
@Remote
public interface DoctorSession {

    public EntityManager getEntityManager();
    public List<Doctor> getDoctors();

}

package com.tsc.deo.beans;

import com.tsc.deo.entities.Doctor;
import java.util.List;
import javax.ejb.Local;
import javax.persistence.EntityManager;

/**
 *
 * @author IK
 */
@Local
public interface DoctorSessionLocal {

    public EntityManager getEntityManager();
    public List<Doctor> getDoctors();

}

我有一个 servlet 正在尝试将新实体存储在 DB 中(连接到 DB 工作正常):

package com.tsc.deo.servlets;

import com.tsc.deo.beans.DoctorSessionBean;
import com.tsc.deo.entities.Doctor;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author IK
 */
@WebServlet(name = "TestUpdateDBServlet", urlPatterns = {"/TestUpdateDBServlet"})
public class TestUpdateDBServlet extends HttpServlet {



    @EJB
    private DoctorSessionBean doctorSessionBean;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        Doctor doc = new Doctor();
        doc.setIDDoctor(8);
        doc.setSirname("Материнка");
        doc.setName("Оля");
        doc.setPatientIDPatient(81);

        doctorSessionBean.insertDBDoctor(doc);

        response.setContentType("text/html;charset=UTF-8");

        try (PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet TestUpdateDBServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet TestUpdateDBServlet at " + request.getContextPath() + "</h1>");
            out.println(doctorSessionBean.getDoctors());
            out.println("</body>");
            out.println("</html>");

        }


    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

}

运行应用程序后,我的浏览器中弹出错误消息:

"javax.servlet.ServletException: 实例化 servlet 类 com.tsc.deo.servlets.TestUpdateDBServlet 时出错

说是找不到DoctorSessionBean:

“javax.naming.NameNotFoundException:com.tsc.deo.beans.DoctorSessionBean#com.tsc.deo.beans.DoctorSessionBean 未找到”

这个问题的原因是什么,我该如何纠正?

现在 NetBeans 中的 GlassFish 4.0 弹出错误消息:

“严重:Web 应用程序 [/DEO] 创建了一个 ThreadLocal,其键类型为 [org.glassfish.pfl.dynamic.codegen.impl.CurrentClassLoader$1](值 [org.glassfish.pfl.dynamic.codegen.impl .CurrentClassLoader$1@2380e2]) 和 [org.glassfish.web.loader.WebappClassLoader] 类型的值(值 [WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)])但在Web 应用程序已停止。线程将随着时间的推移而更新,以避免可能的内存泄漏。"

【问题讨论】:

  • 在 servlet 中将 ejb 的局部变量类型设置为 DoctorSessionLocal

标签: servlets jpa-2.0 ejb-3.1


【解决方案1】:

在你的代码中

@Named
public class DoctorSessionBean implements

这意味着 bean 的名称将是医生会话Bean。如果您不指定名称,它将使用小写的 bean 名称。

look here for http://docs.oracle.com/javaee/6/tutorial/doc/gjbak.html information.

    Giving Beans EL Names
    To make a bean accessible through the EL, use the @Named built-in qualifier:

    import javax.inject.Inject;
    import javax.enterprise.context.RequestScoped;
    import javax.inject.Named;

    @Named
    @RequestScoped
    public class Printer {

        @Inject @Informal Greeting greeting;
        ...
    The @Named qualifier allows you to access the bean by using the bean name, 

与第一个

小写字母。例如,Facelets 页面将 bean 称为打印机。

    You can specify an argument to the @Named qualifier to use a nondefault name:

    @Named("MyPrinter")
    With this annotation, the Facelets page would refer to the bean as MyPrinter.

【讨论】:

  • 谢谢约翰。我只是会检查你的建议。有很好的经验。
  • 约翰,事实并非如此。在我的代码中,我已经使用“@Named”注释进行了编码,并且“@EJB”注释应该为 servlet 进行 bean 注入,但是初始化出现了问题。但就所有人而言,感谢您的帮助。
猜你喜欢
  • 2018-04-16
  • 2015-01-02
  • 2016-06-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多