Tema: Duda con JPA
Ver Mensaje Individual
  #1 (permalink)  
Antiguo 10/12/2012, 20:49
Avatar de farfamorA
farfamorA
 
Fecha de Ingreso: noviembre-2010
Ubicación: Lima
Mensajes: 136
Antigüedad: 13 años, 5 meses
Puntos: 24
Duda con JPA

Saludos Comunidad Foros del Web, nuevamente recurro a ustedes en busca de algunas ideas. Estoy haciendo unas cosillas con JPA y me pasa algo que me está intrigando mucho.
Veamos, estoy usando EclipseLink (JPA 2.0) y una base de datos Apache Derby embebida.
Básicamente, lo que necesito es crear (muchos) otros objetos a partir de una lista de la entidad Curso. En este proceso de creación, siempre voy a usar la lista de cursos original, es decir, no necesito (y no quiero, por un tema de eficiencia) consultar una y otra vez a la base de datos para que me devuelva la misma lista. Quiero usar siempre la misma instancia para generar mis otros objetos.
Para esto, uso el patrón Singleton:
Código Java:
Ver original
  1. // Método Singleton
  2.     private List<Curso> listaCursos;
  3.  
  4.     public List<Curso> getListaCursos() throws DaoException {
  5.         if ( listaCursos == null ) {
  6.            listaCursos = new CursoDao().traerTodos();
  7.         }
  8.         return listaCursos;
  9.     }
Hasta ahí todo bien, sólo hace la consulta a la base de datos la primera vez (cuando listaCursos es nulo).

El problema viene a continuación:

Creo un List de la entidad Curso llamado listaCursos1 y en esta lista guardo la lista de cursos.
Código Java:
Ver original
  1. // Instancia lista de cursos
  2.     List<Curso> listaCursos1;
  3.     listaCursos1 = Utilitarios.getInstance().getListaCursos();
Itero la listaCursos1, le hago algunos cambios (le "seteo" otras valores a sus atributos).
Creo una nueva lista de cursos llamada listaCursos2.
Código Java:
Ver original
  1. // Instancia nueva lista de cursos
  2.     List<Curso> listaCursos2;
  3.     listaCursos2 = Utilitarios.getInstance().getListaCursos();
Ahora, pasa que la listaCursos2 no es igual a lista original (la del patrón singleton, la que viene de la base de datos), sino que es igual a la listaCursos1. Todos los cambios que he realizado a la listaCursos1 se han realizado también sobre la listaCursos original. ¿Por qué pasa eso?

Adjunto el método que me devuelve la lista de cursos desde la base de datos.
Código Java:
Ver original
  1. // Método que devuelve la lista de todos los cursos
  2.     public List<Curso> traerTodos() throws DaoException {
  3.         em = getEntityManager();
  4.         List<Curso> cursos;
  5.         try {
  6.             Query q = em.createQuery("SELECT c FROM Curso c ORDER BY c.codigo ASC");
  7.             cursos = q.getResultList();
  8.             logger.log(Level.INFO, "Lista de cursos devuelta satisfactoriamente ({0})", cursos.size());
  9.         } catch(Exception ex){
  10.             logger.log(Level.WARNING, ex.getMessage(), ex);
  11.             throw new DaoException("Error al traer Lista de Cursos:" + ex.getMessage(), ex);
  12.         } finally {
  13.             if (em != null && em.isOpen()) {
  14.                 em.close();
  15.             }
  16.         }
  17.         return cursos;
  18.     }
El EntityManager se cierra al finalizar y se manejan las excepciones.

Acá un pequeño ejemplo de mi problema:
Código Java:
Ver original
  1. // Ejemplo
  2.     public static void main(String[] args) {
  3.         try {
  4.             FactoryDao factoryDao = new FactoryDao();
  5.            
  6.             List<Curso> listaCursos1;
  7.             listaCursos1 = Utilitarios.getInstance().getListaCursos();
  8.             System.out.println("Lista Original: " + listaCursos1);
  9.            
  10.             // Hago algunos cambios sobre la listaCursos1
  11.             listaCursos1.remove(0);
  12.             System.out.println("Lista Cursos 1: " + listaCursos1);
  13.            
  14.             // Creo una nueva lista
  15.             List<Curso> listaCursos2;
  16.             listaCursos2 = Utilitarios.getInstance().getListaCursos();
  17.             // La (nueva) lista 2 refleja los cambios que se le hicieron a la lista 1.
  18.             System.out.println("Lista Cursos 2: " + listaCursos2);
  19.         } catch (Exception e) {
  20.             e.printStackTrace();
  21.         }
  22.     }

Y no entiendo por qué pasa eso, ¿qué podría hacer para salvar esta situación?
Gracias por su atención, espero ansioso sus observaciones.