EntityManager.encuentra, no puede encontrar la entidad, pero el uso de la API de Criterios ¿

He encontrado un lugar extraño caso en Java EE 6, donde el uso de la JPA EntityManager del find método, junto con una entidad primaria id devuelve null, pero el uso de la API de Criterios para seleccionar todas las entidades con las que funciona el identificador de multa.

Este es el código que estoy usando para find:

//Always returns null, even for records I know for sure are in there.
user = em.find(User.class, userId);

…y este es el código que estoy usando con la API de Criterios:

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> u = criteria.from(User.class);
TypedQuery<User> query = em.createQuery(
    criteria.select(u).where(builder.equal(u.get("id"), userId)));
user = query.getSingleResult();

Alguna idea de por qué find devuelve null pero los Criterios encuentra el Usuario? Traté de estos dos métodos alternativos en el mismo lugar en el programa.

Aquí están las partes pertinentes de la entidad Usuario:

@Entity
@Table(name = "USERS")
@Access(AccessType.PROPERTY)
public class User implements Serializable {
    ...
    private Long id;
    ...
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_generator")
    @SequenceGenerator(name = "user_id_generator", sequenceName = "user_sequence", allocationSize = 1)
    @Column(name="id")
    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    ...
}
No estoy seguro si esto hace una diferencia, pero es userId Mucho o tal vez un Entero en tu código?
Es un Largo, he comprobado que.
Me acaba de experimentar este problema con Hibernate 4.1.8.Final

OriginalEl autor cdmckay | 2010-07-08

6 Kommentare

  1. 11

    Me solucionaron el problema. Fue debido a un campo en la base de datos null donde no debería haberse permitido. Esto fue debido a que me editarlo a mano. Después de agregar un valor para ese campo, el problema desapareció.

    Puede que desee hacer valer not NULL para la columna para el futuro de salvaguardia.
    saludos para compartir, me salvó el día
    100% de acuerdo. Este no era mi base de datos, pero me enseñó el valor de uso de restricciones para hacer cumplir la integridad de los datos 😉
    Mi apuesta es que encontrar intenta obtener de la entidad mediante combinaciones internas ya que esto puede causar vacía de conjuntos de resultados

    OriginalEl autor cdmckay

  2. 3

    Qué proveedor está utilizando?

    De dónde eres la ejecución de este hallazgo, dentro o fuera de una transacción? Estás lavado y limpieza de la EM antes de la encontrar?

    El uso de EclipseLink como proveedor, y mi propio modelo similar, yo no soy capaz de reproducir este.

    Suponiendo que su proveedor de registro de SQL, están viendo SQL que va a la base de datos en la encontrar? ¿Qué hace el SQL aspecto, y no se ejecutará correctamente en SQL Plus, etc…

    Yo debería ser el lavado de la EM antes de la encontrar? Estoy usando Hibernate como mi proveedor.
    Yo estoy corriendo en un @Stateless EJB. La EM está decorado con un @PersistanceContext(unitName = "xxx_persistence"). Me voy a referir a los registros de SQL y ver lo que puedo encontrar.
    Aceptar revisé los SQL y estaba muy sorprendido de ver la diferencia entre las dos consultas: la «encontrar» la versión fue haciendo un mil millones de combinaciones, mientras que los «criterios» de la consulta fue sólo el acaparamiento de la tabla de usuarios. Alguien escribió que la entidad archivos así que voy a tener que cavar a través de aquellos para averiguar lo que está causando esto.
    «yo debería ser el lavado de la EM antes de la encontrar? Estoy usando Hibernate como mi proveedor.» No (la realización de una consulta a ras cambios pendientes).

    OriginalEl autor Peter Krogh

  3. 3

    De confirmar la solución. Lo mismo me pasó a mí. Yo había collumns marcado como NOT NULL, durante la prueba en mi aplicación me cambié la limitación de apagado en la base de datos para dos collumns (claves foráneas), sin embargo no cambia el (optional = false) atributo de @ManyToOne relación en mi clase de entidad. Después de eliminar el atributo, por lo que el modelo era coherente con la base de datos, todo comenzó a funcionar bien.
    Extraño que el medio ambiente no produce una advertencia o una excepción de algún tipo.

    OriginalEl autor pkudlacik

  4. 1

    Doble verificación que se pasa un Long en el siguiente fragmento:

    //Always returns null, even for records I know for sure are in there.
    user = em.find(User.class, userId);

    Si esto no ayuda, activar el inicio de sesión de SQL para ver lo que está sucediendo y comparar el comportamiento en ambos casos.

    Yo depurar y comprobar que efectivamente era Mucho.
    Me encontré con su código de mi lado y no puedo reproducir (como era de esperar para ser honesto). Probado con Hibernate EM 3.5.3-Final.
    Sí, yo creo que tiene que ver con la forma en que el Usuario de la entidad está anotado.

    OriginalEl autor Pascal Thivent

  5. 0

    Una de las razones podría ser que el campo «id» no ha sido correctamente marcado como el id de la entidad Usuario.

    OriginalEl autor bashflyng

  6. 0

    Como una comprobación de validez de la depuración del código, tomando el tiempo necesario antes de ejecutar el buscar para ejecutar un manual de consulta en la base de datos de asegurar un adecuado registro de Usuario con el id que usted espera.

    Si no está en la base de datos, asegúrese de que el gerente de la entidad ha sido eliminado o que la transacción actual se ha cometido.

    Por ejemplo, si usted está usando Hibernate como el proveedor, es posible que el objeto es «persisted» sólo en la memoria caché y los cambios no han sido empujados a la base de datos. En consecuencia, los criterios que va a través de Hibernación de la implementación de recuperar el objeto, pero el gerente de la entidad encontrar no será capaz de localizar el objeto.

    Esta es una buena sugerencia, pero yo sé que no está en caché, porque podría mirar en la base de datos antes de que incluso se inicia con la aplicación.

    OriginalEl autor apiri

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea