JPQL和外连接

时间:2011-11-28 17:57:38

标签: java jpql outer-join

我对这个简单的左连接有这个问题。

我有两张桌子: 员工和部门

员工与部门有多对一的关联:

public class Employee {
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_EMPLOYEE")
    private Long id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "SURNAME")
    private String surname;

    @ManyToOne()    
    private Department department;

部门:

@Entity
@Table(name = "DEPARTMENT")
@SequenceGenerator(name = "SEQ_DEPARTMENT", sequenceName = "SEQ_DEPARTMENT", allocationSize = 1)
public class Department {

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_DEPARTMENT")
    private Long id;

    @Column(name = "NAME")
    private String name;

在db

SELECT * FROM EMPLOYEE;
ID      NAME    SURNAME     DEPARTMENT_ID  
1   Massimo Ugues   1
2   Mazi    Ugues   2

SELECT * FROM DEPARTMENT;
ID      ADDRESS     NAME  
1   Via Gaber   Le betulle

因此,有一个员工不属于任何部门。

现在我需要加载ID为2的Employee,即在Db上没有的departmentId = 2的员工。

所以这是JPQL查询:

select e, department from Employee e left outer join e.department department where e.name = :name and department.id = :id

这是相对sql生成的:

SELECT t0.ID, t0.NAME, t0.SURNAME, t0.DEPARTMENT_ID, t1.ID, t1.ADDRESS, t1.NAME FROM {oj EMPLOYEE t0 LEFT OUTER JOIN DEPARTMENT t1 ON (t1.ID = t0.DEPARTMENT_ID)} WHERE ((t0.NAME = ?) AND (t1.ID = ?))
    bind => [Mazi, 2]

问题不在于联接,而在于t1.ID = ?。它应该是t0.ID =?其中t0是员工表。

知道如何让它有效吗?

亲切的问候。 马西莫

1 个答案:

答案 0 :(得分:0)

问题不在于Hibernate。问题是你的数据库。如果员工不属于任何部门,则NULL列中应该有department_id,而不是某些不存在的部门ID。你应该在employee.department_id上有一个外键约束,以确保这种不一致性永远不会发生。这是ACID中的C.

所以,我的建议是:修复数据:

update employee set department_id = null where department_id not in (select id from department)

另外,请注意,执行左连接并强制部门具有特定ID与执行内部联接相同。