2010-01-21 12 views
13

Ich benutze JPA (Hibernate) mit Spring. Wenn ich zu faul Last i eine Stirng Eigenschaft wollen verwenden Sie folgende Syntax:@Basic (fetch = FetchType.LAZY) funktioniert nicht?

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

Aber wenn ich an der SQL suchen, die erzeugt Hibernate, scheint es diese Eigenschaft nicht faul geladen ist? Ich benutze auch diese Klasse org.hibernate.tool.instrument.javassist.InstrumentTask im ANT-Skript, um diese Eigenschaft zu instrumentieren, aber es scheint, dass es nicht funktioniert.

Bitte helfen Sie mir.

Khosro.

Antwort

-3

Lazy-Abruf gilt nur für Verweise auf andere Entitäten oder Objektgruppen. Es gilt nicht für Werte wie String oder int.

+0

Nicht wahr, LOBs können Lazy-geladen werden. Siehe Abschnitt 2.2.2.1 der Hibernate-Annotations-Dokumentation: http://docs.jboss.org/hibernate/stable/annotations/reference/en/html/entity.html#d0e342 - speziell die Eigenschaft 'detailedComment' in diesem Beispiel und die Notiz darunter. – Cowan

1

von der Spezifikation von JPA sagen sie, dass, selbst wenn Sie Annotate eine Eigenschaft verwenden, um faul abgerufen werden, wird nicht garantiert, dass angewendet werden, so dass die Eigenschaften möglicherweise träge geladen werden oder nicht (hängt von dem Implementierer von JPA) Wenn Sie jedoch angeben, dass Sie sie eifrig abrufen sollten, muss der JPA-Implementierer sie eifrig laden.

Fazit: @Basic (fetch = FetchType.LAZY) kann oder kann nicht funktionieren, hängt von der JPA-Implementierer.

+0

Ich benutze Hibernate, und ich beschreibe das Problem hier http://stackoverflow.com/questions/2112508/basicfetch-fetchtype-lazy-does-not-work/2112846#2112846 in Hennings Antwort – Khosro

4

Lazy Lob Das Laden würde erfordern Bytecode Instrumentierung ordnungsgemäß zu funktionieren, so dass es nicht standardmäßig in jeder mir bekannten JPA-Implementierung verfügbar ist.

Am besten setzen Sie den Lob in eine separate Entität wie HtmlSummary und verwenden Sie eine lazy loaded Eins-zu-Eins-Zuordnung.

+0

Würden Sie mir bitte sagen, wie zu instrumentieren ? Ich benutze Hibernate-Implementierung von JPA.Ich auch Anweisung hier beschreiben, aber es funktioniert nicht: http: //docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-fetching-lazyproperties – Khosro

+0

@ Khosro: Was sagt der Ant-Log-Output? "Es funktioniert nicht" ist nicht genug Informationen, um Ihr Problem zu diagnostizieren, fürchte ich. – Henning

+0

Nun, meine Ant-Task funktioniert gut, und die Ausgabe ist [Instrument] Annahme Transformation des Feldzugriffs [N ews.textBody] aber nach dem Ausführen von Apps habe ich diese Ausnahme org.hibernate.MappingException: Konnte Typ nicht bestimmen für: org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback, bei Tabelle: News, für Spalten: [org.hibernate.mapping.Column (interceptFieldCallback)] In diesem Fall verwende ich org.hibernate.tool.instrument.cglib. InstrumentTask für das Instrumentieren. In einem anderen Fall, wenn ich org.hibernate.tool.instrument.javassist.InstrumentTask verwenden, Apps zwar implementiert, aber Lazy Loading funktioniert nicht – Khosro

3

Verwendung FieldHandled mit @Basic(fetch=FetchType.LAZY) Werken:

public class myFile implements Serializable, FieldHandled 
{ 

    private FieldHandler  fieldHandler; 

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

Hat jemand das versucht? Es scheint nicht für mich zu funktionieren. –

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

I Hibernate4 h2database.I verwenden ist sicher, verzögertes Laden kann durch meinen Code funktionieren.

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

, wenn die Verwendung repository.save(User) ein neuer Benutzer hinzuzufügen ok sein, aber aktualisiert ein Benutzer eine Ausnahme

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

werfen schlage ich vor Gebrauch repository.delete(userid) vor repository.save in einer Transaktion, dann wird es gut funktionieren.

3

Zunächst sollten Sie wissen, dass die JPA-Spezifikationen eindeutig angeben, dass LAZY nur ein Hinweis für JPA-Anbieter ist, also keine zwingende Voraussetzung.

für den Grundtyp faul Abruf zu arbeiten, müssen Sie enable bytecode enhancement und explizit die enableLazyInitialization Konfigurationseigenschaft auf true gesetzt:

<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

Ich denke, dass es zu Eclipse ähnlich sein würde, da müssen Sie Weben aktiviert sein Andernfalls wird die Abrufeinstellung nicht wirksam. Das Weben erfordert Bytecode-Zugriff. Dies könnte helfen: https://stackoverflow.com/a/18423704/7159396

Verwandte Themen