java - JPA Left Join IS NULL 条件不起作用

标签 java jpa join eclipselink jpql

我在 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 = 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;
    }

}

用户.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"

您还可以使用 exist 和子查询:

"select e from Employee e where not exists (select 1 from User u where u.employee = e)"

关于java - JPA Left Join IS NULL 条件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36742028/

相关文章:

Java - 通过递归的方式测试一个字符数组是否为回文

java - 如何使用 jooq 编写具有多个字段的条件

PHP和mysql如何使用join得到想要的结果

java - InetAddress.getByName 在代理后面失败

java - 在某些情况下,一种逻辑的最少步骤失败

google-app-engine - JPA 与 App Engine 上的低级数据存储

java - Spring boot JPA + MySQL 抛出错误

java - 使用jpa持久化对象的问题

php - 如何在 MySQL 中获取登录用户不是好友的所有用户?

C pthread 加入一个结束的线程