I am working on a Spring-MVC application in which I would like to search in the database with some mentioned criteria. Unfortunately, they are around 10-12 of them. So I had asked a question before on SO as to how I can break them up into small chunks, check which of them are not null, and use them as a parameter. I was partially successful by using a StringBuilder as mentioned below.
The problem I am having is how can I set the query.setParameter("variablename",variableName) for values which are not null. First the example :
@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().equals(""))){
sb.append("s.country=:").append(hostSearchHistory.getCountry());
}
if(!(hostSearchHistory.getCity().equals(""))){
sb.append("OR s.city=:").append(hostSearchHistory.getCity());
}
if(!(hostSearchHistory.getDrivingLicense().equals(""))){
sb.append("OR s.studentDetails.drivingLicense=").append(hostSearchHistory.getDrivingLicense());
}
if(!(hostSearchHistory.getGender().equals(""))){
sb.append("OR s.gender=").append(hostSearchHistory.getGender());
}
if(!(hostSearchHistory.getMotherTongue().equals(""))){
sb.append("OR s.studentDetails.motherTongue=:").append(hostSearchHistory.getMotherTongue());
}
if(!(hostSearchHistory.getSmoker().equals(""))){
sb.append("OR s.studentDetails.smoker=").append(hostSearchHistory.getSmoker());
}
if(!(hostSearchHistory.getPreviousAuPair().equals(""))){
sb.append("OR s.studentDetails.previouslyAuPair=").append(hostSearchHistory.getPreviousAuPair());
}
if(!(hostSearchHistory.getWillingToWork().equals(""))){
sb.append("OR s.studentDetails.willingToWork=").append(hostSearchHistory.getWillingToWork());
}
if(!(hostSearchHistory.getWorkForSingleParent().equals(""))){
sb.append("OR s.studentDetails.workForSingleParent=").append(hostSearchHistory.getWorkForSingleParent());
}
if(!(hostSearchHistory.getWorkingForDisabledChild().equals(""))){
sb.append("OR s.studentDetails.workingForDisabledChild").append(hostSearchHistory.getWorkingForDisabledChild());
}
sb.append(" order by s.registrationDate desc");
Query query = session.createQuery(sb.toString());
if(!(hostSearchHistory.getCountry().equals(""))){
query.setParameter("country",hostSearchHistory.getCountry());
}
if(!(hostSearchHistory.getCity().equals(""))){
query.setParameter("city",hostSearchHistory.getCity());
}
if(!(hostSearchHistory.getDrivingLicense().equals(""))){
query.setParameter("drivingLicense",hostSearchHistory.getDrivingLicense());
}
if(!(hostSearchHistory.getGender().equals(""))){
query.setParameter("gender",hostSearchHistory.getGender());
}
if(!(hostSearchHistory.getMotherTongue().equals(""))){
query.setParameter("motherTongue",hostSearchHistory.getMotherTongue());
}
if(!(hostSearchHistory.getSmoker().equals(""))){
query.setParameter("smoker",hostSearchHistory.getSmoker());
}
if(!(hostSearchHistory.getPreviousAuPair().equals(""))){
query.setParameter("previouslyAuPair",hostSearchHistory.getPreviousAuPair());
}
if(!(hostSearchHistory.getWillingToWork().equals(""))){
query.setParameter("willingToWork",hostSearchHistory.getWillingToWork());
}
if(!(hostSearchHistory.getWorkForSingleParent().equals(""))){
query.setParameter("workForSingleParent",hostSearchHistory.getWorkForSingleParent());
}
if(!(hostSearchHistory.getWorkingForDisabledChild().equals(""))){
query.setParameter("workingForDisabledChild",hostSearchHistory.getWorkingForDisabledChild());
}
List<Student> studentList = query.list();
for(Student student : studentList){
System.out.println("Student name is "+student.getUsername());
}
return studentList;
}
Now even when I can build the query like this, I again have to keep digging up the HostSearchHistory and then set the query.setParameters(). Is there any alternative to that?
Also, as you guys may have noticed, the last sb.append requests information from a mapping, specifically one-to-one mapping with StudentInfo. Is that syntax correct? I am posting the model of Student and StudentInfo below for further clarity. Kindly let me know. Thanks a lot.
Student model :
@Entity
@Table(name="student")
public class Student implements UserDetails{
@Id
@Column(name="studentid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "student_seq_gen")
@SequenceGenerator(name = "student_seq_gen",sequenceName = "student_seq")
private Long studentid;
@OneToOne(mappedBy = "studentDetails",fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
private StudentInfo studentInfoDetails = new StudentInfo();
public void setStudentInfoDetails(StudentInfo studentInfoDetails){
this.studentInfoDetails = studentInfoDetails;
}
public StudentInfo getStudentInfoDetails(){
return this.studentInfoDetails;
}
}
StudentInfo model :
@Entity
@Table(name = "studentinfo")
public class StudentInfo {
@Id
@Column(name="infoid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "student_info_gen")
@SequenceGenerator(name = "student_info_gen",sequenceName = "student_info_seq")
private Long studentInfoId;
@OneToOne
@JoinColumn(name = "studentid",nullable = false)
private Student studentDetails;
public Student getStudentDetails() {
return studentDetails;
}
public void setStudentDetails(Student studentDetails) {
this.studentDetails = studentDetails;
}
}
Thank you for your help.