假设我有实体讲师和课程两个实体在JPA 2.0中有多对多的关系
拥有一个没有注释的实体LecturerCourse(带有多表选择列,没有注释)和JPQL就可以了。
final Query query = em.createQuery(
"select new com.cs.entity.LectureCourse(l.id, l.name, l.surName, " +
"l.type, c.code, c.name) from lecturer l join l.courses c where l.id = :l_id"
);
如何使用JPA Criteria API执行相同的操作?
以下是Lecturer和Courses的代码
@Entity(name = "course")
public class Course implements Serializable {
@Id
@Column(name = "course_code", columnDefinition = "char(6)",
unique = true, nullable = false)
private String code;
@Column(name = "course_name")
private String name;
@ManyToMany(mappedBy = "courseSet", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Student> students;
@ManyToOne(fetch = FetchType.EAGER, targetEntity = Lecturer.class)
@JoinColumn(name = "lecture_id")
private Lecturer lecturer;
public Course() {
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
public Lecturer getLecturer() {
return lecturer;
}
public void setLecturer(Lecturer lecturer) {
this.lecturer = lecturer;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Course)) return false;
Course course = (Course) o;
if (code != null ? !code.equals(course.code) : course.code != null) return false;
if (name != null ? !name.equals(course.name) : course.name != null) return false;
if (students != null ? !students.equals(course.students) : course.students != null) return false;
return true;
}
@Override
public int hashCode() {
int result = code != null ? code.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (students != null ? students.hashCode() : 0);
return result;
}
}
@Entity(name = "lecturer")
public class Lecturer {
public static enum LectureType{
FULL_TIME, PART_TIME
}
@Id
@Column(name = "lecture_id", nullable = false,
unique = true, columnDefinition = "char(8)")
private String id;
@Column(name = "lecture_name", length = 20, nullable = false)
private String name;
@Column(name = "lecture_sur_name", length = 20, nullable = false)
private String surName;
@Enumerated(EnumType.ORDINAL)
@Column(name = "lecture_type", columnDefinition = "char(1)")
private LectureType type;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "lecturer", fetch = FetchType.EAGER)
private Set<Course> courses;
public Lecturer() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurName() {
return surName;
}
public void setSurName(String surName) {
this.surName = surName;
}
public LectureType getType() {
return type;
}
public void setType(LectureType type) {
this.type = type;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
for(final Course course : this.courses){
course.setLecturer(this);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Lecturer)) return false;
Lecturer lecturer = (Lecturer) o;
if (id != null ? !id.equals(lecturer.id) : lecturer.id != null) return false;
if (name != null ? !name.equals(lecturer.name) : lecturer.name != null) return false;
if (surName != null ? !surName.equals(lecturer.surName) : lecturer.surName != null) return false;
if (type != lecturer.type) return false;
return true;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (surName != null ? surName.hashCode() : 0);
result = 31 * result + (type != null ? type.hashCode() : 0);
return result;
}
}
答案 0 :(得分:1)
你正在寻找的是CriteriaQuery#multiselect的一种形式......我假设你是generating an appropriate static metamodel(这是EntityClass_.field作品的来源),但我手工工作类似的事情:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<LectureCourse> criteria = builder.createQuery(LectureCourse.class);
Root<Lecturer> l = criteria.from(Lecturer.class);
Path<Course> c = l.join(Lecturer_.courses);
ParameterExpression<String> l_id = builder.parameter(String.class);
Predicate lecturerIdMatches = builder.equal(l.get(Lecturer_.id),l_id);
TypedQuery<LectureCourse> query = em.createQuery(criteria.multiselect(l.get(Lecturer_.id), l.get(Lecturer_.name), l.get(Lecturer_.surName), l.get(Lecturer_.type), c.get(Course_.code), c.get(Course_.name)).where(lecturerIdMatches));
query.setParameter(l_id,"queryvalue");
List<LectureCourse> results = query.getResultList();