column alias in hibernate projections - java

similar questions have been asked before, but not answered yet, i want to perform simple query as follow
select first_name as name from hr_employee
I need to alias column "first_name" as "name"
this is my controller
`public #ResponseBody List EmployeeJson()
{
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
List list = session.createCriteria(HrEmployee.class)
.add(Restrictions.eq("employeeId", 1))
.setProjection(Projections.projectionList()
.add(Projections.property("firstName"), "name") )
.setResultTransformer(Transformers.aliasToBean(HrEmployee.class)).list();
return list;
}`
by running code we get "could not resolve property: name" as column defined in bean class is "first_name" not "name".
`
#Table(name = "hr_employee")
#Entity
#JsonIgnoreProperties({"hibernateLazyInitializer"})
public class HrEmployee {
#Column(name="first_name")
private String firstName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
`

You have to make to setter and getter methods for name like:
public void setName(String name){this.firstName = name;}
public String getName(){return this.firstName;}
there is no need to make variable "name"
your bean class shoul be like this:
#Table(name = "hr_employee")
#Entity
#JsonIgnoreProperties({"hibernateLazyInitializer"})
public class HrEmployee {
#Column(name="first_name")
private String firstName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setName(String name){
this.firstName = name;
}
public String getName(){
return this.firstName;
}
}
then the Transformer will call the method setName();

Related

H2 database columns and values don't converge JAVA Spring

I am new one at java and spring framework and have this problem. I have class, which has fields, that should be columns in H2. It looks like this:
package com.bankapp.bankwebapplication.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class PersonClient implements Client {
#Id
#Column(nullable = false, unique = true)
private Long id;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
#Column(nullable = false)
private String firstName;
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
#Column(nullable = false)
private String lastName;
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
#Column(nullable = false)
private String address;
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
#Column
private String workPhone;
public String getWorkPhone() { return workPhone; }
public void setWorkPhone(String workPhone) { this.workPhone = workPhone; }
#Column
private String homePhone;
public String getHomePhone() { return homePhone; }
public void setHomePhone(String homePhone) { this.homePhone = homePhone; }
#Override
public void getDetails() {
}
}
Also, I have data.sql file that inserts 1 value into that table:
INSERT INTO person_client VALUES (1, 'firstName', 'lastName', 'paper street', '+123123', '+321321')
So, the problem is that it looks like this:
Why? And how can I fix that?
Always specify the target columns in INSERT statements:
INSERT INTO person_client
(id, first_name, last_name, address, home_phone, work_phone)
VALUES
(1, 'firstName', 'lastName', 'paper street', '+123123', '+321321')
If you don't specify the target columns, the values are matched by position and apparently the columns are created in a different order than you think they are.
agree with #a_horse_with_no_name, if you not specify column names it will insert based on the position/index. And all your java variables are in string that is the reason it does't throw any classcast exception.

Pass a list of string to a declared class file

Hi All below is my Employeeinformation class file java. I have to pass the values to it through java code
I am fine passing the strings but i am unable to pass list of technologies and list of strings.
Technologies.java
package com.ElasticSearchCrud.ElasticSearchCrud;
import lombok.Data;
#Data
public class Technologies {
private String name;
private String yearsOfExperience;
}
Employeeinformation.java
package com.ElasticSearchCrud.ElasticSearchCrud;
import lombok.Data;
import java.util.List;
#Data
public class EmployeeInformation {
private String id;
private String firstName;
private String lastName;
private List<Technologies> technologies;
private List<String> emails;
public EmployeeInformation(String id, String firstName, String lastName, List<Technologies> technologies, List<String> emails) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.technologies = technologies;
this.emails = emails;
}
public String getId() {
return id;
}
public void setId(String 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 List<Technologies> getTechnologies() {
return technologies;
}
public void setTechnologies(List<Technologies> technologies) {
this.technologies = technologies;
}
public List<String> getEmails() {
return emails;
}
public void setEmails(List<String> emails) {
this.emails = emails;
}
}
Passing a value to class file
EmployeeInformation EmployeePost = new EmployeeInformation("3", "Vignesh", "Murali","?","?");
How to pass the list of technologies and list of string in above code. Could some one help me tho achieve this?
List<Technologies> technologies = new ArrayList<>();
technologies.add(new Technologies("name1", "1999"));
technologies.add(new Technologies("name2", "1999"));
List<String> emails = new ArrayList<>();
strs.add("one");
strs.add("two");
EmployeeInformation EmployeePost = new EmployeeInformation("3", "Vignesh", "Murali",technologies,emails);
Also add #AllArgsConstructor to Technologies class. Or use setters to init Technologies objects:
#Data
#AllArgsConstructor
public class Technologies {
private String name;
private String yearsOfExperience;
}
#Data annotation has inner #RequiredArgsConstructor. This constructor is created with all non-initialized FINAL properties.
If you have not final properties there will be empty constructor.
So you have 3 ways:
Set you fields as final: new SomeObject(List.of("1","2"));
Add #AllArgsConstuctor: result the same
Leave as it is and initialize an object by set methods
SomeObject obj = new SomeObject();
obj.setList(List.of("1", "2"));

