2011-10-26 10 views
9

残念ながら、以下のコードは機能しません。画像は常に検索されます!JPAレイジー単純バイト[]フィールドレベル

@Entity 
public Car implements Serializable { 
    ... 
    @Basic(fetch = FetchType.LAZY) //Neither with @Lob 
    private byte[] image; 
    ... 
} 

SETUP:JPA 2.0 /休止状態3.5/MySQLの5.5

私はこれが(2007年頃)しばらく前に質問されて覚えて

答えて

0

:バイト配列を熱心にも、カントーフェッチされている、すなわち理由彼らは怠け者と宣言されています。明らかに、Hibernateの人たちはまだこの問題を修正していません。

ここではいくつかの実行可能な代替です:

拳は、同様@Lobであなたのフィールドに注釈を付ける試してみて、期待通りにそれが動作するかどうかを確認。

第二に、それは大きなリファクタリングではありません、これは実際に遅延読み込みの問題を解決する必要がありますのでjava.sql.Blobであなたのbyte[]を置き換え、それが実際のバイト配列を設定し、取得するための便利なメソッドがあります。

http://download.oracle.com/javase/1.4.2/docs/api/java/sql/Blob.html

+0

ありがとうございました。しかし、これらのアプローチは私のためには機能しません。大きな問題! '@Lob @Basic(fetch = FetchType.LAZY)Blobプライベートバイト[]イメージ;' EntityManagerはこのプロパティを保持できません。すべてのフィールドを保持し、 'image'はnullのままです。私は具体的なクラス 'SerialBlob'を使っています – CelinHC

3

JPAプロバイダは、指定したときに遅延してデータをフェッチする必要はありません。 ヒントです。要件ではありません。

JPA仕様2.0 11.1.6

EAGER戦略は、データが熱心にフェッチする必要があり永続プロバイダランタイムに必要です。 LAZY戦略は、持続アクセス・ランタイムに対するのヒントヒントです。最初にアクセスされたときにデータが遅くフェッチされるべきであることを意味します( )。実装はであり、 LAZY戦略のヒントが指定されたデータをフェッチするです。 特に、プロパティベースのアクセスの基本マッピング に対してのみ遅延フェッチが可能です。

+0

ペドロさんありがとう!だから私は失われていますか? – CelinHC

+0

Pedro、これは本当にこれがHibernateのバグだと思っています(JPAの実装で最初にやることはありません)。この質問を確認する:http://stackoverflow.com/questions/2605477/spring-hibernate-blob-lazy-loadingあなたは基本的にあなたと同じ問題を抱えています。解決策:あなたのエンティティ(イメージには存在しません)とbyte []だけを含む別のエンティティとのマッピングを1対1にして、その関連付けを怠け者にします –

+0

@AndreiBodnarescuもちろんHibernateのバグですが、JPAプロバイダが遅れてデータを読み込むとは想定できません。あなたのロジックがこのような機能に依存していると私の意見では、JPAプロバイダを変更すると驚くかもしれないので、よく書かれています。 –

1

私の知る限り、レイジーローディングは@OneToManyリレーションシップがある場合のみ可能です(クラスウィービングを使用しない限り)。これは、少なくともEclipseLinkがそれをhttp://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Basic_Mappings/Lazy_Basicsと説明する方法であり、Java言語の観点からは理にかなっています。あなたは

@OneToMany (fetch = FetchType.LAZY) 
Collection<Employee> employees; 

コレクションを持っている場合はJPAは簡単にあなたがそれを反復処理開始時に遅延したデータをロードし、自身のコレクションの実装を使用することができるように はインターフェースです。フィールドがbyte[]のオブジェクトがある場合、その値はnullか、すべてのデータが含まれています。これはJavaの動作です。これを回避する唯一の方法は、クラスウィービングを使用し、バイト配列のように見えるが、アクセスするまでデータを含まないバイトコードを作成することです。

2

これは、このトピックで説明achiveする方法トリック:http://justonjava.blogspot.it/2010/09/lazy-one-to-one-and-one-to-many.html

私は、PostgreSQL 9.3、Hibernateのv.4.3.5とJPAのv.1.5.0でそれをchechedさしました。魅力のように働いた。 例:

public class Attachment implements FieldHandled{ 
    @Transient 
    private FieldHandler fieldHandler; 
... 
... 
    @Lob 
    @Column(name=CONTENT, nullable=false) 
    @Basic(fetch = FetchType.LAZY, optional = false) 
    private byte[] content; 

... 
... 
    public byte[] getContent() { 
    if(fieldHandler!=null){ 
     return (byte[])fieldHandler.readObject(this, "content", content); 
    } 
    return content; 
    } 

    public void setContent(byte[] content) { 
    if(fieldHandler!=null){ 
     fieldHandler.writeObject(this, "content", this.content, content); 
     return; 
    } 
    this.content = content; 
    } 

} 

注:CGLIBを使用している場合は、同じアプローチで、代わりにFieldHandledのnet.sf.cglib.transform.impl.InterceptFieldEnabledを実装します。