web-dev-qa-db-ja.com

@Basic(fetch = FetchType.LAZY)が機能しませんか?

SpringでJPA(Hibernate)を使用しています。 Stirngプロパティを遅延ロードする場合は、次の構文を使用します。

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

しかし、hibernateが作成するSQLを見ると、このプロパティは遅延ロードされていないようです。また、ANTスクリプトでこのクラスorg.hibernate.tool.instrument.javassist.InstrumentTaskを使用してこのプロパティをインストルメント化していますが、機能していないようです。

私を助けてください。

Khosro。

18
Khosro

レイジーLobロードでは、バイトコードインストルメンテーションが正しく機能する必要があるため、私が知っているJPA実装ではデフォルトで使用できません。

最善の策は、LobをHtmlSummaryなどの別のエンティティに配置し、遅延ロードされた1対1の関連付けを使用することです。

5
Henning

まず、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>
3
Vlad Mihalcea
_@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)を使用することをお勧めします。そうすれば、正常に機能します。

3
lionyu

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;
3
William

jPAの仕様から、レイジーにフェッチされるプロパティにアノテーションを使用しても、これが適用される保証はないため、プロパティがレイジーにロードされる場合とされない場合があります(JPAの実装者によって異なります)。それらを熱心にフェッチする必要があることを指定してから、JPA実装者はそれらを熱心にロードする必要があります。

結論:@Basic(fetch = FetchType.LAZY)は、JPAの実装者によって、機能する場合と機能しない場合があります。

1
Omar Al Kababji

EclipseLinkに似ていると思いますが、それ以外の場合はウィービングを有効にする必要があります。そうしないと、フェッチ設定は有効になりません。織りにはバイトコードアクセスが必要です。これは役立つ可能性があります: https://stackoverflow.com/a/18423704/7159396

0
Petr Pahorecký