Want to implement Search function in springboot restapi - spring-boot

So i have two entity classes Employee and Address and they are in #OneToOne Relation I'm able to search a Employee's with different parameter like name,designation,department. But i want to search a employee using address fields like Areaname,pincode, phone etc.. How to implement this functionality i'm currently using JpaRepo with Mysql.
#Entity
public class Employee{
#Id#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String Name;
private String Designation;
private String Department;
#OneToOne(cascade=CascadeType.ALL)
private Address address;}
#Entity
public class Address{
private String Streetname;
private String Areaname;
private String City;
private Long pincode;
#Id
private Long phone;
}

try like this:
#Query("FROM Employee AS emp LEFT JOIN emp.address AS adr WHERE adr.areaname= ?1")
public List<Employee > FindAllEmployeeByAreaName(String areaname);

Related

How to Inner Join using Spring Boot JPA / Hibernate in Repository?

I am currently learning spring boot , hibernate and Spring Boot JPA
I developing a Classroom App for coaching centers and institutes .
In it, students enrolled to multiple courses in a single institute
The Student Entity class :
#Entity
#Table(name = "student")
public class Student {
private String name;
private String dob;
private String gender;
private String address;
private String email;
private Integer mobile;
private String joined;
private Integer instID;
#Id
private String studentid;
getters and setters()....
}
Course Table Entity class
#Entity
#Table(name = "courses")
public class Course {
private String name;
private String description;
private String logo;
private String start;
private String end;
private Integer fee;
#Id
private String courseid;
private Integer instID;
getters and setters();
}
Enrolled Classes Table's Entity class
public class EnrolledCourses {
#Id
String enrollID;
String courseid;
String studentid;
Date joined;
getters and setters()...
}
JPA Repository
#Repository
public interface StudentRepository extends CrudRepository<Student, String> {
Student findTopByInstIDOrderByStudentidDesc(int instID);
}
#Repository
public interface CourseRepository extends CrudRepository<Course,String> {
}
#Repository
public interface EnrolledRepository extends CrudRepository<Course,String> {
}
My Need
Now I am retrieving enrolled students for a given course in a given institute... by using this MySQL query
SELECT
`enrolled_courses.enrollID`,
`student.name`, `student.studentid`
FROM `enrolled_courses`
INNER JOIN `student`
WHERE
`enrolled_courses.studentid` = `student.studentid`
AND
`student.instID` = 13
AND
`enrolled_courses.courseid` = '13I01C' ;
Now I need to implement this Inner join query in CourseRepository (or enrolledstudent repo)
How to achieve this ?
Please guide me
If we use hibernate mapping in EnrolledCourses entity like
#Entity
public class EnrolledCourses {
#Id
String enrolledId;
#ManyToOne
Student student;
#ManyToOne
Course course;
Date joined;
getters and setters()...
}
from the above mappings without using any SQL queries, you can retrieve all student who comes under a particular course
By using the method in the interface
#Repository
public interface EnrolledRepository extends CrudRepository<EnrolledCourses,String> {
List<EnrolledCourses> findByCourse_CourseId(String courseId);
}
if we have some relations between the entities we can easily retrieve all the fields using Jpa.

Project embedded document fields after lookup operation

