有两个实体:职位和员工。
目标是让一个有或没有职位的员工。如果一个职位存在,则此查询有效,但如果不存在,则将引发错误。
如果员工有或没有职位,如何更改此查询以接收员工?
public Employee getEmployee(Long id) {
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
Employee employee;
try {
employee = em.createQuery("select e " +
"from Employee e " +
"join fetch e.position p " +
"where e.employeeId= :id)", Employee.class)
.setParameter("id", id)
.getSingleResult();
em.getTransaction().commit();
} catch (NoResultException ex){
throw new RuntimeException("MAMA mia");
}
return employee;
}
@Entity
@Table(name = "position")
public class Position {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "POSITION_ID", updatable = false)
private Long id;
@Column(name = "NAME")
private String name;
@JoinTable(name = "Position_Employee_JT")
@OneToMany(fetch = LAZY, cascade = ALL)
private Set<Employee employeeSet = new HashSet<();
}
@Entity
@Table(name = "employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "EMPLOYEE_ID", updatable = false)
private Long employeeId;
@ManyToOne(fetch = LAZY)
private Position position;
}
找到了解决方案。如果您使用fetch Lazy,则代理将为您工作!
Spring数据将无法工作,并会引发错误:可选员工= repository.findById(id);
效果很好。
public Employee getEmployee(Long id) {
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
Employee employee = em.find(Employee.class,id);
em.getTransaction().commit();
return employee;
}
在此说明:https://vladmihalcea.com/how-does-a-jpa-proxy-work-and-how-to-unproxy-it-with-hibernate/
这是因为您使用内部联接。像这样使用左联接:
employee = em.createQuery("select e " +
"from Employee e " +
"left join fetch e.position p " +
"where e.employeeId= :id)", Employee.class)
.setParameter("id", id)
.getSingleResult();