2010-01-21 1 views
13

Io uso JPA (Hibernate) con Spring. Quando voglio caricare pigro una proprietà Stirng io uso la seguente sintassi:@Basic (fetch = FetchType.LAZY) non funziona?

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

Ma quando guardo lo SQL che crea ibernazione, a quanto pare questa struttura non è caricato in modo pigro? Io uso anche questa classe org.hibernate.tool.instrument.javassist.InstrumentTask in ANT script per strumentare questa proprietà ma sembra che non funzioni.

Per favore aiutatemi.

Khosro.

risposta

-3

pigro recupero si applica solo ai riferimenti ad altre entità o collezioni di entità. Non si applica a valori come String o int.

+0

Non è vero, LOB può essere pigro-caricato. Vedere la Sezione 2.2.2.1 della documentazione di hibernate-annotations: http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e342 - in particolare la proprietà 'detailedComment' su quell'esempio e la nota sotto di esso. – Cowan

1

dalle specifiche di JPA si dice che anche se si annota una proprietà da recuperare pigramente, non è garantito che venga applicata, quindi le proprietà possono essere caricate pigramente o meno (dipende dall'implementatore di JPA) , tuttavia, se si specifica che è necessario recuperarli in modo Eagerly, l'implementatore JPA deve caricarli con entusiasmo.

Riga inferiore: @Basic (fetch = FetchType.LAZY) può o non può funzionare, dipende dall'implementatore JPA.

+0

Uso Hibernate e descrivo il problema qui http://stackoverflow.com/questions/2112508/basicfetch-fetchtype-lazy-does-not-work/2112846#2112846 nella risposta di Henning – Khosro

4

Lazy Lob caricamento richiede che la strumentazione bytecode funzioni correttamente, quindi non è disponibile per impostazione predefinita in qualsiasi implementazione JPA di cui sono a conoscenza.

La soluzione migliore è mettere l'Lob in un'entità separata, ad esempio HtmlSummary, e utilizzare un'associazione one-to-one caricata pigramente.

+0

Per favore, dimmi come utilizzare lo strumento ? Uso l'implementazione Hibernate di JPA.Io anche le istruzioni descrivono qui ma, non funziona: http: //docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-fetching-lazyproperties – Khosro

+0

@ Khosro: cosa dice l'uscita del registro Ant? "Non funziona" non è abbastanza informazioni per diagnosticare il tuo problema, temo. – Henning

+0

Bene, l'attività Ant funziona bene e l'output è [strumento] che accetta la trasformazione dell'accesso al campo [N ews.textBody] ma dopo aver eseguito le app ho ottenuto questa eccezione org.hibernate.MappingException: Impossibile determinare il tipo per: org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback, a tavola: Notizie, per le colonne: [org.hibernate.mapping.Column (interceptFieldCallback)] in questo caso uso org.hibernate.tool.instrument.cglib. InstrumentTask per strumentazione. In un altro caso quando utilizzo org.hibernate.tool.instrument.javassist.InstrumentTask, le app vengono distribuite ma il caricamento lazy non funziona – Khosro

3

Usa FieldHandled con @Basic(fetch=FetchType.LAZY) opere:

public class myFile implements Serializable, FieldHandled 
{ 

    private FieldHandler  fieldHandler; 

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

Qualcuno ha provato questo? Non sembra funzionare per me. –

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; 
    } 
} 

Io uso Hibernate4 h2database.I sono sicuro lazy loading può funzionare bene per il mio codice.

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=?

se l'uso repository.save(User) per aggiungere un nuovo utente sarà ok, ma aggiornare un utente sarà un'eccezione

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

suggerisco l'uso repository.delete(userid) prima dello repository.save in una transazione, quindi funzionerà correttamente.

3

Prima di tutto, dovresti sapere che le specifiche JPA specificano chiaramente che LAZY è solo un suggerimento per i fornitori di JPA, quindi non è un requisito obbligatorio.

Per tipo di base fetching pigro per lavorare, è necessario enable bytecode enhancement e impostare in modo esplicito la proprietà di configurazione 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

Penso che sarebbe simile a EclipseLink, non è necessario aver attivato la tessitura in caso contrario, l'impostazione di recupero non ha alcun effetto. La tessitura richiede l'accesso bytecode. Questo potrebbe aiutare: https://stackoverflow.com/a/18423704/7159396