-1

I have a problem with LazyInitializationException and I don't know how to fix it.

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);
    }

Before the problem was when I was calling .getperson=null but I fix the call findProjectEmployeesWithinDates asking there to get the person. But then I got the exception when I call the 'findProjectEmployeesWithinDates'. The code 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;
}

So using debbug i saw that :

 Hibernate.initialize(pe.getEmployee()); ----line 105
Hibernate.initialize(pe.getEmployee().getPerson()); ---line 106

it goes at the first line here at the for loop in the findProjectEmployeesWithinDates but not at the second, and this is where the exception happens.

the error I get

Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session

at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final] at org.hibernate.Hibernate.initialize(Hibernate.java:75) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final] at com.xitee.ccpt.service.ProjectEmployeeService.findProjectEmployeesWithinDates(ProjectEmployeeService.java:105) ~[classes/:na] at com.xitee.ccpt.service.ProjectEmployeeService$$FastClassBySpringCGLIB$$63bfc6f9.invoke() ~[spring-core-4.1.1.RELEASE.jar:na]

Project Employee class:

@Entity

@Table(name = "employee", schema = "ccpt_data") @NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e") public class Employee implements 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;
}

Can anyone help me with this problem, please?

Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997
Ilia Tapia
  • 529
  • 7
  • 19
  • can you provide the stacktrace of error ? Is the stacktrace pointing out which line has error ? – Santosh Balaji Feb 05 '19 at 08:31
  • I just edit the question @SantoshBalaji – Ilia Tapia Feb 05 '19 at 08:33
  • where line number 105 in this code ? – Santosh Balaji Feb 05 '19 at 08:36
  • Hibernate.initialize(pe.getEmployee()); ----line 105 Hibernate.initialize(pe.getEmployee().getPerson());-- line 106 i try even using only the line 106 but still the same thing. – Ilia Tapia Feb 05 '19 at 08:38
  • Can try changing the ProjectEmployee object relationship to eager type instead of lazy ? If possible can you show the ProjectEmployee class – Santosh Balaji Feb 05 '19 at 08:43
  • I suppose it's 'pe' variable that is problematic. You can try maybe Hibernate.initialize(pe) first. Or better approach might be in repository prefetch required object with JOIN FETCH. – Stan Feb 05 '19 at 08:44
  • Yeap i try that already was the first thing i try even EAGER is not advice to be used, but didn't work. – Ilia Tapia Feb 05 '19 at 08:44
  • @Stan I will change the name of the variable to 'projectEmployee' and built again, what you mean i should do in repository?? – Ilia Tapia Feb 05 '19 at 08:46
  • @IliaTapia, I didn't mean name is a problem, I meant it probably detached proxy so you can try to initialize it first. However using JPQL's JOIN FETCH is more preferable since you don't need boilerplate Hibernate.initialize(...) code – Stan Feb 05 '19 at 08:50
  • Sorry but i don't understand you @Stan – Ilia Tapia Feb 05 '19 at 08:51
  • @SantoshBalaji i insert the employee class – Ilia Tapia Feb 05 '19 at 08:51
  • I have added the answer. You can refer to the following link for similar question https://stackoverflow.com/questions/54504006/how-to-fix-the-lazyinitializationexception-im-encountering/54510390#54510390 – Santosh Balaji Feb 05 '19 at 08:53
  • This seems to be a duplicated issue: https://stackoverflow.com/questions/21574236/how-to-fix-org-hibernate-lazyinitializationexception-could-not-initialize-prox – Gerardo Roza Aug 27 '19 at 01:36

2 Answers2

2

I would recommend one of the following approaches:

1) In you repository method findProjectEmployeesWithinDates you can do

for (ProjectEmployee pe : listProjectEmployees)
{
    pe.getEmployee().getPerson();

}

so it will initialize objects while session is open

2) You can fetch data using query

  SELECT * FROM ProjectEmployee pe JOIN FETCH pe.employee e JOIN FETCH e.person

In this way Hibernates will populate execution result with employee and person objects automatically

Stan
  • 1,398
  • 9
  • 14
1
  • When you call projectEmployeeRepository.findProjectEmployeesWithinDates method it returns List. At this point of time your hibernate session is already closed.
  • So when read the ProjectEmployee object you are allowed to access only those object specific variables and not object specific child objects since you are using lazy initialization for your child objects.
  • So the workaround is to keep your hibernate session open or use eager fetch or use a wrapper class object to transfer values from ProjectEmployee class to ProjectEmployeeWrapper within projectEmployeeRepository.findProjectEmployeesWithinDates method and then return the List of ProjectEmployeeWrapper object
Santosh Balaji
  • 353
  • 2
  • 13
  • how can i keep my session open? I try Eager it still gives me the same exception. @SantoshBalaji – Ilia Tapia Feb 05 '19 at 08:54
  • https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/Session.html. This is one of the way to maintain transaction manually. But if you don't want to do this try filling up all the values required with in your repository method by creating a wrapper class – Santosh Balaji Feb 05 '19 at 08:57