java - 如何在JPA Criteria中做到这一点?

标签 java jpa-2.0 criteria-api

假设我有实体 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 执行相同操作?

这里分别是讲师和类(class)的代码

@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;
    }
}

最佳答案

您正在寻找的是 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();

关于java - 如何在JPA Criteria中做到这一点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14050005/

相关文章:

Java 行 IO 与 C++ IO?

java - 无法为 org.gradle.api.internal.artifacts.dsl.dependency.DefaultDependencyHandler 类型的对象设置未知属性 'nav_version'

jsf-2 - JSF 2 : h:link and getrowdata

java - JPA 2 和 Hibernate 之间有什么关系?

java - JPA 标准 API : Aggregating on Multiple Columns with IF Condition

java - JPA 2 - 获取@OneToMany 关系中列表的最后一个元素

java - CountDownLatch 中断异常

java - 如何在特定连接上使用不同的证书?

mysql - Eclipse Virgo 注入(inject)的 JPA EntityManager 不连接到数据库

java - 如何正确确定 "exists"JPA Criteria Query 子句是否返回 true 或 false?