我对这个简单的左连接有这个问题。
我有两张桌子: 员工和部门
员工与部门有多对一的关联:
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是员工表。
知道如何让它有效吗?
亲切的问候。 马西莫
答案 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与执行内部联接相同。