[英]Hibernate org.hibernate.LazyInitializationException: could not initialize
[英]Transactional annotation doesn't solve org.hibernate.LazyInitializationException
我正在編寫一個簡單的 Spring 數據 JPA 應用程序。 我使用 MySQL 數據庫。 有兩個簡單的表:
每個員工在某個部門工作 (Employee.department_id)。
我有兩個實體類:
@Entity
public class Department {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long id;
@Basic(fetch = FetchType.LAZY)
@OneToMany(mappedBy = "department")
List<Employee> employees;
}
@Entity
public class Person {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private Long id;
@ManyToOne
@JoinColumn
private Department department;
}
存儲庫:
@Repository
public interface DepartmentRepository extends JpaRepository<Department, Long> {}
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {}
有一個DepartmentService class:
@Service
@Transactional
public class DepartmentService {
@Autowired
DepartmentRepository departmentRepository;
@Transactional
List<Department> getAll() {
departmentRepository.findAll();
}
@Transactional
void getEmployees() {
for(Department department: getAll()) {
List<Employee> employees = department.getEmployees();
for(Employee employee: employees)
System.out.println(employee);
}
}
}
和主要的 class(我不需要 web,所以我使用CommandLineRunner
將應用程序作為控制台應用程序運行):
@SpringBootApplication
public class EmployeeDB implements CommandLineRunner {
@Autowired
DepartmentService departmentService;
public static void main(String[] args) {
SpringApplication.run(EmployeeDB.class, args);
}
@Override
public void run(String... args) throws Exception {
departmentService.getEmployees();
}
}
我在 class DepartmentService
之前以及它的所有方法之前添加了@Transactional
,但我仍然不斷收到以下錯誤:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: employeeDB.Department.employees, could not initialize proxy - no Session
堆棧跟蹤:
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: employeeDB.Department.employees, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:602) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:217) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:581) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:148) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:303) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at employeeDB.DepartmentService.getEmployees(DepartmentService.java:25) ~[main/:na]
at employeeDB.EmployeeDB.run(EmployeeDB.java:41) [main/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
... 5 common frames omitted
為什么會出現此錯誤? 我該如何解決?
@Transactional
不應該用於獲取延遲加載的實體,這將導致n+1 select 問題。
您需要改用適當的映射或查詢,例如在 jpql 中:
select d
from Department d
left join fetch d.employees
總結以上所有答案和評論:
發生這種情況是因為方法DepartmentService::getEmployees
不是公開的。
我在 getEmployees() 之前添加了 public,這解決了這個問題。
@Transactional
注釋由 AOP 提供支持,那么代理只能處理公共方法。
這意味着@Transactional
實際上並未應用於此方法,並且 session 在讀取惰性集合時已經關閉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.