假设我有实体 Lecturer 和 Course 两个实体在 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;
}
}