2010-02-09 13 views
11

En Hibernate cuando recuperar una entidad a través de una carga, si accede a que descriptor de acceso Identificación de la entidad que no inicializa el proxy:¿Cuándo recupera el ID de un proxy de Hibernate inicializar el proxy?

Property myProp = (Property) session.load(Property.class, myId); 
myProp.getId(); // Doesn't load the proxy 
myProp.getDescription(); // Loads the proxy from the database hit 

Sin embargo, no tengo muy claro cuáles son las reglas de representación de la asociación de carga. Tenía la impresión de que cuando recuperas una entidad a través de una consulta HQL o Criteria se aplican las mismas reglas.

Cada Property en mi código tiene un Company. El Company se declara como tal:

@ManyToOne(fetch = FetchType.LAZY, optional=false) 
@JoinColumn(name = "company_id", nullable=false) 
private Company company; 

Sin embargo, en mi código que estoy actualmente recibiendo N + 1 le permite elegir cuando se repite a través de la Properties porque el Company se carga cuando llamo Company.getId().

En el objeto Company y Property, el campo de id es un Long anotado con @Id.

¿Hay alguna otra consideración que me falta para evitar la carga de la entidad Company?

+0

La respuesta es un gran comienzo, pero el primer comentario es la mejor respuesta. Asegúrate de leer el enlace que publicó Gennady Shumakher. Además, si alguien tiene curiosidad, hay un error en la base de datos de Hibernate sobre este problema que encontré: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3718 – jbarz

Respuesta

10

No funciona como se esperaba simplemente porque tiene que usar el acceso a la propiedad en lugar de acceso de campo.

En lugar de

@ManyToOne(fetch=FetchType.LAZY, optional=false) 
@JoinColumn(name="COMPANY_ID", nullable=false) 
private Company company; 

Uso

@ManyToOne(fetch=FetchType.LAZY, optional=false) 
@JoinColumn(name="COMPANY_ID", nullable=false) 
public Company getCompany() { 
    return this.company; 
} 

cuida que no se puede utilizar de acceso a propiedades y campo de acceso al mismo tiempo. Entonces, , debe elegir un enfoque.

respetos,

+2

+1 - hay una explicación más detallada disponible aquí: http://www.catalysts.cc/en/blog/ejb-annotations-hibernate-lazy-loading/ –

+0

veo, al leer el artículo parece que el enfoque correcto es en realidad cambiar el objeto de la empresa para que el las anotaciones están todas en los getters. Es más importante que el método getId() esté anotado en lugar de getCompany() en la propiedad. – jbarz

+1

Java Persistence with Hibernate - (www.manning.com/bauer2) menciona este punto en "13.1.3 Comprensión de los proxies": 'Siempre que acceda solo a la propiedad del identificador de la base de datos, no es necesaria la inicialización del proxy de . (Tenga en cuenta que esto no es cierto si asigna la propiedad identificador con acceso directa sobre el terreno; Hibernate entonces ni siquiera sabe que existe método la getId() Si usted lo llama, el proxy tiene que ser inicializado..) ' . –

Cuestiones relacionadas