在具有 3 個級別的樹中構造物體我想獲取頂級物體的投影串列,其中包括中級物體的一些屬性,但跳過獲取底層物體。我有一個像下面這樣的設定:
@Entity
class TopLevelEntity {
@EmbeddedId
private TopLevelEntityId id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "mid_level_entity_id")
private MidLevelEntity midLevelEntity;
@Column(name = "some_number")
private Integer someNumber;
}
@Entity
class MidLevelEntity {
@EmbeddedId
private MidLevelEntityId id;
@OneToOne(mappedBy = "midLevelEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private BottomLevelEntityId bottomLevelEntityId;
}
@Entity
class BottomLevelEntity {
@EmbeddedId
private BottomLevelEntityId id;
@OneToOne
@JoinColumn(name = "mid_level_entity_id")
private MidLevelEntityId midLevelEntityId;
}
interface TopLevelEntityProjection {
TopLevelEntityId getTopLevelEntityId();
@Value("#{target.midLevelEntity?.id}")
MidLevelEntityId getMidLevelEntityId();
}
@Repository
public interface TopLevelEntityRepository extends JpaRepository<TopLevelEntity, TopLevelEntityId> {
@EntityGraph(attributePaths = {"midLevelEntity.id"}, type = EntityGraph.EntityGraphType.FETCH)
@Query("select e from TopLevelEntity e where e.someNumber > :someNumber")
Page<TopLevelEntityProjection> findTopLevelEntitiesWithSomeNumberGreaterThanSomeOtherNumber(Integer someNumber, Pageable pageable);
}
正在執行的第一個查詢很好——它獲取頂級和中級物體。然而,對于每個底層物體也有一個查詢——即使它們并沒有真正用于任何事情,它們也會被延遲加載。我們當然可以急切地加載底層物體以避免多個查詢,但是有沒有辦法完全跳過這些?
編輯:
我現在可以看到這個問題可以簡化:如果我直接查詢 MidLevelEntities 也會發生同樣的事情。盡管投影沒有使用 BottomLevelEntities,但它們仍然被延遲加載。起初我雖然可能在某些 equals/hashCode 呼叫期間訪問了它,但是當我覆寫這些方法并在其中設定斷點時,它們沒有被呼叫。
uj5u.com熱心網友回復:
Hibernate ORM 總是獲取@OneToOne關聯,因為它需要知道關聯是否為 null 或者它需要回傳一個物件(關聯惰性時的代理)。使用FetchType.LAZY不會改變這種行為。
我認為有三種可能的方法:
如果您知道關聯始終存在,則可以使用
@JoinColumn(nullable=false). 這種方式 Hibernate ORM 不必檢查,它會懶惰地獲取物體使用單向一對一
@MapsId:@Entity class TopLevelEntity { @EmbeddedId private TopLevelEntityId id; @Column(name = "some_number") private Integer someNumber; } @Entity class MidLevelEntity { @EmbeddedId private MidLevelEntityId id; @OneToOne(fetch = FetchType.LAZY) @MapsId @JoinColumn(name = "top_level_entity_id") private TopLevelEntity topLevelEntity; }您可以啟用位元組碼增強功能并使用注釋
@LazyToOne
您可以在 Hibernate ORM 檔案中找到有關這些用例的更多資訊: 雙向一對一惰性關聯
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/490058.html
