How to select multiple records from table in hibernate - mysql

I am trying to get multiple values from a web page form and search the value from databate using hibernate query and retrieve the result and display it in a new page.
I need to get these text fields and even if any of the field is empty, I need to run a search query in database via controller and return set of results in a new page. I tried to store the result in array list of ArrayList but it didnt work. Could anyone please help me?
I am trying to get the text values from from web page in controller:
String lastname = request.getParameter("lastname");
String firstname = request.getParameter("firstname");
String gender = request.getParameter("gender");
String speciality = request.getParameter("speciality");
String keyword = request.getParameter("keyword");
I have Doctor's table which has all these texts fields stored. Lastname, firstname, gender, speciality. I have a class named doctor which links to the database.
#Entity
#Table(name="DOCTOR_DETAILS")
public class Doctor {
#Id
#Column (nullable=false)
private int npi;
#Column (nullable=false)
private String firstName;
#Column (nullable=false)
private String lastName;
#Column (nullable=false)
private String gender;
#Column (nullable=false)
private String speciality;
public int getNpi() {
return npi;
}
public void setNpi(int npi) {
this.npi = npi;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getSpeciality() {
return speciality;
}
public void setSpeciality(String speciality) {
this.speciality = speciality;
}
}
I need to run a select query to retrieve the records from table. Even if any of the 4 fields are empty, the query should retrieve the records.
try {
begin();
ArrayList <String> cntList = new ArrayList<String>();
Query q = getSession().createQuery("select * from
doctor where lastName = :lastName or firstName =:firstName or
gender=:gender or speciality = :speciality");
q.setString("username", username);
cntList = (ArrayList<String>) q.list();
commit();
return cntList;
}
I tried the below way of using Hibernate criteria, but I am getting an error. Am I going wrong anywhere?.
I wrote below code in my controller:
Below part in my DAO class which connects to the database.
But I am getting below error:
Could you please help me out?
The code worked fine and returned the list of results. I tried to follow the steps provided in tutorial point site, but I am getting a cast error.
"Type mismatch: cannot convert from int to doctor.
A type mismatch asking me to change
Doctor doctor = iterator.next();
to
int doctor = iterator.next();
which is something weird, since I cannot retrieve values from Doctor class.

You should use Hibernate criteria query with disjunction. It's been designed to handle this sort of situations. Try this code snippet
public List<Doctor> getSearchResult(String firstName, String lastName, String gender, String speciality, Session session) {
Criteria cr = session.createCriteria(Doctor.class);
Disjunction or = Restrictions.disjunction();
if (firstName != null)
or.add(Restrictions.ilike("firstName", firstName+"%"));
if (lastName != null)
or.add(Restrictions.ilike("lastName", "%"+lastName));
if (gender != null)
or.add(Restrictions.eq("gender", gender));
if (speciality != null)
or.add(Restrictions.ilike("speciality", "%"+speciality+"%"));
cr.add(or);
return (List<Doctor>) cr.list();
}
You can get idea about Hibernate Criteria queries here.

Related

Spring MVC can not delete a parent row?

I started to learn spring mvc. I was doing some practises and i encountered a logical error. In my example I have 2 entity class in spring mvc. Down there my code school_ıd is the primary key. When I try to delete a school from school list I gave an error like this
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails
Entity school:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="school_id")
private int schoolId;
#Column(name="school_name")
private String schoolName;
public int getSchoolId() {
return schoolId;
}
public void setSchoolId(int schoolId) {
this.schoolId = schoolId;
}
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
Entity Student
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Column(name="email")
private String email;
#OneToOne
#JoinColumn(name="school_id")
private School school;
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
School Controller delete method:
#GetMapping("/deleteSchool")
public String deleteSchool(#RequestParam("schoolID") int
theSchoolId) {
schoolService.deleteSchool(theSchoolId);
return "redirect:/school/list";
}
Delete Method SchoolDAOImpl:
#Override
public void deleteSchool(int theSchoolId) {
Session currentSession=sessionFactory.getCurrentSession();
Query theQuery=currentSession.createQuery("delete from School where id=:schoolID");
theQuery.setParameter("schoolID", theSchoolId);
theQuery.executeUpdate();
}
Actually i now the problem is i attemp to delete a school, theSchool has at least 1 student because of that i cannot delete a school. For this first i need to delete child in this example child is student after delete parent(school).
But i think my scenario does not avaliable for this. Please help me what should ı do?
You can update Student first:
#Override
public void deleteSchool(int theSchoolId) {
Session currentSession=sessionFactory.getCurrentSession();
Query updateStudentQuery=currentSession.createQuery("Update Student s SET s.school = null WHERE s.school.schoolId = :schoolId");
updateStudentQuery.setParameter("schoolID", theSchoolId);
updateStudentQuery.executeUpdate();
Query theQuery=currentSession.createQuery("delete from School where id=:schoolID");
theQuery.setParameter("schoolID", theSchoolId);
theQuery.executeUpdate();
}
or update using Stundent's DAO and then exec the school's delete query.
I couldnt test so i dont know if it works the "WHERE s.school.schoolId = :schoolId" or you have to make a where with a subquery. If doesn't works, try with a native query:
Query updateStudentQuery=currentSession.createNativeQuery("sql here");
Instead of
Query updateStudentQuery=currentSession.createQuery("Update Student s SET s.school = null WHERE s.school.schoolId = :schoolId");
Also, if you want to make the relation bidirectional, add this to School Entity:
#OneToOne(mappedBy = "school")
private Student student;
By the way, i guess that the relation is #ManyToOne and not #OneToOne, isn't it?
You have to delete the integrity constraint of whatever the DB you are using or you should first delete the child and then parent or you can look the cascade rule of that in hibernate https://thoughts-on-java.org/hibernate-tips-how-to-delete-child-entities/

Trying to extend a class in java and running into problems

I was wondering if anyone could help me with a problem I am encountering when trying to extend a class. I want to be able to add a first name and a last name which is part of my base class to an extended class.
Here is a snippet from my base class Person.java
public class Person
{
private String firstName = "";
private String lastName = "";
private String id = "";
public Person()
{
}
public Person(String firstName, String lastName, String id)
{
this.firstName = firstName;
this.lastName = lastName;
this.id = id;
}
And here is the class where I am trying to extend the base class:
public TeamMember(String firstName, String lastName, String team, String id, String role)
{
super(firstName, lastName);
this.team = team;
this.id = id;
this.role = role;
}
The error I receive is:
Error:(25, 9) java: constructor Person in class xxx.xxxx.xxx.xx
cannot be applied to given types;
required: no arguments
found: java.lang.String,java.lang.String
reason: actual and formal argument lists differ in length
I had to create a constructor that matched what was in the super() in the extended class in the base class.
This is what I added to the base class to make it work.
public Person(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
Try this.
public TeamMember(String firstName, String lastName, String team, String id, String role)
{
super(firstName, lastName, id);
this.team = team;
this.role = role;
}
Id is a private property of base class, so cannot be accessed in derived class.
private String id = "";

Getting a java.lang.StringIndexOutOfBoundsException using Constructor

My professor asked for us to make two separate java classes for a popular problem where you have to build an employee email based off of a first name, last name, and employee ID number.
If you'd like to see the problem:
Assignment
The problem is happening in the substring. I think I vaguely know why, but I'm not actually entirely sure how to solve the issue.
Here's the first class:
public class EmployeeSchmidt
{
public String FirstName = "";
public String LastName = "";
public String EmID = "";
public String Email = "";
public EmployeeSchmidt(String FirstName, String LastName, String EmID)
{
this.FirstName = FirstName;
this.LastName = LastName;
this.EmID = EmID;
Generator();
}
public String getFirstName()
{
return FirstName;
}
public void setFirstName(String em)
{
FirstName = em;
}
public String getLastName()
{
return LastName;
}
public void setLastName(String em)
{
LastName = em;
}
public String getEmID()
{
return EmID;
}
public void setEmID(String em)
{
EmID = em;
}
public String getEmail()
{
return Email;
}
public void setEmail(String em)
{
Email = em;
}
String fName = (FirstName.substring(0,2));
String lName = (LastName.substring(0,4));
String eID = (EmID.substring(3,4));
public void Generator()
{
Email = (fName + lName + eID + "#initech.com");
}
}
And the second class:
import java.util.Scanner;
public class EmployeeInfo
{
public static void main(String[] args)
{
EmployeeSchmidt em1 = new EmployeeSchmidt("","","");
Scanner in = new Scanner (System.in);
System.out.println("Please enter your first name.");
em1.setFirstName(in.next());
System.out.println("Please enter your last name.");
em1.setLastName(in.next());
System.out.println("Please enter your 5-digit Employee ID.");
em1.setEmID(in.next());
em1.Generator();
System.out.println();
System.out.println(em1.getFirstName());
System.out.println(em1.getLastName());
System.out.println(em1.getEmID());
System.out.println("Your Employee Email is " + em1.getEmail());
}
}
And this is the error I'm getting:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
at java.lang.String.substring(String.java:1963)
at EmployeeSchmidt.<init>(EmployeeSchmidt.java:57)
at EmployeeInfo.main(EmployeeInfo.java:6)
The Scanner isn't necessary, but our professor offered extra credit if we were able to do it. I'm just absolutely lost.
There is an error cause you are trying to substring the name variables and assign them to member variables in the class body. Not inside any method. As they will be empty strings when the class gets intialized, the exception is thrown.
Change the EmployeeSchmidt java class to following.
public class EmployeeSchmidt {
public String FirstName = "";
public String LastName = "";
public String EmID = "";
public String Email = "";
public EmployeeSchmidt(String FirstName, String LastName, String EmID) {
this.FirstName = FirstName;
this.LastName = LastName;
this.EmID = EmID;
Generator();
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String em) {
FirstName = em;
}
public String getLastName() {
return LastName;
}
public void setLastName(String em) {
LastName = em;
}
public String getEmID() {
return EmID;
}
public void setEmID(String em) {
EmID = em;
}
public String getEmail() {
return Email;
}
public void setEmail(String em) {
Email = em;
}
public void Generator() {
String fName = null;
if (FirstName != null && FirstName.length() >= 2) {
fName = (FirstName.substring(0, 2));
}
String lName = null;
if (LastName != null && LastName.length()>=4) {
lName = (LastName.substring(0, 4));
}
String eID = null;
if (EmID != null && EmID.length()>=4) {
eID = (EmID.substring(3, 4));
}
Email = (fName + lName + eID + "#initech.com");
}
}
Note the placement of the declarations of variables fName, lName, and eID in your code:
String fName = (FirstName.substring(0,2));
String lName = (LastName.substring(0,4));
String eID = (EmID.substring(3,4));
public void Generator()
{
Email = (fName + lName + eID + "#initech.com");
}
They are outside any method, and therefore they are instance variables. These initializations will be performed when each instance is initialized, before the body of the constructor. At that point, you are guaranteed that the base strings are all empty (because of their own, prior, initializers).
Perhaps you want those to be local variables of the Generator() method. In that case, their initializers would not run until Generator() is invoked, at which point the FirstName, LastName, and EmID variables will have the values set by the constructor.
Note, however, that even that does not fully protect you from an out-of-bounds string index. Consider, for instance, an employee whose last name is "Wu" -- that's fewer than four characters. There are two things you can do to solve this problem:
Pad the strings with blanks or some other character to ensure that they are at least as long as you need them to be before computing the substrings (and be prepared for trailing blanks/whatever in the results; example: fName = (FirstName + "..").subString(0,2);), or
Test the string lengths before trying to extract substrings, and use the whole string instead where appropriate. Alternatively, fail (throwing an exception) if the string is not long enough.
you must make the substring in method because if it outside the method you make substring of the
FirstName = "";
LastName = "";
EmID = "";
Email = "";
and that's error you want to substring of the input of user
you can make that solution make it in method
public String getinfo()
{ String fName = (FirstName.substring(0,2));
String lName = (LastName.substring(0,4));
String eID = (EmID.substring(3,4));
Email=Generator(fName,lName,eID);
return Email;}
public String Generator(String fName,String lName,String eID)
{
Email = (fName + lName + eID + "#initech.com");
return Email;
then in the second class you do that
System.out.println("Your Employee Email is " + em1.getinfo());
without Generator before
i hope you understand me

Empty string when query for VACHAR data type in MySQL using Spring JdbcTemplate and Spring Data JPA

I've been getting this strange problem with MySQL VARCHAR data type.
I have this database table in MySQL, there are two fields of VARCHAR data type,let's call these field First_name and last_name. Problem is, when querying for these particular fields using Spring JdbcTemplate or using Spring Data JpaRepository interface, it always return an empty string or white spaces even though these fields have values.
I also tried to update the values into numeric like 12345 for both fields and alter the data type into INT and had the JdbcTemplate to queryForInt and it's giving me the correct result.
Here's the Entity class:
#Entity
#Table(name = "tb_user")
public class AppUser extends BaseEntity{
private static final long serialVersionUID = -1008862792657260298L;
#Id
#GeneratedValue( strategy = GenerationType.IDENTITY )
#Column(name = "id")
private Integer id;
#Column(name = "first_name", length = 30, nullable = false)
String firstName;
#Column(name = "last_name", length = 30)
String lastName;
}
The code used for testing:
//code #1
JdbcTemplate jt = new JdbcTemplate(ds);
String sql = "select first_name from tb_user where id=3";
JdbcTemplate jt = new JdbcTemplate(ds);
try {
System.out.println(jt.queryForObject(sql, String.class)); //returns empty string/white space instead of actual value, e.g: JOHN
} catch (Exception e) {
e.printStackTrace();
} finally{
}
//code #2
String sql = "select first_name, last_name from tb_user where id=3";
JdbcTemplate jt = new JdbcTemplate(ds);
try {
jt.query(sql, new RowMapper<UserDTO>(){
#Override
public UserDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
System.out.println(rs.getString("first_name") + " " + rs.getString("last_name")); //also returns empty string/white spaces
return null;
}
});
} catch (Exception e) {
e.printStackTrace();
} finally{
}
Please advice. Thank you.
-Ipie-

how to retrieve a column value by passing another column value

I have a table client having a column cid.
The entity class is
public class client{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Version
#Column(name = "version")
private Integer version;
#NotNull
#ManyToOne
private Client cid;
....
}
In my session I have kept the client id and retrieving by the following way
String clientId = request.getSession().getAttribute("clientId").toString();
This is my controller code
List l=serviceClientServiceImpl.getSavedParents(clientId);
uiModel.addAttribute("savedParents",l);
This is my getSavedParents code
public List getSavedParents(String cid)
{
List l=serviceClientDaoImpl.getSavedParents(cid);
return l;
}
and this is my query code
public List getSavedParents(String cid)
{
String queryString="select distinct pid from ClientParentQuestion where cid="+cid;
Query query=entityManagerUtil.getQuery(queryString);
return query.getResultList();
}
when I try to receive in my jsp using ${savedParents} then I get nothing.
I do not understand where do I make mistake.
Can any body solve my problem?
Your code is vulnerable to SQL injection.
So client has a self-reference to itself.
I'd refactor the dao method to:
public List getSavedParents(String cid) {
return getEntityManager()
.createQuery("select distinct cpq.pid from ClientParentQuestion cpq where cpq.cid.id = :cid")
.setParameter("cid, Long.valueOf(cid))
.getResultList();
}
Also use an alias for the entity when you want to specify what properties you'd like to return or match.
It's much more readable and it follows the JPQL/HQL projection idioms.