我有两张table:
雇员
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查询创建一个criteria查询,但是连接有问题。这是我在谷歌上尝试过的:
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);
或
.
.
.
编辑:添加了我的模型类
员工.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;
}
}
培训.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;
}
}
4条答案
按热度按时间yhqotfr81#
你可以试试
cross join
. 本机sql有点不同,但结果与预期的一样6qqygrtg2#
此错误消息-不兼容类型:推断变量y具有不兼容的相等约束-表示您需要仔细检查要加入的列的数据类型。对于性能和高速比较,=两侧的数据类型应该相同。
gxwragnw3#
从模型类来看,实体并不是直接相关的(即使
employeeId
在Training
应该是外键,但在实体关系中没有这样定义。因此,如果您希望在不改变现有实体的情况下与现有实体合作,您需要以下内容-根据select子句Map属性的pojo(例如empres)。criteriaquery应在此pojo上初始化为-
CriteriaQuery<EmpRes> criteriaQuery = builder .createQuery(EmpRes.class);
由于实体不相关,生成的查询将具有交叉连接。代码看起来像-
但是,如果实体可以更改(这应该是理想的设计),则员工需要接受培训。所以,一个
@OneToMany
员工和培训模型类之间的关系应定义如下-员工.java
@OneToMany(mappedBy="employee") private Set<Training> trainings = new HashSet<>();
培训.java@ManyToOne @JoinColumn(name = "employeeId") private Employee employee;
准则查询相关代码-然后可以根据您的需求添加额外的where子句。这里是对criteriaapi的一个很好的参考。
64jmpszr4#
我可以看出您已经为您的查询生成了一个元模型。因此,最好的方法是扩展实体定义,如下所示:
您必须在
Training
班级:然后在你的
Employee
类添加站点引用:然后将条件查询更改为: