¿Por qué es un objeto encontrado por id en JPA, pero no a través de una consulta JPQL?
Pregunta
Tengo un caso de prueba JUnit 4 con la anotación @Transactional
primavera que salva un objeto, y luego los intentos de encontrarlo. El caso de prueba pasa cuando uso esta aplicación:
@Override
public EventSummary findEventSummaryById(Integer id) {
return em.find(EventSummary.class, id);
}
Se produce un error cuando se utiliza esta aplicación (y luego cambio el método que yo llamo en el caso de la prueba):
@Override
public EventSummary findEventSummary(Integer id) {
Query query = em.createQuery("select es from EventSummary as es where es.id = :id");
query.setParameter("id", id);
EventSummary result = (EventSummary) query.getSingleResult();
return result;
}
Solución
Si está utilizando el modo de descarga por defecto (AUTO
) y si se está ejecutando la consulta dentro de una transacción, las garantías de especificación JPA que una consulta no devolverá datos obsoletos o incorrectos:
3.6.2 Consultas y FlushMode
La configuración del modo afecta al ras como resultado de una consulta de la siguiente manera.
Cuando se ejecutan las consultas dentro de una transacción, si
FlushModeType.AUTO
se establece en el objetoQuery
, o si el ajuste del modo de descarga para la persistencia contexto esAUTO
(por defecto) y una ajuste del modo de color no ha sido especificado para el objetoQuery
, la proveedor de persistencia es responsable para asegurar que todos los cambios a la estado de todas las entidades del contexto de persistencia que podría potencialmente afectar el resultado de la consulta son visibles para el procesamiento de la consulta. El proveedor de persistencia implementación puede lograr esto mediante la lavado de dichas entidades a la base de datos o por algún otro medio. SiFlushModeType.COMMIT
se establece, el efecto de los cambios realizados a entidades de el contexto de persistencia en las consultas está especificado.public enum FlushModeType { COMMIT, AUTO }
Si no hay ninguna transacción activa, el proveedor de persistencia no debe lavarlo a la base de datos.
Si se asume que está utilizando AUTO
, consulte la parte transaccional.
Otros consejos
?he entidad está en la sesión actual (gestor de la entidad) - se encuentra en estado persistente, a la espera de ser eliminados. El método GET primero comprueba el contenido de la sesión, y si no se encuentran vueltas a la base de datos subyacente. En su caso, la entidad acaba de ser salvado en la misma sesión, por lo que se encontró y regresó.
Actualización: resultó que el problema es el uso de un gestor de transacciones incorrectas, por lo tanto, la entidad no se ha volcado a la base de datos. Ver explicación de Pascal.
en el primer caso, el ID es un número entero
en la segunda, el ID es una cadena
Integer Nunca será igual a una cadena