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// Método Singleton
private List<Curso> listaCursos;
public List<Curso> getListaCursos() throws DaoException {
if ( listaCursos == null ) {
listaCursos = new CursoDao().traerTodos();
}
return listaCursos;
}
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// Instancia lista de cursos
List<Curso> listaCursos1;
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// Instancia nueva lista de cursos
List<Curso> listaCursos2;
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// Método que devuelve la lista de todos los cursos
public List<Curso> traerTodos() throws DaoException {
em = getEntityManager();
List<Curso> cursos;
try {
Query q = em.createQuery("SELECT c FROM Curso c ORDER BY c.codigo ASC");
cursos = q.getResultList();
logger.log(Level.INFO, "Lista de cursos devuelta satisfactoriamente ({0})", cursos.size());
logger.log(Level.WARNING, ex.getMessage(), ex);
throw new DaoException("Error al traer Lista de Cursos:" + ex.getMessage(), ex);
} finally {
if (em != null && em.isOpen()) {
em.close();
}
}
return cursos;
}
El EntityManager se cierra al finalizar y se manejan las excepciones.
Acá un pequeño ejemplo de mi problema:
Código Java:
Ver original// Ejemplo
public static void main
(String[] args
) { try {
FactoryDao factoryDao = new FactoryDao();
List<Curso> listaCursos1;
listaCursos1 = Utilitarios.getInstance().getListaCursos();
System.
out.
println("Lista Original: " + listaCursos1
);
// Hago algunos cambios sobre la listaCursos1
listaCursos1.remove(0);
System.
out.
println("Lista Cursos 1: " + listaCursos1
);
// Creo una nueva lista
List<Curso> listaCursos2;
listaCursos2 = Utilitarios.getInstance().getListaCursos();
// La (nueva) lista 2 refleja los cambios que se le hicieron a la lista 1.
System.
out.
println("Lista Cursos 2: " + listaCursos2
); e.printStackTrace();
}
}
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.