#hibernate #jpa #lazy-loading
#спящий режим #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]
}
Может кто-нибудь сказать мне, как я могу «присоединиться к выборке» game.gameRules
при запросе person
?
Я пытался создать @NamedEntityGraph
on game
(с gameRules
атрибутом)
и использовать его в person
репозитории findAll
с @EntityGraph
, но использование
entitygraph в person
репозитории вызвало исключение, в котором Hibernate не смог найти gameRules
атрибут person
(неудивительно).
Итак, как кто-то может инициализировать ленивую сущность на уровне члена на несколько уровней глубже? Спасибо,
Ответ №1:
Поскольку ваши отношения в этом случае являются вложенными, вам нужно использовать subgraph
и @namedsubg graph, как показано ниже.
используйте 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 ") }) })