【发布时间】: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