Search code examples
javahibernatejpapersistence

EntityManager becomes null


I have a curious error when using EntityManager. Here is an extract of the code.

@PersistenceUnit
EntityManagerFactory factory;
@Resource
UserTransaction transaction;
EntityManager em;

Inside the method:

try{
datos.crearDatos(docEntrada);
ctx.setDatosMensajes(datos);
factory=Persistence.createEntityManagerFactory("ealia");
transaction = (UserTransaction)new InitialContext().lookup("java:comp/UserTransaction");
EntityManager em = factory.createEntityManager();

//Do whatever it does, everything works fine.
// HERE THE ENTITY MANAGER IS NOT NULL
}
catch (Exception e){

}
finally{
    // HERE THE ENTITY MANAGER IS NULL 
        try {
            SVCSMensajes.grabarMensajeSalida(datos, Constantes.MENSAJE_SALIDA_WS_USUARIOS_GESTION, Constantes.NOMBRE_SERVICIO_WS_USUARIOS_GESTION, Constantes.MENSAJE_ENTRADA_WS_USUARIOS_GESTION, em, ctx,transaction);
        } catch (CecaException e) {
            // No devolvemos error en este caso
        }

        em.close();
        factory.close();
  }

I don't understand why the eentity manager becomes null inside the finally, when just at the end of the try is not null, when everything is working fine, there are no exceptions. I trace the variable and it becomes null with no intermediate instructions in between.

Instead, if I rearrange the code this way

    factory=Persistence.createEntityManagerFactory("ealia");
    transaction = (UserTransaction)new  InitialContext().lookup("java:comp/UserTransaction");
    EntityManager em = factory.createEntityManager();

    try{
        datos.crearDatos(docEntrada);
        ctx.setDatosMensajes(datos);
    ....
    }
    ....

everything works fine. Can anyone explain it, please?


Solution

  • You declared em as a local variable of the try block here:

    EntityManager em = factory.createEntityManager();
    

    The variable is not visible to the finally block. That block uses the one you declared as a field of your class.

    What you need is change the above line to:

    em = factory.createEntityManager();
    

    In order to initialize your field, not a local variable.

    Even better, you might want to inject your EntityManager instead of creating it manually.