【问题标题】:How to write this JPA query term?如何编写这个 JPA 查询术语?
【发布时间】:2016-02-25 07:02:07
【问题描述】:

我有两张桌子;

Create table Student (
    id int NOT NULL AUTO_INCREMENT,
    name varchar(35),
    PRIMARY KEY (id)
);

Create table Course (
    id int NOT NULL AUTO_INCREMENT,
    student_id int,
    name varchar(35),
    PRIMARY KEY (id),
    FOREIGN KEY (student_id)
    REFERENCES Student(id)
    ON DELETE CASCADE
);

查询:查找学生“John”上的所有课程。

Select C.name 
FROM Course C
JOIN Student S
  ON S.id=C.student_id 
WHERE S.name='John';

如何用 JPA 查询语言编写这个?如何编写涉及两个这样的由外键关联的表的标准?

public List<Course> findCourseByStudentName(String name) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Course> criteria = cb.createQuery(Course.class);
    Root<Course> courseRoot = criteria.from(Course.class);

    Join<Course,Student> courseStudent = courseRoot.join(Course_.student);
    criteria.select(courseRoot).where(cb.equal(courseStudent.get(Student_.name), "John"));

}

编辑: 这是Student类,Student.java

@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = "name"))
public class Student implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    @Size(min = 1, max = 35)
    private String name;

    @OneToMany(cascade = CascadeType.ALL, mappedBy="student")
    Set<Course> courses;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setCourses(Set<course> courses) {
        this.course = course;
    }        

    public Set<Course> getCourses() { 
       return courses; 
    }
}

这是课程类,Course.java

@Entity
@Table
public class Course implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull 
    @ManyToOne( targetEntity = Student.class ) 
    @JoinColumn( name = "student_id", referencedColumnName = "id") 
    private Student student; 

    @NotNull
    @Size(min = 1, max = 35)
    private String name;

    public void setId(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    public void setStudent(String student) {
        this.student = student;
    }

    public String getStudent() {
        return student;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return Name;
    }
}

【问题讨论】:

标签: java hibernate jpa


【解决方案1】:

首先,您必须创建两个实体StudentCourse,并在Course 中至少添加@ManyToOne 关系。你可以使用 JPQL,比如:

    SELECT C.name
      FROM Cource C
INNER JOIN Student S
     WHERE S.name = :studentName

之后你应该在查询中添加参数并得到List&lt;String&gt;作为结果

【讨论】:

  • 应该将@OneToMany 放在Student 类中吗?由于学生有多个课程。请查看我编辑的课程。
  • 在这种情况下没有必要,但如果你想从学生班获得Set&lt;Cources&gt; 的课程或在JPQL 中使用从StudentCource 的连接 - 你应该添加它。此外,阅读有关级联操作和延迟加载的信息也会很有用
  • 上面的类,我收到这个错误“Caused by: javax.persistence.PersistenceException: [PersistenceUnit: registration-ds] Unable to build Hibernate SessionFactory Caused by: org.hibernate.MappingException: 无法确定输入:java.util.Set,表:Student,列:[org.hibernate.mapping.Column(courses)]"}}"。
  • 在你的代码中 Cource 类字段 Student 不能是 String 而是 Student 并且注释 @ManyToOne( targetEntity = Student.class ) @JoinColumn( name = "student_id" , referencedColumnName = "id")
  • " @ManyToOne( targetEntity = Student.class ) @JoinColumn( name = "student_id", referencedColumnName = "id" ) " 这应该添加到哪个方法中?
【解决方案2】:

我的最新版本给出了正确答案。感谢所有cmets。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-26
    • 2011-03-22
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 2011-09-13
    • 2012-11-01
    相关资源
    最近更新 更多