How to update one field in my Entity using JPA Repository

I have Entity with 3 fields: id, lastname and phoneNumber. I want to create method which works for update all fields or only one or two.
I use Hibernate and JPA Repository.
When I try to update all fields everything works well but when for example i want to update only lastname without changing of phoneNumber I have in output null insted of old phoneNumber.
Here is my method from Controller:
#PutMapping("/students/update/{id}")
public String updateStudentById(#ModelAttribute Student student, #ModelAttribute StudentDetails studentDetails,
String lastname, String phoneNumber,
#PathVariable Long id) {
Optional<Student> resultOptional = studentRepository.findById(id);
//Student result =resultOptional.get();
resultOptional.ifPresent((Student result) -> {
result.getStudentDetails().setPhoneNumber(studentDetails.getPhoneNumber()); result.getStudentDetails().setLastname(studentDetails.getLastname());
studentRepository.save(result);
});
return "Student updated";
}
The class for update:
#DynamicUpdate
#Entity
public class StudentDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name="lastname")
private String lastname;
#Column(name="phone_number")
private String phoneNumber;
public StudentDetails() {
}
public StudentDetails(Long id, String lastname, String phoneNumber) {
this.id = id;
this.lastname = lastname;
this.phoneNumber = phoneNumber;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
The class which has relation with StudentDetails:
#Entity
#Table(name = "student")
#DynamicUpdate
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
//#OneToMany(mappedBy = "student")
#ManyToMany
#JoinTable(name="course_student",joinColumns = #JoinColumn(name="student_id"),
inverseJoinColumns = #JoinColumn(name="course_id"))
private List<Courses> courses;
#OneToOne(cascade = CascadeType.ALL)
// #JoinColumn(name="studen/_details_id") // with this we have dobule student_details column
private StudentDetails studentDetails;
public List<Courses> getCourses() {
return courses;
}
public void setCourses(List<Courses> courses) {
this.courses = courses;
}
public StudentDetails getStudentDetails() {
return studentDetails;
}
public void setStudentDetails(StudentDetails studentDetails) {
this.studentDetails = studentDetails;
}
// Methods for StudentViewController
public String getLastname(){
return studentDetails.getLastname();
}
public String getPhoneNumber(){
return studentDetails.getPhoneNumber();
}
public Student() {
}
public Student(String name, String email, StudentDetails studentDetails) {
// this.id = id;
this.name = name;
this.email = email;
this.studentDetails = studentDetails;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
}
I was looking for solution and I added #DynamicUpdate but still it doesn't work.
Your code works properly. When you only provide lastName parameter in your request, then the phoneNumber parameter will be mapped to null so you override the phoneNumer property in your entity with this null value.
Change the code in the following way:
resultOptional.ifPresent((Student result) -> {
if(studentDetails.getPhoneNumber()!=null) {
result.getStudentDetails().setPhoneNumber(studentDetails.getPhoneNumber());
}
if(studentDetails.getLastname()!=null) {
result.getStudentDetails().setLastname(studentDetails.getLastname());
}
studentRepository.save(result);
});
Unfortunately it raises an other problem: How will you delete these fields? (How can you set them explicitly to null? )
A possible solution if you check for the "" (empty string) and set the property to null if the parameter is empty string.
It will be a quite messy code anyway...
You should consider using the Spring Data Rest package. It automatically creates all of the standard REST endpoints for your entities and handles all of these PUT/PATCH/POST/DELETE issues out of the box.
why don't you just set the params of your request in you setters?
resultOptional.ifPresent((Student result) -> {
result.getStudentDetails().setPhoneNumber(phoneNumber);
result.getStudentDetails().setLastname(lastname);
studentRepository.save(result);
});
You forget set #OneToOne mapping in StudentDetails - StudentDetails also need field of type Student which will be annotated #OneToOne.
Also you have to ensure, that all of entity fields will be filled - read more about fetch types.

Hibernate nulls in DB with #Embedded

hello im learning Hibernate, currently I'm trying to use #Embedded annotation, but i got nulls from #Embeddable object in my DB.
the code is as follows:
#Entity
public class Employee {
#Id
#GeneratedValue
private int id;
private String firstName;
private String lastName;
private double salary;
#Embedded
private Adress adress;
public Adress getAdress() {
return adress;
}
public void setAdress(Adress adress) {
this.adress = adress;
}
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 double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
So that is my Employee class which hold, #embedded field from Adress.class
Here comes Adress class:
#Embeddable
public class Adress {
private String locality;
private String streetNumber;
private String zipCode;
public String getLocality() {
return locality;
}
public void setLocality(String locality) {
this.locality = locality;
}
public String getStreetNumber() {
return streetNumber;
}
public void setStreetNumber(String streetNumber) {
this.streetNumber = streetNumber;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
}
and thats my main class:
public class Main {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myDatabase");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Employee employee = new Employee();
Adress adress = new Adress();
adress.setLocality("New York");
adress.setZipCode("55-5555");
adress.setStreetNumber("55");
employee.setFirstName("Andy");
employee.setLastName("Cole");
employee.setSalary(3333);
entityManager.getTransaction().begin();
entityManager.persist(employee);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
So fields related to class Employee go to the database without problem, but fields related to class Adress are set to null. I'd like to have them as setValues. Thanks in advance to all.
You're missing setAddress call
public class Test {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myDatabase");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Employee employee = new Employee();
Adress adress = new Adress();
adress.setLocality("New York");
adress.setZipCode("55-5555");
adress.setStreetNumber("55");
employee.setFirstName("Andy");
employee.setLastName("Cole");
employee.setSalary(3333);
employee.setAdress(adress);
entityManager.getTransaction().begin();
entityManager.persist(employee);
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
You need to set your created Adress object in your employee before persisting the employee, as in your current implementation your employee is not aware of his adress.
employee.setAdress(adress);

JSP Iterate over a user-defined class that inherits

I have two entity classes that represent two tables in my database.
The two tables are User and Student. The Student class(userID, studentID, classID) inherits from the User class(id, firstName, lastName, email).
When I query the database for students, I have a List returned. I then want to use that list to iterate over and display the firstName,lastName,email,and classID for each student. However, it only displays the classID. I believe this is because the object is of a Student that only contains three fields (userID, studentID, classID) and doesn't doesn't contain the names and email. However, because the Student class extends the User class, I thought it should still be able to get the other fields.
Here are my classes
User
public class User {
private int id;
private String firstName;
private String lastName;
private String email;
public User(){
}
public String getFullName(){
return firstName +" "+ lastName;
}
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;
}
}
Student
public class Student extends User {
private int userID;
private int studentID
private int classID
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
public int getStudentID() {
return studentID;
}
public void setStudentID(int studentID) {
this.studentID = studentID;
}
public int getClassID() {
return classID;
}
public void setClassID(int classID) {
this.classID = classID;
}
}
JSP
<c:forEach items="${students}" var="student">
<tr>
<td>${student.firstName} ${student.lastName}</td>
<td>${student.email}</td>
<td>${student.classID}</td>
</tr>
</c:forEach>
In my controller class
List<Student> students = getStudents();
output.addObject("students", students);
How can I get it to display, user.firstName, user.lastName, user.email, student.classID
The JSP code seems fine.
If the values are not available in the Student object and should be because of the hierarchy, the problem lies in the code that populates the Student objects after the query is done. You might want to validate how a Student object is created and why the fields which belong to the User object are not set.

Categories