2010-01-21 23 views
13

Uso JPA (Hibernate) con Spring. cuando quiero carga perezosa una propiedad Stirng i utilizar esta sintaxis:@Basic (fetch = FetchType.LAZY) no funciona?

@Lob 
@Basic(fetch = FetchType.LAZY) 
public String getHtmlSummary() { 
    return htmlSummary; 
} 

Pero cuando miro el SQL que crea Hibernate, parece que esta propiedad no está cargado ligeramente? También utilizo esta clase org.hibernate.tool.instrument.javassist.InstrumentTask en el script ANT para instrumentar esta propiedad, pero parece que no funciona.

Por favor, ayúdame.

Khosro.

Respuesta

-3

La recuperación diferida solo se aplica a las referencias a otras entidades o colecciones de entidades. No se aplica a valores como String o int.

+0

No es cierto, los LOB pueden cargarse vagamente. Consulte la Sección 2.2.2.1 de la documentación de anotaciones de hibernación: http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e342 - específicamente la propiedad 'detailedComment' en ese ejemplo y la nota debajo. – Cowan

1

Según la especificación de JPA, dicen que incluso si utiliza anotar una propiedad que se va a buscar perezosamente, no se garantiza que se aplique, por lo que las propiedades pueden cargarse o no de forma perezosa (depende del implementador de JPA) Sin embargo, si especifica que debe buscarlos con impaciencia, entonces el implementador de JPA debe cargarlos con entusiasmo.

Conclusión: @Basic (fetch = FetchType.LAZY) puede funcionar o no, depende del implementador de JPA.

+0

Yo uso Hibernate, y describo el problema aquí http://stackoverflow.com/questions/2112508/basicfetch-fetchtype-lazy-does-not-work/2112846#2112846 en la respuesta de Henning – Khosro

4

Lazy Lob carga requeriría que la instrumentación bytecode funcione correctamente, por lo que no está disponible por defecto en ninguna implementación de JPA de la que tenga conocimiento.

Su mejor opción es colocar el Lob en una entidad separada, como HtmlSummary, y utilizar una asociación de uno a uno cargada de forma perezosa.

+0

¿Podría decirme cómo instrumentar? ? Utilizo la implementación Hibernate de JPA. También hago las instrucciones descritas aquí, pero no funciona: http: //docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-fetching-lazyproperties – Khosro

+0

@Khosro: ¿Qué dice la salida del registro Ant? "No funciona" no es suficiente información para diagnosticar su problema, me temo. – Henning

+0

Bueno, mi tarea Ant funciona bien, y la salida es [instrumento] aceptando transformación de acceso de campo [N ews.textBody] pero después de ejecutar las aplicaciones obtuve esta excepción org.hibernate.MappingException: No se pudo determinar el tipo para: org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback, en la tabla: Noticias, para columnas: [org.hibernate.mapping.Column (interceptFieldCallback)] en este caso utilizo org.hibernate.tool.instrument.cglib. InstrumentTask para instrumentar. En otro caso cuando uso org.hibernate.tool.instrument.javassist.InstrumentTask, las aplicaciones se implementan pero la carga diferida no funciona – Khosro

3

Uso FieldHandled con @Basic(fetch=FetchType.LAZY) obras:

public class myFile implements Serializable, FieldHandled 
{ 

    private FieldHandler  fieldHandler; 

    @Lob 
    @Basic(fetch = FetchType.LAZY) 
    @Column(name = "CONTENT") 
    protected byte[]   content; 
+0

¿Alguien ha intentado esto? No parece funcionar para mí. –

3
@Entity 
public class User implements FieldHandled { 

    @Id 
    private String uid; 

    private String uname; 

    private int age; 

    @Lob 
    @Basic(fetch = FetchType.LAZY) 
    private byte[] img; 

    private FieldHandler fieldHandler; 

    public User() { 
    } 

    // getter() and setter() of uid, uname, age 

    public byte[] getImg() { 
     // if User user = new User() then fieldHandler is null 
     // if User user = entityManager.find(User.class, "001") then fieldHandler is not null 
     if(img != null) { 
      return img; 
     } 

     if (fieldHandler != null) { 
      return (byte[]) fieldHandler.readObject(this, "img", img); 
     } else { 
      return null; 
     } 
    } 

    public void setImg(byte[] img) { 
     this.img = img; 
    } 

    public void setFieldHandler(FieldHandler fieldHandler) { 
     this.fieldHandler = fieldHandler; 
    } 

    public FieldHandler getFieldHandler() { 
     return fieldHandler; 
    } 
} 

utilizo Hibernate4 h2database.I estoy seguro de carga lenta puede funcionar bien por mi código.

Hibernate: select user0_.uid as uid1_0_0_, user0_.age as age2_0_0_, user0_.uname as uname4_0_0_ from User user0_ where user0_.uid=?

Hibernate: select user_.img as img3_0_ from User user_ where user_.uid=?

si el uso repository.save(User) para añadir un nuevo usuario va a estar bien, pero actualizar un usuario va a lanzar una excepción

java.lang.ClassCastException: org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer$1 cannot be cast to java.sql.Blob

que sugieren el uso repository.delete(userid) antes de repository.save en una transaccional, entonces funcionará bien.

3

En primer lugar, debe saber que las especificaciones de JPA especifican claramente que LAZY es solo una sugerencia para los proveedores de JPA, por lo que no es un requisito obligatorio.

Para el tipo básico de recuperación perezosa para trabajar, es necesario enable bytecode enhancement y establece explícitamente la propiedad de configuración enableLazyInitialization a true:

<plugin> 
    <groupId>org.hibernate.orm.tooling</groupId> 
    <artifactId>hibernate-enhance-maven-plugin</artifactId> 
    <version>${hibernate.version}</version> 
    <executions> 
     <execution> 
      <configuration> 
       <enableLazyInitialization>true</enableLazyInitialization> 
      </configuration> 
      <goals> 
       <goal>enhance</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 
0

creo que sería similar a EclipseLink, no es necesario haber permitido tejer de lo contrario, la configuración de búsqueda no tiene efecto. El tejido requiere acceso de bytecode. Esto podría ayudar: https://stackoverflow.com/a/18423704/7159396

Cuestiones relacionadas