JPA Left Join IS NULL条件不起作用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JPA Left Join IS NULL条件不起作用相关的知识,希望对你有一定的参考价值。
我在mysql上有User和Employee表,在User表中有employeeId作为外键。
现在我需要找到没有用户的员工。
我在MySQL Workbench中编写这个SQL,这正是我想要的:
SELECT * FROM HUMANRESOURCE.EMPLOYEE E LEFT JOIN AUTHORIZE.USER U
ON U.EMPLOYEEOBJID = E.OBJID
WHERE U.EMPLOYEEOBJID is NULL;
但是当我尝试将此SQL实现为JPA查询时,它什么都不返回。这是JPA查询:
Query query = em.createQuery("SELECT e FROM Employee e LEFT JOIN User u
WHERE u.employee.objid = e.objid
AND u.employee IS NULL");
这是真正有效的JPA Query,用于获取拥有用户的员工:
Query query = em.createQuery("SELECT e FROM Employee e INNER JOIN User u
WHERE u.employee.objid = e.objid");
我在这做错了什么?
实体类的更新:
base.Java
package com.kadir.entity;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.Date;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
@Cacheable
@MappedSuperclass
public abstract class Base {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "OBJID")
private BigInteger objid;
@Column(name = "CREATEDBY")
private String createdby;
@Column(name = "CREATEDDATE")
private Timestamp createddate;
@Version
@Column(name = "ROWVERSION")
private Integer rowversion;
@Column(name = "UPDATEDBY")
private String updatedby;
@Column(name = "UPDATEDDATE")
private Timestamp updateddate;
@Column(name = "ARCHIVED", columnDefinition = "int default 0")
private int archived;
public BigInteger getObjid() {
return this.objid;
}
public void setObjid(BigInteger objid) {
this.objid = objid;
}
public String getCreatedby() {
return this.createdby;
}
public void setCreatedby(String createdby) {
this.createdby = createdby;
}
public Date getCreateddate() {
return this.createddate;
}
public void setCreateddate(Timestamp createddate) {
this.createddate = createddate;
}
public Integer getRowversion() {
return this.rowversion;
}
public void setRowversion(Integer rowversion) {
this.rowversion = rowversion;
}
public String getUpdatedby() {
return this.updatedby;
}
public void setUpdatedby(String updatedby) {
this.updatedby = updatedby;
}
public Timestamp getUpdateddate() {
return this.updateddate;
}
public void setUpdateddate(Timestamp updateddate) {
this.updateddate = updateddate;
}
public int getArchived() {
return archived;
}
public void setArchived(int archived) {
this.archived = archived;
}
}
employee.Java
package com.kadir.entity.humanresource;
import com.kadir.entity.corporation.Company;
import com.kadir.entity.Base;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the EMPLOYEE database table.
*
*/
@Cacheable
@Entity
@Table(name = "EMPLOYEE", schema = "HUMANRESOURCE")
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e")
public class Employee extends Base implements Serializable {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "COMPANYOBJID")
private Company company;
@Column(name = "FIRSTNAME")
private String firstname;
@Column(name = "GENDER")
private int gender;
@Column(name = "EMAIL")
private String email;
@Column(name = "PHONE")
private String phone;
@Column(name = "LASTNAME")
private String lastname;
public Employee() {
}
public Company getCompany() {
return this.company;
}
public void setCompany(Company company) {
this.company = company;
}
public String getFirstname() {
return this.firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public int getGender() {
return this.gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getLastname() {
return this.lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
user.Java
package com.kadir.entity.authorize;
import com.kadir.entity.Employee;
import com.kadir.entity.Base;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
/**
* The persistent class for the USER database table.
*
*/
@Cacheable
@Entity
@Table(name="USER", schema="AUTHORIZE")
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User extends Base implements Serializable {
private static final long serialVersionUID = 1L;
@OneToOne
@JoinColumn(name="EMPLOYEEOBJID")
private Employee employee;
@Column(name="NAME")
private String name;
@Column(name="PASSWORD")
private String password;
public User() {
}
public Employee getEmployee() {
return this.employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
答案
EclipseLink支持ON clause,因此请尝试使用
"SELECT e FROM Employee e LEFT JOIN User u on u.employee = e WHERE u.employee IS NULL"
您还可以使用exists和子查询:
"select e from Employee e where not exists (select 1 from User u where u.employee = e)"
另一答案
就我而言,我正在使用Apache OpenJPA。
查询应该是这样的:
SELECT e FROM Employee e LEFT JOIN e.user u WHERE u.employeeId IS NULL
以上是关于JPA Left Join IS NULL条件不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 LEFT JOIN 创建 JPA NamedQuery
LEFT JOIN FETCH 不起作用 - Spring 数据 JPA
嵌套 CONCAT 中的 LEFT JOIN 和 IS NULL 仅返回 NULL