LazyInitializationException - 无法初始化代理 - 无会话
LazyInitializationException - could not initialize proxy - no Session
我有一个 LazyInitializationException 问题,我不知道如何解决它。
for (Long id : employeeIds)
{
List<ProjectEmployee> projectEmployeeList = projectEmployeeService.findProjectEmployeesWithinDates(id,
startDate, endDate);
// if no data, then continue with next employee
if (projectEmployeeList.isEmpty())
{
continue;
}
gridCreated = true;
Employee employee = projectEmployeeList.get(0).getEmployee();
Label titleLabel = new Label(employee.getPerson().getSurname() + " " + employee.getPerson().getName() + " ["
+ employee.getRole().getHumanizedRole() + "]");
titleLabel.setStyleName("header-bold");
ProjectEmployeePanel projectEmployeePanel = new ProjectEmployeePanel(id, startDate, endDate);
gridPanelsLayout.addComponents(titleLabel, projectEmployeePanel);
}
之前的问题是当我调用 .getperson=null 但我修复了调用 findProjectEmployeesWithinDates 要求在那里找到那个人。但是当我调用 'findProjectEmployeesWithinDates' 时出现异常。
代码 findProjectEmployeesWithinDates:
public List<ProjectEmployee> findProjectEmployeesWithinDates(Long employeeId, LocalDate startDate, LocalDate endDate) {
List<Long> list = new ArrayList<>();
list.add(employeeId);
List<ProjectEmployee> listProjectEmployees = projectEmployeeRepository.findProjectEmployeesWithinDates(list,
LocaleUtils.getDateFromLocalDate(startDate, LocaleUtils.APPLICATION_DEFAULT_ZONE_ID),
LocaleUtils.getDateFromLocalDate(endDate, LocaleUtils.APPLICATION_DEFAULT_ZONE_ID));
for (ProjectEmployee pe : listProjectEmployees)
{
Hibernate.initialize(pe.getEmployee());
Hibernate.initialize(pe.getEmployee().getPerson());
}
return listProjectEmployees;
}
所以使用 debbug 我看到了:
Hibernate.initialize(pe.getEmployee()); ----line 105
Hibernate.initialize(pe.getEmployee().getPerson()); ---line 106
它出现在 findProjectEmployeesWithinDates 中 for 循环的第一行,但不出现在第二行,这就是异常发生的地方。
我得到的错误
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
在 org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
在 org.hibernate.Hibernate.initialize(Hibernate.java:75) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
在 com.xitee.ccpt.service.ProjectEmployeeService.findProjectEmployeesWithinDates(ProjectEmployeeService.java:105) ~[classes/:na]
在 com.xitee.ccpt.service.ProjectEmployeeService$$FastClassBySpringCGLIB$$63bfc6f9.invoke() ~[spring-core-4.1.1.RELEASE.jar:na]
项目员工class:
@Entity
@Table(名称="employee",架构="ccpt_data")
@NamedQuery(名称="Employee.findAll",查询="SELECT e FROM Employee e")
public class Employee 实现 Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "employee_id")
@SequenceGenerator(name = "EMPLOYEE_ID_GENERATOR", sequenceName = "employee_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "EMPLOYEE_ID_GENERATOR")
private Long employeeId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "person_id")
private Person person;
@Column(name = "monthly_cost")
private String monthlyCost;
@Enumerated(EnumType.STRING)
@Column(name = "role")
private EmployeeRole role;
@Column(name = "employee_manager")
private String employeeManager;
@Column(name = "obsolete")
private Boolean obsolete;
@Column(name = "bank_account_number")
private String bankAccountNumber;
@Column(name = "last_employer")
private String lastEmployer;
@Column(name = "starting_day")
private String startingDay;
@Column(name = "hours")
private Short hours;
@OneToMany(mappedBy = "employee", cascade =
{
CascadeType.ALL
}, orphanRemoval = true)
private Set<EmployeeWorkload> employeeWorkloads;
@OneToMany(mappedBy = "employee", fetch = FetchType.LAZY, orphanRemoval = true)
private Set<ProjectEmployee> projectEmployee;
@OneToMany(mappedBy = "employee", cascade =
{
CascadeType.PERSIST
}, orphanRemoval = true)
private Set<Qualification> qualifications;
@OneToMany(mappedBy = "employee", cascade =
{
CascadeType.PERSIST
}, orphanRemoval = true)
private List<CareerExperience> careerExperiences;
@Transient
private Map<Integer, String> exportOptions;
@OneToMany(mappedBy = "employee", fetch = FetchType.LAZY, orphanRemoval = true)
private Set<ProjectEmployeeRejection> projectEmployeeRejections;
@Transient
private boolean decrypted = true; // allows editing and viewing for users with no encryption rights
/**
* Initialization vector used for encryption of this employee or NO_KEY if no encryption was used
*
* @since 0.4.0
*/
@Column(name = "iv")
private String iv;
@Column(name = "cis_employee_id")
private Long cISEmployeeId;
@Column(name = "experience_summary")
private String experienceSummary;
@Enumerated(EnumType.STRING)
@Column(name = "employee_job_type")
private EmployeeJobType employeeJobType;
@Column(name = "ending_day")
@Type(type = "date")
private Date endingDay;
@Column(name = "main_skill")
private String mainSkill;
public Employee()
{
}
public Long getEmployeeId()
{
return employeeId;
}
public void setEmployeeId(Long employeeId)
{
this.employeeId = employeeId;
}
public Person getPerson()
{
return person;
}
public void setPerson(Person person)
{
this.person = person;
}
public String getExperienceSummary()
{
return experienceSummary;
}
public void setExperienceSummary(String experienceSummary)
{
this.experienceSummary = experienceSummary;
}
有人能帮我解决这个问题吗?
- 当你打电话
projectEmployeeRepository.findProjectEmployeesWithinDates方法吧
returns 列表。此时您的休眠会话已经关闭。
- 因此,当读取 ProjectEmployee 对象时,您只能访问那些特定于对象的变量,而不能访问特定于对象的子对象,因为您对子对象使用延迟初始化。
- 因此,解决方法是让您的休眠会话保持打开状态或使用急切获取或使用包装器 class 对象在 projectEmployeeRepository.findProjectEmployeesWithinDates 方法中将值从 ProjectEmployee class 传输到 ProjectEmployeeWrapper 然后return ProjectEmployeeWrapper 对象列表
我会推荐以下方法之一:
1) 在你的存储库方法中 findProjectEmployeesWithinDates
你可以做
for (ProjectEmployee pe : listProjectEmployees)
{
pe.getEmployee().getPerson();
}
因此它将在会话打开时初始化对象
2) 您可以使用查询
获取数据
SELECT * FROM ProjectEmployee pe JOIN FETCH pe.employee e JOIN FETCH e.person
这样,Hibernates 将自动使用员工和人员对象填充执行结果
我有一个 LazyInitializationException 问题,我不知道如何解决它。
for (Long id : employeeIds)
{
List<ProjectEmployee> projectEmployeeList = projectEmployeeService.findProjectEmployeesWithinDates(id,
startDate, endDate);
// if no data, then continue with next employee
if (projectEmployeeList.isEmpty())
{
continue;
}
gridCreated = true;
Employee employee = projectEmployeeList.get(0).getEmployee();
Label titleLabel = new Label(employee.getPerson().getSurname() + " " + employee.getPerson().getName() + " ["
+ employee.getRole().getHumanizedRole() + "]");
titleLabel.setStyleName("header-bold");
ProjectEmployeePanel projectEmployeePanel = new ProjectEmployeePanel(id, startDate, endDate);
gridPanelsLayout.addComponents(titleLabel, projectEmployeePanel);
}
之前的问题是当我调用 .getperson=null 但我修复了调用 findProjectEmployeesWithinDates 要求在那里找到那个人。但是当我调用 'findProjectEmployeesWithinDates' 时出现异常。 代码 findProjectEmployeesWithinDates:
public List<ProjectEmployee> findProjectEmployeesWithinDates(Long employeeId, LocalDate startDate, LocalDate endDate) {
List<Long> list = new ArrayList<>();
list.add(employeeId);
List<ProjectEmployee> listProjectEmployees = projectEmployeeRepository.findProjectEmployeesWithinDates(list,
LocaleUtils.getDateFromLocalDate(startDate, LocaleUtils.APPLICATION_DEFAULT_ZONE_ID),
LocaleUtils.getDateFromLocalDate(endDate, LocaleUtils.APPLICATION_DEFAULT_ZONE_ID));
for (ProjectEmployee pe : listProjectEmployees)
{
Hibernate.initialize(pe.getEmployee());
Hibernate.initialize(pe.getEmployee().getPerson());
}
return listProjectEmployees;
}
所以使用 debbug 我看到了:
Hibernate.initialize(pe.getEmployee()); ----line 105
Hibernate.initialize(pe.getEmployee().getPerson()); ---line 106
它出现在 findProjectEmployeesWithinDates 中 for 循环的第一行,但不出现在第二行,这就是异常发生的地方。
我得到的错误
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
在 org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final] 在 org.hibernate.Hibernate.initialize(Hibernate.java:75) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final] 在 com.xitee.ccpt.service.ProjectEmployeeService.findProjectEmployeesWithinDates(ProjectEmployeeService.java:105) ~[classes/:na] 在 com.xitee.ccpt.service.ProjectEmployeeService$$FastClassBySpringCGLIB$$63bfc6f9.invoke() ~[spring-core-4.1.1.RELEASE.jar:na]
项目员工class:
@Entity
@Table(名称="employee",架构="ccpt_data") @NamedQuery(名称="Employee.findAll",查询="SELECT e FROM Employee e") public class Employee 实现 Serializable { private static final long serialVersionUID = 1L;
@Id
@Column(name = "employee_id")
@SequenceGenerator(name = "EMPLOYEE_ID_GENERATOR", sequenceName = "employee_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "EMPLOYEE_ID_GENERATOR")
private Long employeeId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "person_id")
private Person person;
@Column(name = "monthly_cost")
private String monthlyCost;
@Enumerated(EnumType.STRING)
@Column(name = "role")
private EmployeeRole role;
@Column(name = "employee_manager")
private String employeeManager;
@Column(name = "obsolete")
private Boolean obsolete;
@Column(name = "bank_account_number")
private String bankAccountNumber;
@Column(name = "last_employer")
private String lastEmployer;
@Column(name = "starting_day")
private String startingDay;
@Column(name = "hours")
private Short hours;
@OneToMany(mappedBy = "employee", cascade =
{
CascadeType.ALL
}, orphanRemoval = true)
private Set<EmployeeWorkload> employeeWorkloads;
@OneToMany(mappedBy = "employee", fetch = FetchType.LAZY, orphanRemoval = true)
private Set<ProjectEmployee> projectEmployee;
@OneToMany(mappedBy = "employee", cascade =
{
CascadeType.PERSIST
}, orphanRemoval = true)
private Set<Qualification> qualifications;
@OneToMany(mappedBy = "employee", cascade =
{
CascadeType.PERSIST
}, orphanRemoval = true)
private List<CareerExperience> careerExperiences;
@Transient
private Map<Integer, String> exportOptions;
@OneToMany(mappedBy = "employee", fetch = FetchType.LAZY, orphanRemoval = true)
private Set<ProjectEmployeeRejection> projectEmployeeRejections;
@Transient
private boolean decrypted = true; // allows editing and viewing for users with no encryption rights
/**
* Initialization vector used for encryption of this employee or NO_KEY if no encryption was used
*
* @since 0.4.0
*/
@Column(name = "iv")
private String iv;
@Column(name = "cis_employee_id")
private Long cISEmployeeId;
@Column(name = "experience_summary")
private String experienceSummary;
@Enumerated(EnumType.STRING)
@Column(name = "employee_job_type")
private EmployeeJobType employeeJobType;
@Column(name = "ending_day")
@Type(type = "date")
private Date endingDay;
@Column(name = "main_skill")
private String mainSkill;
public Employee()
{
}
public Long getEmployeeId()
{
return employeeId;
}
public void setEmployeeId(Long employeeId)
{
this.employeeId = employeeId;
}
public Person getPerson()
{
return person;
}
public void setPerson(Person person)
{
this.person = person;
}
public String getExperienceSummary()
{
return experienceSummary;
}
public void setExperienceSummary(String experienceSummary)
{
this.experienceSummary = experienceSummary;
}
有人能帮我解决这个问题吗?
- 当你打电话 projectEmployeeRepository.findProjectEmployeesWithinDates方法吧 returns 列表。此时您的休眠会话已经关闭。
- 因此,当读取 ProjectEmployee 对象时,您只能访问那些特定于对象的变量,而不能访问特定于对象的子对象,因为您对子对象使用延迟初始化。
- 因此,解决方法是让您的休眠会话保持打开状态或使用急切获取或使用包装器 class 对象在 projectEmployeeRepository.findProjectEmployeesWithinDates 方法中将值从 ProjectEmployee class 传输到 ProjectEmployeeWrapper 然后return ProjectEmployeeWrapper 对象列表
我会推荐以下方法之一:
1) 在你的存储库方法中 findProjectEmployeesWithinDates
你可以做
for (ProjectEmployee pe : listProjectEmployees)
{
pe.getEmployee().getPerson();
}
因此它将在会话打开时初始化对象
2) 您可以使用查询
获取数据 SELECT * FROM ProjectEmployee pe JOIN FETCH pe.employee e JOIN FETCH e.person
这样,Hibernates 将自动使用员工和人员对象填充执行结果