输出不同,执行休眠命令是否有时间延迟

Output is different, is there any time lag for hibernate commands to get executed

我的项目class -

@Entity
public class Project {
    @Id
    private Integer projectId;

    private String projectName;

    @ManyToMany(mappedBy = "projects")
    private List<Employee> employees;
}

我的员工class -

@Entity
public class Employee {
    @Id
    private Integer employeeId;
    private String employeeName;

    @ManyToMany
    private List<Project> projects;
}

我的主class-

SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Employee employee1 = new Employee();
employee1.setEmployeeId(1);
employee1.setEmployeeName("Harry");
Employee employee2 = new Employee();
employee2.setEmployeeId(2);
employee2.setEmployeeName("Ron");

Project project1 = new Project();
project1.setProjectId(3);
project1.setProjectName("ABC");
Project project2 = new Project();
project2.setProjectId(4);
project2.setProjectName("DEF");

List<Project> projectList = new ArrayList<>();
projectList.add(project1);
projectList.add(project2);
employee1.setProjects(projectList);

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

session.save(employee1);
session.save(employee2);
session.save(project1);
session.save(project2);

transaction.commit();

Project project3 = session.get(Project.class, 3);
System.out.println(project3.getProjectId() + " " + project3.getProjectName());
for(Employee employee : project3.getEmployees()){
       System.out.println(employee.getEmployeeId()+" "+ employee.getEmployeeName());
}

session.close();
sessionFactory.close();

在 运行 上面的代码中,employee1、employee2、project1、project2 已成功保存到数据库中,但我得到一个 NullPointerExceptionproject3.getEmployees()

但下次我 运行 代码(所有保存命令都已注释)时,project3.getEmployees() 不为空并且包含 Employee(employeeId=1, employeeName="Harry")。

我第一次用 project3.getEmployees() 得到 NullPointerException 是否有任何时间延迟?

注意 - project3.getProjectId()project3.getProjectName() 在任何一种情况下都不 return null。

在将 ProjectEmployee 保存到数据库之前,您必须手动正确管理它们之间的关系。为了方便起见,你可以在Employee上创建一个实例方法来封装这样的逻辑,而不是直接设置员工的项目列表。

public class Employee {
    
    public void addProject(Project project){
        this.projects.add(project);
        project.getEmployees().add(this);
    }
}

并通过以下方式管理他们的关系:

employee1.addProject(project1);
employee1.addProject(project2);

当然你可以用其他方式来做,将员工添加到项目中:

public class Project {
    
    public void addEmployee(Employee employee){
        this.employees.add(employee);
        employee.getProjects().add(this);
    }
}

并通过以下方式管理他们的关系:

project1.addEmployee(employee1);
project2.addEmployee(employee1);

当你得到 project3 时,它只是 return 你 Session 中的 project1 实例,因为 project1project3 都引用到同一个ID。由于您之前没有正确管理 project1 的员工,它有 NULL 员工列表,因此您得到 NullPointerException.

当你再次执行它的时候,project3 是从数据库加载的,hibernate 已经帮助自动管理它们的关系,因此你不会得到 NullPointerException

如果你确实想自己管理关系,你可以在事务提交后调用session.refresh(employee1)强制休眠从数据库刷新它的最新状态,这不应该解决NullPointerException :

....
transaction.commit();
session.refresh(project1);

Project project3 = session.get(Project.class, 3);
System.out.println(project3.getProjectId() + " " + project3.getProjectName());
for(Employee employee : project3.getEmployees()){
       System.out.println(employee.getEmployeeId()+" "+ employee.getEmployeeName());
}