【问题标题】:JPQL join fetch if not null如果不为空,则 JPQL 加入获取
【发布时间】:2020-09-03 09:51:02
【问题描述】:

有两个实体:职位和雇员。

目标是让员工有或没有职位。 如果位置存在,则此查询有效,但如果不存在,则会抛出错误。

如果员工有或没有职位,如何更改此查询以接收员工?

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 和 cascade.ALL?你把它们放在奇怪的地方,表明你并不真正理解它们在做什么。重新评估这些作为一个好的开始。

标签: hibernate jpa jpql


【解决方案1】:

找到了解决办法。 如果您使用 fetch Lazy,代理将为您工作!

Spring Data 不起作用,会抛出错误: 可选员工 = 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/

【讨论】:

    【解决方案2】:

    这是因为您使用了内连接。像这样使用左连接:

        employee = em.createQuery("select e " +
                "from Employee e " +
                "left join fetch e.position p " +
                "where e.employeeId= :id)", Employee.class)
                .setParameter("id", id)
                .getSingleResult();
    

    【讨论】:

      猜你喜欢
      • 2018-09-20
      • 1970-01-01
      • 2013-11-14
      • 2016-10-13
      • 2013-08-23
      • 2021-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多