我有以下(1:n)关系:SchoolClass->学生。 SchoolClass
可以有多个学生,并且Student
只能分配给一个SchoolClass
。在Hibernate(SchoolClass
类)中,我具有以下内容:
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;
}
但这不是一个好方法,因为现在有两个集合正在使用时修改一个表(它将抛出
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
类中的布尔值表示。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();