簡體   English   中英

Hibernate:org.hibernate.QueryParameterException:找不到命名參數

[英]Hibernate : org.hibernate.QueryParameterException: could not locate named parameter

我正在開發一個Spring-MVC應用程序,在該應用程序中我想同時對多個變量運行搜索。 但是代碼始終無法為第一個值本身設置參數。 我不知道為什么。 你能幫忙的話,我會很高興。

名單學生:

@Override
public List<Student> addHostSearchHistory(HostSearchHistory hostSearchHistory, Long hostId) {
    session = this.sessionFactory.getCurrentSession();
    Host host = (Host) session.get(Host.class,hostId);
    host.getHostSearchHistorySet().add(hostSearchHistory);
    hostSearchHistory.setHsHistory(host);
    session.save(hostSearchHistory);
    session.flush();

    StringBuilder sb = new StringBuilder();
    sb.append("from Student as s where ");

    if(!(hostSearchHistory.getCountry()==null)){
        sb.append("s.studentCountry=:").append(hostSearchHistory.getCountry());
    }
    if(!(hostSearchHistory.getCity()==null)){
        sb.append(" OR s.city=:").append(hostSearchHistory.getCity());
    }
    if(!(hostSearchHistory.getDrivingLicense()==null)){
        sb.append(" OR s.studentInfoDetails.drivingLicense=").append(hostSearchHistory.getDrivingLicense());
    }
    if(!(hostSearchHistory.getGender()==null)){
        sb.append(" OR s.gender=").append(hostSearchHistory.getGender());
    }
    if(!(hostSearchHistory.getMotherTongue()==null)){
        sb.append(" OR s.studentInfoDetails.motherTongue=:").append(hostSearchHistory.getMotherTongue());
    }
    if(!(hostSearchHistory.getSmoker()==null)){
        sb.append(" OR s.studentInfoDetails.smoker=").append(hostSearchHistory.getSmoker());
    }
    if(!(hostSearchHistory.getPreviousAuPair()==null)){
        sb.append(" OR s.studentInfoDetails.previouslyAuPair=").append(hostSearchHistory.getPreviousAuPair());
    }
    if(!(hostSearchHistory.getWillingToWork()==null)){
        sb.append(" OR s.studentInfoDetails.willingToWork=").append(hostSearchHistory.getWillingToWork());
    }
    if(!(hostSearchHistory.getWorkForSingleParent()==null)){
        sb.append(" OR s.studentInfoDetails.workForSingleParent=").append(hostSearchHistory.getWorkForSingleParent());
    }
    if(!(hostSearchHistory.getWorkingForDisabledChild()==null)){
        sb.append(" OR s.studentInfoDetails.workingForDisabledChild=").append(hostSearchHistory.getWorkingForDisabledChild());
    }
    if(!(hostSearchHistory.getOtherLanguages()==null)){
        sb.append(" OR s.studentInfoDetails.otherLanguages=:").append(hostSearchHistory.getOtherLanguages());
    }

    sb.append(" order by s.registrationDate desc");

    System.out.println("Sb.toString is "+sb.toString());

    Query query = session.createQuery(sb.toString());

// The code fails here
    if(!(hostSearchHistory.getCountry()==null)){
        query.setParameter("studentCountry",hostSearchHistory.getCountry());
    }
    if(!(hostSearchHistory.getCity()==null)){
        query.setParameter("city",hostSearchHistory.getCity());
    }
    if(!(hostSearchHistory.getDrivingLicense()==null)){
        query.setParameter("drivingLicense",hostSearchHistory.getDrivingLicense());
    }
    if(!(hostSearchHistory.getGender()==null)){
        query.setParameter("gender",hostSearchHistory.getGender());
    }
    if(!(hostSearchHistory.getMotherTongue()==null)){
        query.setParameter("motherTongue",hostSearchHistory.getMotherTongue());
    }
    if(!(hostSearchHistory.getSmoker()==null)){
        query.setParameter("smoker",hostSearchHistory.getSmoker());
    }
    if(!(hostSearchHistory.getPreviousAuPair()==null)){
        query.setParameter("previouslyAuPair",hostSearchHistory.getPreviousAuPair());
    }
    if(!(hostSearchHistory.getWillingToWork()==null)){
        query.setParameter("willingToWork",hostSearchHistory.getWillingToWork());
    }
    if(!(hostSearchHistory.getWorkForSingleParent()==null)){
        query.setParameter("workForSingleParent",hostSearchHistory.getWorkForSingleParent());
    }
    if(!(hostSearchHistory.getWorkingForDisabledChild()==null)){
        query.setParameter("workingForDisabledChild",hostSearchHistory.getWorkingForDisabledChild());
    }
    if(!(hostSearchHistory.getOtherLanguages()==null)){
        query.setParameter("otherLanguages",hostSearchHistory.getOtherLanguages());
    }

    List<Student> studentList = query.list();
    for(Student student : studentList){
        System.out.println("Student name is "+student.getUsername());
    }
   return studentList;

}

sb.toString()的輸出:

Sb.toString is from Student as s where s.studentCountry=:Germany OR s.city=:Hamburg OR s.studentInfoDetails.drivingLicense=true OR s.gender=male OR s.studentInfoDetails.smoker=true OR s.studentInfoDetails.willingToWork=true OR s.studentInfoDetails.workingForDisabledChild=true order by s.registrationDate desc

錯誤日志:

org.hibernate.QueryParameterException: could not locate named parameter [studentCountry]
    org.hibernate.engine.query.spi.ParameterMetadata.getNamedParameterDescriptor(ParameterMetadata.java:148)
    org.hibernate.engine.query.spi.ParameterMetadata.getNamedParameterExpectedType(ParameterMetadata.java:165)
    org.hibernate.internal.AbstractQueryImpl.determineType(AbstractQueryImpl.java:523)
    org.hibernate.internal.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:493)
    com.journaldev.spring.dao.HostSearchHistoryDAOImpl.addHostSearchHistory(HostSearchHistoryDAOImpl.java:82)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

我在做什么錯的家伙。 你能幫忙的話,我會很高興。 非常感謝。 :-)

您應該使用Predrag建議的第一個選項。 使用第二個選項有兩個主要缺點:

1)性能低下。 數據庫不會使用綁定變量來緩存一條准備好的語句,而是將其中許多用於輸入參數的所有組合。 這意味着要重新解析這些語句,並從緩存中清除其他准備好的語句。

2)安全性。 沒有綁定變量的語句非常容易受到SQL注入攻擊。 在您的特定示例中可能會,也可能不是,但是通常,假定惡意用戶(黑客:))為城市或其他字段輸入了以下或類似的過濾條件:

' union select null, USERNAME || ',' || PASSWORD, null, null... from USER_PASSWORDS --

他會將所有用戶名/密碼作為學生城市返回。 :)當然,這只是一個一般示例,它可能是數據庫中實際存在的其他查詢部分或數據庫中的其他敏感數據。

簡短答案-您寫了這個

query.setParameter("studentCountry",hostSearchHistory.getCountry());

但在sb.toString()輸出中,您沒有:studentCountry

方法的整個第一部分應該具有硬編碼的參數名稱,例如sb.append("s.studentCountry=:studentCountry") ,然后第二部分應該可以工作。

或者,使用sb.append("s.studentCountry='").append(hostSearchHistory.getCountry()).append("'"); 並且根本不使用參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM