需要帮助将标准SQL查询转换为JPA标准查询

问题描述 投票:0回答:3

我有两个表:

Employee

id
firstName
lastName
.
.
.

培训

id
employeeId
trainingName
trainingSuspsnseDate
trainingComplete

当我在MySQL Workbench中执行标准SQL查询时,它看起来像这样:

SELECT e.id, e.firstName, e.lastName, t.trainingName, t.trainingSuspenseDate, t.trainingComplete
FROM Employee e
JOIN Training t on t.employeeId = e.id
WHERE t.trainingSuspenseDate < CURDATE()
order by t.trainingSuspenseDate;

现在,我想创建同一SQL查询的条件查询,但是在连接时遇到了麻烦。这是我根据谷歌搜索尝试过的内容:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> employeeQuery = builder.createQuery(Employee.class);
Root<Employee> employee = employeeQuery.from(Employee.class);
Join<Employee, Training> training = employee.join(Employee_.ID);
employeeQuery.select(builder.construct(Employee.class,
    employee.get(Employee_.ID),
    employee.get(Employee_.firstName),
    employee.get(Employee_.lastName),
    training.get(Training_trainingName),
    training.get(Training_trainingSuspsnseDate),
    training.get(Training_trainingComplete)));

但是,我得到了错误:

incompatible types: inference variable Y has incompatible equality constraints Templates,Integer where Y,X are type-variables:
Y extends Object declared in method <Y>join(SingularAttribute<? super X,Y>)
X extends Object declared in interface From

我尝试了JOIN的其他排列,但是得到了不同的错误。我似乎找不到创建此查询的确切“秘密”。

Join<Employee, Training> training = training.join(Training_.employeeId);

Join<Employee, Training> training = training.join(Training_.employeeId).join(Employee_.ID);

Join<Training, Employee> training = training.join(Training_.employeeId);

Join<Training, Employee> training = training.join(Training_.employeeId).join(Employee_.ID);

.
.
.

编辑:添加了我的模型类

Employee.java

@Entity
@Table(name = "employee")
@XmlRootElement
@NamedQueries(
        {
            @NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e"),
            @NamedQuery(name = "Employee.deleteAll", query = "DELETE FROM Employee e"),
            @NamedQuery(name = "Employee.countAll", query = "SELECT COUNT(e.ID) FROM Employee e")
        })
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @GeneratedValue
    @Column(name = "id")
    private Integer ID;

    @Basic(optional = true)
    @Column(name = "name_first")
    private String firstName;

    @Basic(optional = true)
    @Column(name = "name_last")
    private String lastName;

    @Basic(optional = true)
    @Column(name = "created_date")
    private String employeeDate;

    @Basic(optional = true)
    @Column(name = "personal_type")
    private String personnelType;

    public Employee() {
        ID = 0;
    }

    public Employee(Integer id) {
        this.ID = id;
    }

    public Integer getID() {
        return ID;
    }

    public void setID(Integer id) {
        this.ID = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmployeeDate() {
        return employeeDate;
    }

    public void setEmployeeDate(String employeeDate) {
        this.employeeDate = employeeDate;
    }

    public String getPersonnelType() {
        return personnelType;
    }

    public void setPersonnelType(String personnelType) {
        this.personnelType = personnelType;
    }

}

Training.java

@Entity
@Table(name = "training")
@XmlRootElement
@NamedQueries(
        {
            @NamedQuery(name = "Training.findAll", query = "SELECT t FROM Training t"),
            @NamedQuery(name = "Training.deleteAll", query = "DELETE FROM Training t"),
            @NamedQuery(name = "Training.countAll", query = "SELECT COUNT(t.ID) FROM Training t")
        })
public class Training implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @GeneratedValue
    @Column(name = "ID")
    private Integer ID;

    @Basic(optional = false)
    @Column(name = "employee_id")
    private String employeeId;

    @Basic(optional = false)
    @Column(name = "training_name")
    private String trainingName;

    @Basic(optional = false)
    @Column(name = "training_suspense_date")
    private Date trainingSuspenseDate;

    @Basic(optional = false)
    @Column(name = "training_complete")
    private Boolean trainingComplete;

    public Integer getID() {
        return ID;
    }

    public void setID(Integer ID) {
        this.ID = ID;
    }

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public void setTrainingName(String trainingName) {
        this.trainingName = trainingName;
    }

    public String getTrainingName() {
        return trainingName;
    }

    public void setTrainingSuspenseDate(Date trainingSuspsenseDate) {
        this.trainingSuspsenseDate = trainingSuspsenseDate;
    }

    public Date getTrainingSuspenseDate() {
        return trainingSuspsenseDate;
    }

    public void setTrainingComplete(Boolean trainingComplete) {
        this.trainingComplete = trainingComplete;
    }

    public Boolean getTrainingComplete() {
        return trainingComplete;
    }
}
java mysql jpa criteria-api
3个回答
0
投票

我可以确定您有一个针对查询生成的元模型。因此,最好的方法将是按如下所示扩展您的实体定义:


0
投票

您可以尝试cross join。本地sql有所不同,但结果却令人惊讶[]

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> employeeQuery = builder.createQuery(Employee.class);
Root<Employee> employee = employeeQuery.from(Employee.class);
Root<Employee> training= employeeQuery.from(Training.class);

employeeQuery.select(builder.construct(Employee.class,
    employee.get(Employee_.ID),
    employee.get(Employee_.firstName),
    employee.get(Employee_.lastName),
    training.get(Training_.trainingName),
    training.get(Training_.trainingSuspsnseDate),
    training.get(Training_.trainingComplete)))
.where(builder.equal(employee.get(Employee_.ID), training.get(Training_.employeeId)));

0
投票

[查看模型类,实体并不直接相关(即使employeeId中的Training应该是外键,但在实体关系中并未定义外键。因此,如果您希望在不更改现有实体的情况下使用它们,您将需要以下内容-

© www.soinside.com 2019 - 2024. All rights reserved.