使用 Hibernate 对 @OneToMany 包关系的多个引用
Multiple references to @OneToMany bag relationships using Hibernate
我有以下 (1:n) 关系:SchoolClass -> Students。 SchoolClass
可以有多个学生,Student
只能分配给一个SchoolClass
。在 Hibernate (SchoolClass
class) 中,我有以下内容:
private transient List students;
/**
* @return Returns students.
* @hibernate.bag lazy="true" cascade="all" where="(graduated_with_honors=0)"
* @hibernate.collection-key column="class_id"
* @hibernate.collection-one-to-many class="my.project.namespace.Student"
*/
public List getStudents() {
if (students == null) {
students = new Vector();
}
return students;
}
现在,我想创建另一种方法,列出 SchoolClass 的所有学生(还有以优异成绩毕业的学生,所以 graduated_with_honors
可以是 0 或 1).我试过以下:
private transient List students, allStudents;
/**
* @return Returns students.
* @hibernate.bag lazy="true" cascade="all" where="(graduated_with_honors=0)"
* @hibernate.collection-key column="class_id"
* @hibernate.collection-one-to-many class="my.project.namespace.Student"
*/
public List getStudents() {
if (students == null) {
students = new Vector();
}
return students;
}
/**
* @return Returns students.
* @hibernate.bag lazy="true" cascade="all"
* @hibernate.collection-key column="class_id"
* @hibernate.collection-one-to-many class="my.project.namespace.Student"
*/
public List getAllStudents() {
if (allStudents == null) {
allStudents = new Vector();
}
return allStudents;
}
但这不是好方法,因为现在我们有 两个集合正在修改一个 table(它会抛出 hibernate found shared references to a collection
异常) .
有人知道怎么做吗?或者,有没有办法,如何在@hibernate.bag where
子句中插入一个参数,这样我们就可以根据情况更改where
子句?
提前致谢。
编辑:
private transient List students;
- 这必须保持不变,我必须保持原样。
你的映射有很多错误:
集合应始终不可为空:
private List<Student> students = new ArrayList<>();
为什么使用 Vector
而不是 List
? Vector
是同步的,而 ArrayList
不是。你真的要同时使用一个实体吗?
您不能使用java中保留的术语class
,所以也许最好将其重命名为Course
。
graduated_with_honors
关系最好用 Student
class.
中的布尔值表示
private boolean graduatedWithHonor;
然后,您可以简单查询所有Student(s)
以优异成绩毕业:
Course course = ...;
List<Student> honourableStudents = entityManager.createQuery(
"select s " +
"from Student s " +
"where s.graduatedWithHonor = true " +
"and s.course = :course", Student.class)
.setParameter("course", course)
.getResultList();
我有以下 (1:n) 关系:SchoolClass -> Students。 SchoolClass
可以有多个学生,Student
只能分配给一个SchoolClass
。在 Hibernate (SchoolClass
class) 中,我有以下内容:
private transient List students;
/**
* @return Returns students.
* @hibernate.bag lazy="true" cascade="all" where="(graduated_with_honors=0)"
* @hibernate.collection-key column="class_id"
* @hibernate.collection-one-to-many class="my.project.namespace.Student"
*/
public List getStudents() {
if (students == null) {
students = new Vector();
}
return students;
}
现在,我想创建另一种方法,列出 SchoolClass 的所有学生(还有以优异成绩毕业的学生,所以 graduated_with_honors
可以是 0 或 1).我试过以下:
private transient List students, allStudents;
/**
* @return Returns students.
* @hibernate.bag lazy="true" cascade="all" where="(graduated_with_honors=0)"
* @hibernate.collection-key column="class_id"
* @hibernate.collection-one-to-many class="my.project.namespace.Student"
*/
public List getStudents() {
if (students == null) {
students = new Vector();
}
return students;
}
/**
* @return Returns students.
* @hibernate.bag lazy="true" cascade="all"
* @hibernate.collection-key column="class_id"
* @hibernate.collection-one-to-many class="my.project.namespace.Student"
*/
public List getAllStudents() {
if (allStudents == null) {
allStudents = new Vector();
}
return allStudents;
}
但这不是好方法,因为现在我们有 两个集合正在修改一个 table(它会抛出 hibernate found shared references to a collection
异常) .
有人知道怎么做吗?或者,有没有办法,如何在@hibernate.bag where
子句中插入一个参数,这样我们就可以根据情况更改where
子句?
提前致谢。
编辑:
private transient List students;
- 这必须保持不变,我必须保持原样。
你的映射有很多错误:
集合应始终不可为空:
private List<Student> students = new ArrayList<>();
为什么使用
Vector
而不是List
?Vector
是同步的,而ArrayList
不是。你真的要同时使用一个实体吗?您不能使用java中保留的术语
class
,所以也许最好将其重命名为Course
。
中的布尔值表示graduated_with_honors
关系最好用Student
class.private boolean graduatedWithHonor;
然后,您可以简单查询所有Student(s)
以优异成绩毕业:
Course course = ...;
List<Student> honourableStudents = entityManager.createQuery(
"select s " +
"from Student s " +
"where s.graduatedWithHonor = true " +
"and s.course = :course", Student.class)
.setParameter("course", course)
.getResultList();