[英]OneToMany lazy initialization when needing collection data
如果我有關系OneToMany
並想訪問延遲加載的集合,有什么解決方法? 目前我得到LazyInitializationException
有這個:
Club
實體:
@Entity
public class Club {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "club", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JsonBackReference
private List<Player> players;
Player
實體:
有兩種方法是不是一個好主意,一種是在沒有玩家的情況下獲取數據,另一種是也獲取玩家的數據?
@Override
List<Club> findAll();
@Query("Select clubs from Club clubs left join fetch clubs.players")
List<Club> getAllClubsWithPlayers();
我在想的是,這是一個壞主意,因為如果我遇到這樣一種情況,例如我有 4 個延遲加載的屬性,並且我一次需要其中的 3 個,我將不得不進行查詢像: getAllClubsWithPlayersAndSponsorsAndCoaches
,所以我必須有很多這樣的查詢組合。 我不想使用EAGER
,所以如果我有時需要訪問Club
的players
,這是否是一種常見的方法,那么您能告訴我這是不是一種常見的方法嗎?這可以通過拋出LazyInitializationException
的findAll()
方法來撤消?
不要誤解我的意思——我知道LazyInitializationException
是從哪里來的,但我只是不知道如果我在獲取clubs
時有時需要他們,訪問players
的最佳方式是什么。 我的做法是否正確?
有3個選擇:
@Transactional
方法中的所有惰性字段。 你不顯示你的代碼,但通常有一個 Service Facade 層負責@Transactional
。 它調用存儲庫。要有選擇地加載您想要的內容,您可以使用 EntityGraph。
在您的實體中聲明@NamedEntityGraph
@Entity
@NamedEntityGraph(name = "Club.players",
attributeNodes = @NamedAttributeNode("players")
)
public class Club {
然后你應該用這個圖的名字來注釋你的findAll()
方法
@EntityGraph(value = "Club.players")
List<Club> findAll();
但是,這會覆蓋您的基本findAll()
方法。 為避免這種情況(同時具有兩種實現方式),您可以采用以下方式:
從https://mvnrepository.com/artifact/com.cosium.spring.data/spring-data-jpa-entity-graph/<version>
添加依賴
然后將您的存儲庫替換為
@Repository
public interface ClubRepository extends JpaSpecificationExecutor<Club>, JpaRepository<Club, Long>, EntityGraphJpaSpecificationExecutor<Club> {
}
然后您將擁有基本方法findAll()
並且還可以從您的服務中調用
List<Club> clubs = clubRepository.findAll(specification, new NamedEntityGraph(EntityGraphType.FETCH, "Club.players"))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.