Ich habe Benutzer- und Employee-Tabellen für MySQL, und in der User-Tabelle gibt es employeeId als Fremdschlüssel.JPA Left Join IS NULL-Bedingung funktioniert nicht
Jetzt muss ich Mitarbeiter, die keinen Benutzer haben.
Ich schreibe diese SQL in MySQL Workbench, das funktioniert genau, wie ich will:
SELECT * FROM HUMANRESOURCE.EMPLOYEE E LEFT JOIN AUTHORIZE.USER U
ON U.EMPLOYEEOBJID = E.OBJID
WHERE U.EMPLOYEEOBJID is NULL;
Aber wenn ich versuche, diese SQL als JPA-Abfrage zu implementieren, es gibt nichts zurück. Hier ist JPA Abfrage:
Query query = em.createQuery("SELECT e FROM Employee e LEFT JOIN User u
WHERE u.employee.objid = e.objid
AND u.employee IS NULL");
Und hier ist wirklich arbeiten JPA Abfrage, die ich für Mitarbeiter, die haben immer Benutzer:
Query query = em.createQuery("SELECT e FROM Employee e INNER JOIN User u
WHERE u.employee.objid = e.objid");
Was mache ich falsch hier?
Update für Entitätsklassen:
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;
}
}
Grundsätzlich gilt: Sie machen den Fehler, der Bindung Um SQL in JPQL zu übersetzen, funktioniert das nicht, weil sie absolut nicht identisch sind. Die einzige Möglichkeit, das Problem anzugehen, besteht darin, zu versuchen, die Frage aus der Perspektive des Modells, das Sie haben, und des Modells (der JPA-Entitäten), die Sie gerade nicht anzeigen, zu beantworten. Wenn Employee eine umgekehrte Zuordnung zum Benutzer hat, wird dieses Problem unendlich einfacher. – Gimby
Der Mitarbeiter hat keine umgekehrte Zuordnung, es gibt nur ein Mitarbeiterobjekt in der Benutzerklasse. Gibt es eine Problemumgehung für diese Situation, oder muss ich umgekehrte Zuordnung hinzufügen? @ Gimby – kadir
kann ich beide die Entitätsklasse sehen? – Zia