16

このグーグルについて少し見つけることができるものはたくさんありますが、私はこの問題の実行可能な解決策を完全には見つけていません。

基本的に、私が持っているのは、オンデマンドでロードしたい特定のクラスの大きなCLOBです。これを行うための素朴な方法は次のとおりです。

class MyType {

  // ...

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

ただし、これは機能しません。これは、Oracleドライバーを使用しているためと思われます。つまり、Lobオブジェクトは単純なハンドルとして扱われず、常に読み込まれます。またはそう私は私の進出から信じるように導かれました。レイジープロパティの読み込みに特別なインストルメンテーションを使用するソリューションが1つありますが、Hibernateのドキュメントでは、それを正しく機能させることにあまり関心がないように思われるため、そのルートには行きたくありません。特に、追加のコンパイルパスなどを実行する必要があります。

したがって、私が想像した次の解決策は、このオブジェクトを別のタイプに分離し、関連付けを定義することでした。残念ながら、ドキュメントには矛盾する情報が記載されていますが、共有主キーを使用したOneToOneアソシエーションでは遅延読み込みが機能しないことは明らかです。アソシエーションの片側をManyToOneとして設定しましたが、共有主キーがある場合にこれを行う方法がよくわかりません。

それで、誰かがこれについて行くための最良の方法を提案できますか?

4

4 に答える 4

8

これによると、 PostgreSQLだけがBlobを本当に怠惰なものとして実装しています。したがって、最善の解決策は、blobを別のテーブルに移動することです。共有主キーを使用する必要がありますか?このようなことをしてみませんか:

public class MyBlobWrapper {
    @Id
    public Long getId() {
       return id;
    }
    @Lob
    public String getBlob() {
        return blob;
    }
    @OneToOne(fetch=FetchType.LAZY,optional=false) 
    public MyClass getParent() {
        return parent;
    }
}
于 2009-07-17T11:23:05.840 に答える
5

StringHibernateアノテーションを使用して平衡化を行う代わりに、フィールドをからClob(またはBlob)に変換してみてください。

@Lob  
@Basic(fetch=FetchType.LAZY)  
@Column(name = "FIELD_COLUMN")  
public Clob getFieldClob() {  
  return fieldClob;  
}  

public void setFieldClob(Clob fieldClob) {  
  this.fieldClob = fieldClob;  
}  

@Transient  
public String getField()  
{  
  if (this.getFieldClob()==null){  
    return null;  
  }  
  try {  
    return MyOwnUtils.readStream(this.getFieldClob().getCharacterStream());  
  } catch (Exception e) {  
    e.printStackTrace();  
  }  

  return null;  
}  

public void setField(String field)  
{  
  this.fieldClob = Hibernate.createClob(field);  
} 

私のために働いた(フィールドはOracle上で怠惰にロードされ始めた)。

于 2012-11-13T09:12:41.677 に答える
4

あなたはHibernateを使用しているように見えるので、あなたの問題は次のHibernate機能に関連しているのではないかと思います。

レイジープロパティフェッチの使用

Hibernate3は、個々のプロパティの遅延フェッチをサポートしています。この最適化手法は、フェッチグループとも呼ばれます。これは主にマーケティング機能であることに注意してください。行読み取りの最適化は、列読み取りの最適化よりもはるかに重要です。ただし、極端な場合には、クラスの一部のプロパティのみをロードすると便利です。たとえば、レガシーテーブルに数百の列があり、データモデルを改善できない場合です。

レイジープロパティのロードには、ビルド時のバイトコードインストルメンテーションが必要です。永続クラスが拡張されていない場合、Hibernateは遅延プロパティ設定を無視し、即時フェッチに戻ります。

Mavenを使用したHibernateのバイトコードインストルメンテーションを参照してください。

于 2014-02-04T11:55:35.170 に答える
1

古い投稿ですが、@TadeuszKopecの回答のおかげで私を助けてくれたのは1つだけです。

JPAでblobの遅延読み込みを行うのは難しいようです。@OneToOneアソシエーションを試しましたが、ヘルプ以上に複雑になります。MyClass(親。同じテーブル、同じID)との関連付けなしで、バイトを別のクラスに移動しました。

@Entity
@Table(name="MyTable")
public class MyBlobWrapper{

    @Id
    @Column(name = "id") // id of MyTable, same as MyClass
    private Long id;

    @Lob
    private byte[] bytes;   
}

@Entity
@Table(name="MyTable")
public class MyClass{

    @Id
    @Column(name = "id")
    private Long id;
    // other fields  .....
}

BLOBを保存する前に、親をフラッシュすることを忘れないでください。

 em.persist(parent);
 em.flush();
 em.merge(new MyBlobWrapper(parent_id,new byte[1000]));

これで、PDFを単独でロードできます。

String query1 = " select PDF from MyBlobWrapper PDF where PDF.id = :id";

私はJPAの初心者ですが、それがお役に立てば幸いです。

于 2018-03-07T18:48:40.390 に答える