SpringでJPA(Hibernate)を使用しています。 Stirngプロパティを遅延ロードする場合は、次の構文を使用します。
@Lob
@Basic(fetch = FetchType.LAZY)
public String getHtmlSummary() {
return htmlSummary;
}
しかし、hibernateが作成するSQLを見ると、このプロパティは遅延ロードされていないようです。また、ANTスクリプトでこのクラスorg.hibernate.tool.instrument.javassist.InstrumentTaskを使用してこのプロパティをインストルメント化していますが、機能していないようです。
私を助けてください。
Khosro。
レイジーLob
ロードでは、バイトコードインストルメンテーションが正しく機能する必要があるため、私が知っているJPA実装ではデフォルトで使用できません。
最善の策は、LobをHtmlSummary
などの別のエンティティに配置し、遅延ロードされた1対1の関連付けを使用することです。
まず、JPA仕様では、LAZYはJPAプロバイダーへのヒントにすぎないことが明確に指定されているため、必須の要件ではないことを知っておく必要があります。
基本型の遅延フェッチを機能させるには、 バイトコード拡張を有効にする 必要があり、enableLazyInitialization
構成プロパティを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>
_@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;
}
}
_
私はHibernate4h2databaseを使用しています。遅延読み込みは、私のコードで正常に機能すると確信しています。
休止状態:_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=?
_
休止状態:_select user_.img as img3_0_ from User user_ where user_.uid=?
_
repository.save(User)
を使用して新しいユーザーを追加する場合は問題ありませんが、ユーザーを更新すると例外がスローされます
_Java.lang.ClassCastException: org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer$1 cannot be cast to Java.sql.Blob
_
1つのトランザクションで_repository.save
_の前にrepository.delete(userid)
を使用することをお勧めします。そうすれば、正常に機能します。
FieldHandledを@Basic(fetch=FetchType.LAZY)
で使用します。
public class myFile implements Serializable, FieldHandled
{
private FieldHandler fieldHandler;
@Lob
@Basic(fetch = FetchType.LAZY)
@Column(name = "CONTENT")
protected byte[] content;
jPAの仕様から、レイジーにフェッチされるプロパティにアノテーションを使用しても、これが適用される保証はないため、プロパティがレイジーにロードされる場合とされない場合があります(JPAの実装者によって異なります)。それらを熱心にフェッチする必要があることを指定してから、JPA実装者はそれらを熱心にロードする必要があります。
結論:@Basic(fetch = FetchType.LAZY)は、JPAの実装者によって、機能する場合と機能しない場合があります。
EclipseLinkに似ていると思いますが、それ以外の場合はウィービングを有効にする必要があります。そうしないと、フェッチ設定は有効になりません。織りにはバイトコードアクセスが必要です。これは役立つ可能性があります: https://stackoverflow.com/a/18423704/7159396