【问题标题】:Hibernate - issue with criteria.createAlias() return information as if restriction was not specifiedHibernate - criteria.createAlias() 返回信息的问题,就好像没有指定限制一样
【发布时间】:2014-07-24 01:12:21
【问题描述】:

我有表学生,可能有多个注册,每个注册都属于一个注册机构。

如果我只搜索添加学生信息,则查询返回 ok。

至于注册和注册机构,我知道过滤器已添加到查询中,因为例如,对于学生 1,我已将其与课程 c1 和 c2 相关联。因此,如果我插入 c3 作为条件,查询不会返回任何结果,但如果我添加 c1 或 c2,查询将返回与 c1 和 c2 相关的两条记录。

感谢任何帮助。提前谢谢!

public List findByCriteria(Student student) {

    String firstName = student.getFirstName();
    String lastName = student.getFamilyName();
    String sexCode = student.getSexCode();
    Date dob = student.getDateOfBirth();
    Integer courseNo = 0;
    Integer collegeNo = 0;
    Integer latestEnrolmentYear = 0;
    if (student.getEnrolments() != null
            && student.getEnrolments().size() > 0) {
        Enrolment enrolment = (Enrolment) student.getEnrolments().get(0);
        if (enrolment.getCourseNo() != null) {
            courseNo = enrolment.getCourseNo();
        }
        if (enrolment.getEnrolmentInstitution().getInstNo() != null) {
            collegeNo = enrolment.getEnrolmentInstitution().getInstNo();
        }
        if (enrolment.getLatestEnrolmentYear() != null) {
            latestEnrolmentYear = enrolment.getLatestEnrolmentYear();
        }

    }
    List<Student> students = new ArrayList<Student>();
    getCurrentSession().enableFetchProfile("studentEnrolments");//required if we don't add "enrolment" or "enrolment institution" info as criteria

    Criteria criteria = getCurrentSession().createCriteria(Student.class, "student");

    if (!StringUtils.isBlank(lastName) && lastName.length() >= 0) {
        criteria.add(Restrictions.like("familyName", lastName,
                MatchMode.ANYWHERE));
    }

    if (!StringUtils.isBlank(firstName) && firstName.length() >= 0) {
        criteria.add(Restrictions.like("firstName", firstName,
                MatchMode.ANYWHERE));
    }

    if (!StringUtils.isBlank(sexCode)) {
        criteria.add(Restrictions.eq("sexCode", sexCode));
    }

    if (dob != null && !dob.equals(new Date())) {
        criteria.add(Restrictions.eq("dateOfBirth", dob));
    }

    if (courseNo > 0 || latestEnrolmentYear > 0 || collegeNo > 0) {

        criteria.createAlias("student.enrolments", "enrolment");                

        if (courseNo > 0) {
            criteria.add(Restrictions.eq("enrolment.courseNo", courseNo));
        }
        if (latestEnrolmentYear > 0) {
            criteria.add(Restrictions.eq("enrolment.latestEnrolmentYear", latestEnrolmentYear));        
        }

        if (collegeNo > 0) {            
            criteria.add(Restrictions.eq("enrolment.enrolmentInstitution.instNo", collegeNo));              
            criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); //otherwise, instNo criteria may create multiple rows per result
        }

        students = criteria.list();

        //needs to initialize because alias creation leads to lazy initialization (otherwise, search adding the fields below as criteria would fail)
        if (students.size() > 0) { 
            forceLazyInitialization(students);          
        }

    } else{

        getCurrentSession().enableFetchProfile("studentEnrolments");//required if we don't add "enrolment" or "enrolment institution" info as criteria      
        students = criteria.list();
        getCurrentSession().disableFetchProfile("studentEnrolments");   
    }



    return students;
}

【问题讨论】:

    标签: hibernate criteria


    【解决方案1】:

    如果我理解正确,您会期望集合 enrolments 将被预过滤,因为预期的 SQL 查询是:

    SELECT ..
    FROM Student 
    JOIN Enrolment ON ...
    WHERE Enrolment.courseNo = 'c1'
    

    因为这肯定不会返回 courseNo &lt;&gt; 'c2' 的记录

    但这不是它的工作方式。此选择正在影响根(学生)选择...并且注册再次在事后加载...很可能是懒惰的。

    如果您只想在注册中查看课程“c1”,您应该在事后、运行时过滤它们或使用过滤器:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-23
      • 2021-07-23
      • 2015-06-28
      • 2018-01-31
      • 2019-01-23
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多