Pregunta

Podemos usar el modo de Hibernación (con JPA) y de Hibernación Envers de persistir en la historia de los objetos.La aplicación web se ejecuta en muchos hilos, algunos de ellos son creados por RMI método de invocación de otras aplicaciones, algunos de ellos son creados por la aplicación en sí y algunos de ellos son creados para realizar peticiones http (que generan puntos de vista).

También utilizamos la Sesión Abierta En la Vista patrón de gestionar las sesiones, por lo que nuestra web.xml contiene:

<filter>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>openEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

La base de datos es utilizado por los DAOs, todos ellos tienen EntityManagers inyectado por la Primavera.

@PersistenceContext
protected EntityManager em;

@PersistenceUnit
protected EntityManagerFactory emf;

Todo funcionaba muy bien antes de decidirnos a usar el modo de Hibernación Envers.Cuando cualquier hilo que no es una vista de generación de subproceso se ejecuta el código para obtener una versión antigua de un objeto, se produce la excepción.

@Override
public O loadByRevision(Long revision, Long id) {
    @SuppressWarnings("unchecked")
    O object = (O) AuditReaderFactory.get(em).createQuery().forEntitiesAtRevision(getBaseClass(), revision.intValue())
            .add(AuditEntity.id().eq(id)).getSingleResult();
    return object;
}

Excepción en el hilo "Programador" org.hibernate.SessionException:La sesión está cerrada!en org.hibernate.interna.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:129) en org.hibernate.interna.SessionImpl.createQuery(SessionImpl.java:1776) en org.hibernate.envers.herramientas.consulta.QueryBuilder.toQuery(QueryBuilder.java:226) en org.hibernate.envers.consulta.impl.AbstractAuditQuery.buildQuery(AbstractAuditQuery.java:92) en org.hibernate.envers.consulta.impl.EntitiesAtRevisionQuery.lista(EntitiesAtRevisionQuery.java:108) en org.hibernate.envers.consulta.impl.AbstractAuditQuery.getSingleResult(AbstractAuditQuery.java:110) (...)

Cuando el código se ejecuta por el punto de vista de generación de hilo funciona bien.También, la no-envers código en DAO funciona bien para cada subproceso.Por ejemplo, el siguiente fragmento de

@Override
public O load(Long id) {
    final O find = em.find(getBaseClass(), id);
    return find;
}

puede ser ejecutado por RMI hilos sin problemas.

¿Por qué no ver los hilos de los métodos de llamada de la gerente de la entidad, sin excepciones, pero no pueden utilizar Envers' AuditReaderFactory con la gerente de la entidad?Pensé que tal vez llamar a un método en el gerente de la entidad, se crea una sesión temporal, pero que no sucede cuando se utiliza Envers, ¿es eso cierto?

¿Cuál es la mejor manera de arreglar ese problema (de modo que el AuditReaderFactory puede ser utilizado de cada hilo)?

¿Fue útil?

Solución

No encontramos la razón de por qué no subprocesos de interfaz de usuario llamadas de método en EntityManagerFactory funcionó, pero las llamadas de método en AuditReaderFactory no.De todos modos, hemos encontrado una manera de solucionarlo.

La solución fue para anotar los métodos con @Transactional.Si cualquier método en la cadena de llamadas antes de llamar a la AuditReaderFactory se ha marcado como @Transactional, no se SessionException no subprocesos de interfaz de usuario.

Resultó que hacer loadByRevision transaccional, no era suficiente.Si un objeto devuelto por el método de contenidos de carga diferida persistente bolsas, el acceso a ellos fuera de la loadByRevision el ámbito del método causado LazyInitializationException (no hubo sesión).

La solución final fue para asegurarse de que si algún hilo se quiere cargar algunos datos de la base de datos, toda la carga (obtención de un objeto y el acceso de carga diferida colecciones) se llevará a cabo dentro de un método anotado con @Transactional.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top