4

hibernate のプロパティ タグのlazy属性により、次のリンクに従ってプロパティを遅延ロードできます。-財産

lazy (オプション - デフォルトは false): インスタンス変数が最初にアクセスされたときに、このプロパティを遅延フェッチするように指定します。ビルド時のバイトコード インストルメンテーションが必要です。

しかし、プロパティの 1 つに lazy=true を設定しようとすると、この例では遅延ロードされません。

Hibernate マッピング ファイル:

<hibernate-mapping package="org.hibernate.tutorial.domain">

    <class name="Event" table="EVENTS" select-before-update="true">
        <id name="id" column="EVENT_ID">
            <generator class="native" />
        </id>
        <property name="date" type="timestamp" column="EVENT_DATE" />
        <property name="title" lazy="true"/>

        <set name="participants" table="PERSON_EVENT" inverse="true">
            <key column="EVENT_ID" />
            <many-to-many column="PERSON_ID" class="Person" />
        </set>
    </class>

</hibernate-mapping>

プログラム:

public static void main(String[] args) {
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Event event = (Event) session.get(Event.class, 135L);
        session.getTransaction().commit();
        System.out.println(event);
        HibernateUtil.getSessionFactory().close();
    }

休止状態によって生成されたクエリ:

Hibernate: select event0_.EVENT_ID as EVENT1_0_0_, event0_.EVENT_DATE as EVENT2_0_0_, event0_.title as title0_0_ from EVENTS event0_ where event0_.EVENT_ID=?

この場合、怠け者が機能しない理由を理解するのを手伝ってください。

4

3 に答える 3

6

Hibernate 5 では、これはバイトコード拡張を使用して簡単に実行できます

まず、次の Maven プラグインを追加する必要があります。

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

@Basic(fetch = FetchType.LAZY)次に、エンティティのプロパティに次のように簡単に注釈を付けることができます。

@Entity(name = "Event")
@Table(name = "event")
public class Event extends BaseEntity {

    @Type(type = "jsonb")
    @Column(columnDefinition = "jsonb")
    @Basic(fetch = FetchType.LAZY)
    private Location location;

    public Location getLocation() {
        return location;
    }

    public void setLocation(Location location) {
        this.location = location;
    }
}

エンティティをフェッチする場合:

Event event = entityManager.find(Event.class, 
    eventHolder.get().getId());

LOGGER.debug("Fetched event");
assertEquals("Cluj-Napoca", event.getLocation().getCity());

Hibernate は、セカンダリ選択を使用して遅延プロパティをロードします。

SELECT e.id AS id1_0_0_
FROM   event e
WHERE  e.id = 1

-- Fetched event

SELECT e.location AS location2_0_
FROM   event e
WHERE  e.id = 1
于 2016-07-04T12:12:17.070 に答える
3

遅延読み込みは、永続化プロバイダーへのヒントにすぎません。このヒントは、エンティティが実際に遅延ロードされることを保証するものではありません。

プロバイダーは、これがより良いアプローチであると判断した場合、それらを積極的に読み込むことができます。

特に基本的なプロパティは、遅延ロードしてもパフォーマンスが向上しないため、遅延ロードされることはめったにありません。むしろその逆です。

動作はコンテキストによって異なる場合があるため、遅延読み込みを確実にテストすることは不可能です。一方、一括読み込み (デフォルト) は保証されており、テストすることができます。

EDIT遅延ロードの効果を確認したいだけの場合 - 遅延ロードされた属性が他のエンティティまたはLOBとの関係である場合、遅延ロードが発生する可能性が高くなります。

于 2013-10-26T18:14:05.727 に答える
0

<property name="title" lazy="true"/>タイトルは他のオブジェクトに関連付けられていないため、使用した遅延読み込みは正しい使用方法ではありません。関係マッピングで使用すると <set name="participants" table="PERSON_EVENT" inverse="true" lazy="true">、パフォーマンスがいくらか向上します。

上記の構成で。If lazy="false": - Event オブジェクトをロードすると、その時点で子オブジェクト Person もロードされ、setPerson() メソッドに設定されます。呼び出すとevet.getPerson()、ロードされたデータが返されます。新しいデータベース呼び出しはありません。

場合lazy="true":- これがデフォルトの構成です。言及しない場合は、休止状態を検討してlazy=trueください。オブジェクトをロードすると、Eventその時点で子オブジェクト Person がロードされません。アドレス オブジェクトを取得するには、データベースへの追加の呼び出しが必要です。呼び出すとevent.getPerson()、その時点でデータベース クエリが起動し、結果が返されます。新しいデータベース呼び出し。

一度テストするには、false に設定してから<set name="participants" table="PERSON_EVENT" inverse="false" lazy="true"> 、出力クエリを確認します

于 2013-10-26T18:16:47.937 に答える