I want to do a join between Timesheet:
#Data
#AllArgsConstructor
#NoArgsConstructor
#Document(collection = TIMESHEET_COLLECTION)
public class Timesheet {
#Id
private ObjectId id;
private ObjectId employeeId;
private LocalDate date;
private String occupationTitle;
private BigDecimal salary;
private List<TimesheetEntry> entries;
}
and Employee (as embedded document):
#Data
#AllArgsConstructor
#NoArgsConstructor
#Document(collection = Employee.EMPLOYEE_COL)
public class Employee {
#Id
private ObjectId id;
private String registry;
private String cpf;
private String firstName;
private String lastName;
private String nickname;
private String phone;
private LocalDate dateOfBirth;
private LocalDate admissionDate;
private EmployeeOccupation occupation;
private EmployeePaymentPreferences paymentPreferences;
private Map<String, String> equipmentPreferences;
private Boolean active;
}
So I have this aggregation query, with match, lookup, unwind and projection operations.
Aggregation aggregation = Aggregation.newAggregation(matchTimesheetFilter(timesheetFilter), lookupEmployee(), unwindEmployee(), projectEmployee());
There are lookup and unwind implementations. I'm unwinding because employee should be a single object, not an array.
private LookupOperation lookupEmployee(){
return LookupOperation.newLookup()
.from("employee")
.localField("employeeId")
.foreignField("_id")
.as("employee");
}
private UnwindOperation unwindEmployee(){
return Aggregation.unwind("employee");
}
It returns successfully a Timesheet document with a embedded Employee document. The point is: I don't want all data from employee. I only want a few fields.
So, I tried to exclude unwanted fields from employee, using my projection operation:
private ProjectionOperation projectEmployee() {
return Aggregation.project().andExclude("employee.nickname", "employee.firstName", "employee.fullName");
}
It didn't work. My embedded employee is still being returned with all fields. However I can successfully exclude fields from Timesheet, if I do something like this:
private ProjectionOperation projectEmployee() {
return Aggregation.project().andExclude("startDate", "endDate");
}
How can I project custom fields from a document embedded through a lookup operation?
i think you need to exclude "employee.nickname", "employee.firstName", "employee.fullName", instead of "nickname", "firstName", "fullName"
Try this:
private ProjectionOperation projectEmployee() {
return Aggregation.project().andExclude("employee.nickname", "employee.firstName", "employee.fullName");
}
i did it this way (not sure if it's right but it works):
private LookupOperation lookupEmployee(){
return LookupOperation.newLookup()
.from("employee")
.localField("employeeId")
.foreignField("_id")
.as("employeeLookup");
}
no unwind used
Aggregation.project().and("employeeLookup.firstName").as("employee.firstName")

Query child record from parent

I have 2 classes: Staff and State.
public class State {
#Id
private String id;
private String name;
}
public class Staff {
#Id
#Column(nullable = false, columnDefinition="VARCHAR(100)")
private String id;
private String name;
private String phoneNo;
private String address;
#OneToOne
#JoinColumn(name = "state_id")
private State state;
}
How to get query using JpaRepository to filter by State.name. Since it is mapped using state_id?
Something similar to this:
//current DAO to filter by staff's name
List<Staff> findByNameContaining(String name);
But I want to filter by name of Staff and by name of State.
try this.
List<Staff> findByNameAndState_Name(String staffName, String stateName)
You can do that as well. try to create a method as following. pass the state name.
List findByStateName(String stateName);

Spring Specification dynamic query join

I have two entity:
#Entity
public class User{
#Id
private String id;
...
private String username;
private String customerId;
}
public class Customer{
#Id
private String id;
private String name;
}
How can I create dynamic query just like:
select * from user where username='...';
select * from user u left join customer c o u.customerId=c.id where c.name='...';
and without #OneToOne?

Spring and Hibernate Error -- not-null property references a null or transient value: com.tharaka.model.Employee.designation

im new to Spring and hibernate, i got the error above when trying to persist the transaction data. please try to help this problem
Here's my Entity:
#Entity #NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e")
public class Employee implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String city;
private String civil;
#Temporal(TemporalType.DATE)
#Column(name="dob", length=11)
private Date dob;
private String email;
private int epf;
private String fname;
private String gender;
private int landtp;
private String lname;
#Temporal(TemporalType.DATE)
#Column(name="salaryincrement", length=11)
//bi-directional many-to-one association to Designation
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="designation_id", nullable=false)
private Designation designation;
public Employee() { }
#Entity
#NamedQuery(name="Designation.findAll", query="SELECT d FROM Designation d")
public class Designation implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String type;
//bi-directional many-to-one association to Employee
#OneToMany(mappedBy="designation")//, cascade=CascadeType.ALL
private List<Employee> employees;
public Designation() {
}
this is my Entity class,
Entities have a getters ans setters
designation is set nullable = false. However employees variable isn't initialized in Designation. So, you'll have to initialize as
#OneToMany(mappedBy="designation")//, cascade=CascadeType.ALL
private List<Employee> employees = new LinkedList<>();
I'm not sure that you can go with primitive type int as your Id - you should probably use Integer - because int has default zero value and cannot be null, your new record can be rather seen as a detached entity with Id ZERO and not as a transient one.
The same mistake is in Designation class.
See Primitive or wrapper for hibernate primary keys

Resources