Я пытался использовать EntityGraph для загрузки Entity.У меня есть Employee
сущность со всеми ассоциациями, сопоставленными как LAZY
загрузочные ассоциации.В одном случае я хочу с нетерпением получить Employee
с его ассоциациями с одним значением, поэтому я пытался использовать EntityGraph для этого.[Я знаю, что Eager ассоциации не могут быть загружены как LAZY с помощью EntityGraph, но в моем случае я пытаюсь загрузить LAZY ассоциацию EAGERly с помощью графа Entity, который, я думаю, должен работать]
Employee
@NamedEntityGraphs({
@NamedEntityGraph(name = "Employee.graph1", attributeNodes = {
@NamedAttributeNode(value = "firstName") ,
@NamedAttributeNode(value = "lastName"),
@NamedAttributeNode(value = "manager", subgraph = "managerSubGraph"),
@NamedAttributeNode(value = "department")
}, subgraphs = {
@NamedSubgraph(name = "managerSubGraph", attributeNodes = {
@NamedAttributeNode(value = "department"),
@NamedAttributeNode(value = "manager")}
)}
)}
)
public class Employee {
@Column(name = "id")
@Basic
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Department department;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "manager_id")
private Employee manager;
}
Отдел
@Entity
@Table(name = "department")
public class Department {
@Column(name = "id")
@Basic
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Basic
@Column(name = "name")
private String name;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Set<Employee> employees;
public Department(String name) {
this.name = name;
}
}
Абонент
@Transactional(readOnly = true)
public void entityGraphDemo() {
final EntityGraph<?> entityGraph = em.getEntityGraph("Employee.graph1");
Map<String, Object> properties = new HashMap<>();
properties.put("javax.persistence.fetchgraph", entityGraph);
final Employee employee = em.find(Employee.class, 2, properties);
// all of these get loaded EAGERly with no issue
final PersistenceUnitUtil persistenceUnitUtil = entityManagerFactory.getPersistenceUnitUtil();
System.out.println("isLoaded(employee, \"department\") = " + persistenceUnitUtil.isLoaded(employee, "department"));
System.out.println("isLoaded(employee, \"manager\") = " + persistenceUnitUtil.isLoaded(employee, "manager"));
final Employee employeeManager = employee.getManager();
// these return false, means these nested associations Employee -> Manager -> Department, Employee -> Manager -> Manager are not loaded (which should be)
System.out.println("isLoaded(employeeManager, \"department\") = " + persistenceUnitUtil.isLoaded(employeeManager, "department"));
System.out.println("isLoaded(employeeManager, \"manager\") = " + persistenceUnitUtil.isLoaded(employeeManager, "manager"));
}
Первый уровень графа сущностей загружается правильно какожидается, но второй уровень графика загружается не так, как ожидалось.Проблема в том, что ассоциации department
и manager
в employeeManager
(подграф второго уровня) загружаются не слишком быстро.
Последние два Syso
отпечатка false
.Данные доступны для обеих ассоциаций, и когда я вызываю геттеры на экземпляре employeeManager
, hibernate выполняет два sql
для загрузки manager
и department
, поэтому обе ассоциации кажутся загруженными лениво.
Итак,есть ли ограничения по уровням подграфа, поддерживаемые hibernate?В спецификации JPA такого ограничения нет.Или я что-то здесь упускаю?