如何在 JPA 中初始化多个层次的 LAZY 实体?

How to initialize LAZY entity several layers deep in JPA?

我有几层深厚的关系:

class Person {
  @Id
  @Column(name = "PERSON_ID")
  private Long personId;

  @OneToMany(fetch = FetchType.EAGER, mappedBy = "person")
  private Set<Parameter> parameters;

  [... various other attributes omitted]
} 

class Parameter {
  @Id
  @Column(name = "PARAMETER_ID")
  private Long personId;

  @ManyToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "GAME_ID", nullable = false)
  private Game game;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "PERSON_ID")
  @JsonIgnore
  private Person person;

  [... various other attributes omitted]
} 

class Game {
  @Id
  @Column(name = "GAME_ID")
  private Long gameId;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "game") // this is the attribute, that sometimes is required sometimes is not
  private Set<GameRule> gameRules;

  @OneToMany(fetch = FetchType.LAZY, mappedBy = "game")
  @JsonIgnore
  private Set<Parameter> parameters;

  [... various other attributes omitted]
}

class GameRule {
  @Id
  @Column(name = "GAME_RULE_ID")
  private Long gameRuleId;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name="GAME_ID", nullable = false)
  @JsonIgnore
  private Game game;

  [... various other attributes omitted]
}

任何人都可以告诉我如何在查询 person 时使用 game.gameRules “加入获取”? 我试图在 game 上创建一个 @NamedEntityGraph(使用 gameRules 属性), 并在 person 的存储库 findAll@EntityGraph 中使用它,但使用 person 存储库中的实体图导致异常 Hibernate 无法在 person 中找到 gameRules 属性(不足为奇)。

那么如何才能在成员级别上初始化一个惰性实体呢? 谢谢,

由于您的关系在这种情况下是嵌套的,因此您需要使用 subgraph 和 @NamedSubgraph,如下所示。

在您的存储库方法中使用 graph.person.parameters 作为图表名称。

@NamedEntityGraph(name = "graph.person.parameters", attributeNodes = {
        @NamedAttributeNode(value = "parameters", subgraph = "parameters.game") }, subgraphs = {
                @NamedSubgraph(name = "parameters.game", attributeNodes = {
                        @NamedAttributeNode(value = "game", subgraph = "game.gameRules") }),
                @NamedSubgraph(name = "GameRule ", attributeNodes = {
                        @NamedAttributeNode(value = "GameRule ") }) })