2011-09-22 22 views
7

mi pregunta es sobre JPA 2.0 con Hibernate, las relaciones @OneToOne y la carga diferida.JPA 2.0/Hibernate: ¿Por qué la recuperación de LAZY con "@OneToOne" funciona de la caja?

En primer lugar mi configuración:

  • primavera 3.0.5.RELEASE
  • SprnigData JPA 1.0.1.RELEASE
  • Hibernate 3.5.2 de final
  • DBMS PostgreSQL 9.0:

Recientemente me encontré con el hecho de que una relación @OneToOne no se puede obtener de forma perezosa (FetchType.LAZY), al menos no sin la instrumentación del código de bytes n, compilar tejido de tiempo o similar. Muchos sitios por ahí dicen que esto, por ejemplo:

La cosa es que, con mi configuración, una carga lenta de una entidad @OneToOne parece funcionar "fuera de la caja", y realmente me gustaría entender por qué. Por favor, eche un vistazo a mi unidad de prueba:

@Test 
@Transactional 
public void testAvatarImageLazyFetching() 
{ 
    User user = new User(); 
    user.setAvatarImage(new AvatarImage()); 

    User = userRepository.save(user); 

    entityManager.flush(); 
    entityManager.clear(); 

    User loadedUser = userRepository.findOne(user.getId()); 
    assertNotNull(loadedUser); 

    PersistenceUtil persistenceUtil = Persistence.getPersistenceUtil(); 

    assertTrue(persistenceUtil.isLoaded(loadedUser)); 
    assertFalse(persistenceUtil.isLoaded(loadedUser, "avatarImage")); 
} 

Este caso prueba es satisfactoria, y en hiberna salida de registro de SQL, puedo ver claramente, que el "avatarImage" no va a ser exagerado, sólo el "usuario" (un solo SELECT, sin JOIN, no tiene acceso a la "AvatarImage" mesa, etc.)

el relationshop @OneToOne unidireccional en la clase de usuario tiene el siguiente aspecto:

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
private AvatarImage avatarImage; 

lo tanto, todo muy simple - Y parece funcionar.

Para repetir mi pregunta: ¿por qué está funcionando? ¿Por qué se puede buscar "AvatarImage" de forma perezosa, aunque se hace referencia a ella con una asociación @OneToOne?

Realmente aprecio la ayuda que puede ofrecer

Muchas gracias!

Respuesta

8

El problema con la carga diferida de la relación OneToOne es solo en la parte inversa de la misma (la que está marcada con el atributo mappedBy). Funciona bien en el lado propietario de la relación. T La diferencia entre ellos es clara en el nivel de la base de datos. En su caso, la pregunta es si la tabla de la base de datos del usuario contiene una identificación de AvatarImage como una de las columnas o al revés. Si la tabla de usuarios tiene una columna con una identificación de AvatarImage, la carga diferida funcionará como dijo "out-of-box" pero no funcionará al revés.

3

La extracción diferida funciona de la caja para las relaciones anotadas @OneToOne, con el proveedor de Hibernate JPA, cuando se realiza alguna forma de instrumentación de bytecode. En su caso, podríamos descartar la instrumentación de tiempo de compilación (deduciendo de su comentario que funciona de fábrica). Esto te deja con la posibilidad de tejer en tiempo de ejecución, lo cual es bastante posible en Hibernate & Spring. En versiones recientes de Hibernate, Javassist se usa como el marco de trabajo de instrumentación bytecode en tiempo de ejecución para Hibernate, a diferencia de la otra alternativa de CGLIB (which has been deprecated since Hibernate 3.5.5).

La cuestión de si Javassist está habilitado en primavera es bastante fácil de responder. Hibernate EntityManager (que es el proveedor de JPA 2.0 que delega en Hibernate Core), requiere Javassist, y por lo tanto, debe estar en el classpath de Hibernate, lo que permite el uso de las clases en tiempo de ejecución.Puede confirmar esto estableciendo un punto de interrupción (en un depurador remoto conectado a su servidor de aplicaciones) y notará que una instancia gestionada Hibernate de la clase User no contendrá una referencia a una instancia AvatarImage; más bien, contendría una referencia a una clase mejorada con un nombre como <package_name>.AvatarImage_$$_javassist_0 (que es el proxy que permite la recuperación diferida).

Cuestiones relacionadas