javax.ejb.EJBException java.lang.IllegalStateException:无法检索unitName的EntityManagerFactory

时间:2014-12-30 22:39:56

标签: java-ee-6 glassfish-4

我正在使用EJB开发JavaEE应用程序。

我有一个名为 Medico 的实体,其代码为:

@Entity
public class Medico implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 1L;

/**
 * 
 */

public Medico(String nome_medico, String morada_medico,
        String esp, GregorianCalendar dnasc_medico, int tel_medico) { //construtor parametrico
    super();
    this.nome_medico = nome_medico;
    this.morada_medico = morada_medico;
    this.esp = esp;
    this.dnasc_medico = dnasc_medico;
    this.tel_medico = tel_medico;
}


@Id
@GeneratedValue
private int cod_medico; //bi
private String nome_medico;
private String morada_medico;
private String esp;
@Temporal(TemporalType.DATE)
private GregorianCalendar dnasc_medico;
private int tel_medico;
private ArrayList<GregorianCalendar> agenda_consultas;
private ArrayList<GregorianCalendar> agenda_atos;
private int total_atos;
private int total_presc;



public int getTotal_presc() {
    return total_presc;
}

public void setTotal_presc(int total_presc) {
    this.total_presc = total_presc;
}

public Medico(){ //construtor vazio
    super();
}

public int getTotal_atos() {
    return total_atos;
}



public void setTotal_atos(int total_atos) {
    this.total_atos = total_atos;
}

public ArrayList<GregorianCalendar> getAgenda_consultas() {
    return agenda_consultas;
}

public void setAgenda_consultas(ArrayList<GregorianCalendar> agenda_consultas) {
    this.agenda_consultas = agenda_consultas;
}

public ArrayList<GregorianCalendar> getAgenda_atos() {
    return agenda_atos;
}

public void setAgenda_atos(ArrayList<GregorianCalendar> agenda_atos) {
    this.agenda_atos = agenda_atos;
}

public int getCod_medico() {
    return cod_medico;
}

public void setCod_medico(int cod_medico) {
    this.cod_medico = cod_medico;
}

public String getNome_medico() {
    return nome_medico;
}

public void setNome_medico(String nome_medico) {
    this.nome_medico = nome_medico;
}

public String getMorada_medico() {
    return morada_medico;
}

public void setMorada_medico(String morada_medico) {
    this.morada_medico = morada_medico;
}

public String getEsp() {
    return esp;
}

public void setEsp(String esp) {
    this.esp = esp;
}

public GregorianCalendar getDnasc_medico() {
    return dnasc_medico;
}

public void setDnasc_medico(GregorianCalendar dnasc_medico) {
    this.dnasc_medico = dnasc_medico;
}

public int getTel_medico() {
    return tel_medico;
}

public void setTel_medico(int tel_medico) {
    this.tel_medico = tel_medico;
}

@Override
public String toString() {
    return "Medico [cod_medico=" + cod_medico + ", nome_medico="
            + nome_medico + ", morada_medico=" + morada_medico + ", esp="
            + esp + ", dnasc_medico=" + dnasc_medico + ", tel_medico="
            + tel_medico + "]";
}
}

然后我创建了一个会话bean实现类:

@Stateless
public class HospitalManagement implements AdministradorSessionRemote,GestorSessionRemote {

/**
 * Default constructor. 
 */
@PersistenceContext(unitName="Hospital")
private EntityManager em;
public HospitalManagement() {
    // TODO Auto-generated constructor stub
}


@Override
public String cria_medico(String nome_medico, String morada_medico,
        String esp, GregorianCalendar dnasc_medico, int tel_medico) {
        Medico md = new Medico (nome_medico, morada_medico, esp, dnasc_medico,tel_medico);
    em.persist(md);
    return "Medico "+Integer.toString(md.getCod_medico())+" criado!"; 
}

此类实现两个接口,但上述方法仅用于以下方法:

@Remote
public interface GestorSessionRemote {


public String cria_medico(String nome_medico,String morada_medico,String esp,GregorianCalendar dnasc_medico, int tel_medico);
public String procura_nome_medico(String nome);
public String procura_cod_medico(int cod);
public String altera_morada_med(int cod, String morada);
public String altera_telemovel_med(int cod, int tel);

然后我创建了一个客户端:

public class GestorClient {

public static void main(String[] args){

        InitialContext ctx =new InitialContext();
        GestorSessionRemote g=(GestorSessionRemote)ctx.lookup("java:global/HospitalEAR/Hospital/HospitalManagement!Sessions.GestorSessionRemote");
        System.out.println(g.cria_medico(nomem, moradam, esp,cal,telm));

其中方法的参数是通过键盘扫描获得的。

我还创建了以下persistence.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence    http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="Hospital">
    <properties>
    <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
    </properties>
    </persistence-unit>
    </persistence>

当我尝试部署应用程序时,会发生错误。这是完整的堆栈跟踪:

Exception in thread "main" javax.ejb.EJBException
at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:748)
at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:698)
at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:503)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2074)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2044)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:212)
at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:79)
at com.sun.proxy.$Proxy236.cria_medico(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie.dispatchToMethod(ReflectiveTie.java:143)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:173)
at com.sun.corba.ee.impl.protocol.ServerRequestDispatcherImpl.dispatchToServant(ServerRequestDispatcherImpl.java:528)
at com.sun.corba.ee.impl.protocol.ServerRequestDispatcherImpl.dispatch(ServerRequestDispatcherImpl.java:199)
at com.sun.corba.ee.impl.protocol.MessageMediatorImpl.handleRequestRequest(MessageMediatorImpl.java:1549)
at com.sun.corba.ee.impl.protocol.MessageMediatorImpl.handleRequest(MessageMediatorImpl.java:1425)
at com.sun.corba.ee.impl.protocol.MessageMediatorImpl.handleInput(MessageMediatorImpl.java:930)
at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:213)
at com.sun.corba.ee.impl.protocol.MessageMediatorImpl.handleRequest(MessageMediatorImpl.java:694)
at com.sun.corba.ee.impl.protocol.MessageMediatorImpl.dispatch(MessageMediatorImpl.java:496)
at com.sun.corba.ee.impl.protocol.MessageMediatorImpl.doWork(MessageMediatorImpl.java:2222)
at com.sun.corba.ee.impl.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
at com.sun.corba.ee.impl.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
Caused by: java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName Hospital
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.init(EntityManagerWrapper.java:138)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTxRequiredCheck(EntityManagerWrapper.java:158)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.doTransactionScopedTxCheck(EntityManagerWrapper.java:151)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.persist(EntityManagerWrapper.java:281)
at Sessions.HospitalManagement.cria_medico(HospitalManagement.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:55)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:205)
... 19 more

有人可以帮我理解为什么会这样吗?

1 个答案:

答案 0 :(得分:2)

显而易见的问题是,您未在jta-data-source中指定transaction-typepersistence.xml

jta-data-source指定如下:

  <persistence-unit name="Hospital">
    <jta-data-source>jdbc/sample</jta-data-source>
  </persistence-unit>

您必须在Glassfish实例中创建JDBC资源。为此,请在http://localhost:4848下打开Glassfish Admin GUI,并在Resources - &gt;下创建连接池JDBC Connection Pools。然后在Resources - &gt;下创建 JDBC资源JDBC Resources名为jdbc/sample,并使其引用新的连接池。

此外,看起来服务器以某种方式认为您要使用transaction-type RESOURCE_LOCAL,这要求您指定EntityManagerFactory来获取EntityManager的实例。

JTA应该是Java EE环境中的默认transaction-type,但您可能需要在transaction-type中明确指定persistence.xml,如下所示:

<persistence-unit name="Hospital" transaction-type="JTA">

另见: