我有两个表:
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;
}
}
我可以确定您有一个针对查询生成的元模型。因此,最好的方法将是按如下所示扩展您的实体定义:
您可以尝试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)));
[查看模型类,实体并不直接相关(即使employeeId
中的Training
应该是外键,但在实体关系中并未定义外键。因此,如果您希望在不更改现有实体的情况下使用它们,您将需要以下内容-