I'm trying to see whether a Cab is assigned to any Employee so I can fetch that Employee Id and simply to set cab as null, but #OneToMany mapping, simply returning a list of Employees & by this I'm not getting any method like a cab.getEmp() to fetch employee details
Employee.java
#Data
#Entity
#Table(name = "employee")
public class Employee {
#Id
private Integer id;
private String username;
private String password;
private String role;
private String dropLocation;
#ManyToOne(
cascade = CascadeType.ALL,
fetch = FetchType.EAGER
)
#JoinColumn(
name = "empCab",
referencedColumnName = "cabId"
)
public Cab cab;
}
Cab.java
#Data
#Entity
#Table(name = "cab")
public class Cab {
#Id
private Integer cabId;
private Integer cabNumber;
private String cabShift;
#OneToMany(
cascade = CascadeType.ALL,
fetch = FetchType.EAGER,
mappedBy= "cab"
)
private List<Employee> emp = new ArrayList<>();
}
Controller
#GetMapping("deleteCab")
public ModelAndView deleteCab(#RequestParam("id") Integer id, ModelAndView mvc){
Cab cab = cabRepo.findById(id).orElse(null);
if(cab!=null){
List<Employee> emp = cab.getEmp();
if(!cab.getEmp().isEmpty()){
//e1.setCab(null);
//empRepo.save(e1);
mvc.addObject("msg", "Cab deleted & an employee cab detail also got changed");
mvc.setViewName(NOTHING_JSP);
} else {
cabRepo.deleteById(id);
mvc.addObject("msg", "Cab removed from the database");
mvc.setViewName(NOTHING_JSP);
}
}
}
In your code, Cab is perent class and Employee is child class and your goal is to remove the child class dependency with parent class. For that, You have to extract the Employee from Cab and remove the relationship with Cab using employee.setCab(null).
#GetMapping("/deleteCab")
#ResponseBody
public ModelAndView deleteCab(#RequestParam("id") Integer id, ModelAndView mvc){
Cab cab = cabRepo.findById(id).orElse(null);
if(cab != null){
// Extract employee from cab
for(Employee emp: cab.getEmp())
{
// Remove the relationship with cab
emp.setCab(null);
}
cabRepo.save(cab);
mvc.addObject("msg", "Cab deleted & an employee cab detail also got changed");
mvc.setViewName(NOTHING_JSP);
} else {
cabRepo.deleteById(id);
mvc.addObject("msg", "Cab removed from the database");
mvc.setViewName(NOTHING_JSP);
}
return mvc;
}
Related
I'm struggling with this problem. I have table "Cities" which has foreign key to table "Countries" with country_id referenced to country from which is city. In my web application I can list all the data from "Cities" table but I can't find a way to list name of country. This is my service class method.
public List<City> listAll() {
List<City> cities = repo.findAll();
return cities;
}
In "City" entity I have field Country by which I can find in method name of country but I don't know how to return it together with cities.
Addition:
#GetMapping("/cities")
public String getAllCities(Model model) {
List<City> listCities = service.listAll();
model.addAttribute("showListCities", listCities);
return "cities";
}
City.java:
package com.bookflight.BookFlight.gradovi;
import com.bookflight.BookFlight.drzave.Drzave;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "cities")
public class City {
#Id
#Column(name = "city_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(nullable = false, length = 45, name = "city_name")
private String city_name;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "cou_id", referencedColumnName = "cou_id")
private Country countries;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getcity_name() {
return city_name;
}
public void setcity_name(String city_name) {
this.city_name = city_name;
}
public Countries getCountries() {
return countries;
}
public void setCountries(Country countries) {
this.countries = countries;
}
}
NOTE: Every variable name here is in my native language so I literally translated it word by word to better understand your solution afterwards.
You have add FetchType to the #ManyToOne annotation arguments:
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "cou_id", referencedColumnName = "cou_id")
private Country countries;
and her a short description for each fetch type:
FetchType.LAZY will only fire for primary table. If in your code you call any other method that has a parent table dependency then it will fire query to get that table information.
FetchType.EAGER will create join of all table including relevant parent tables directly.
And you can add a method in your city Class to return your country name and this method will be available in your view-layer:
public String getCountryName(){
return countries == null ? null : countries.getName();
//not sure how the country class is implemented
}
I have a OneToMany relationship (two tables bi-directional).
When I save the doctor's specialties, it does work, but when I remove any specialty and update the doctor, it doesn't.
Doctor
#Entity
#Table(name = "doctors")
public class Doctor implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer doctorId;
#Column(length = 20)
private String doctorName;
#Column(length = 9)
private String doctorPhoneNo;
#Column(length = 30)
private String doctorEmailAddress;
private String doctorProfileImage;
#Enumerated(EnumType.STRING)
private Status status;
#Column(length = 6)
private String doctorCmp;
#OneToMany(mappedBy = "doctor", cascade = CascadeType.ALL)
// #JsonIgnore
private Set<DoctorSpecialties> doctorSpecialties;
public Doctor() {
this.doctorSpecialties = new HashSet<>();
}
public Doctor(Integer id){
this();
this.doctorId = id;
}
// getters y setters
}
Specialty
#Entity
#Table(name = "specialties")
public class Specialty implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer specialtyId;
private String specialtyName;
#OneToMany(mappedBy = "specialty")
#JsonIgnore
private Set<DoctorSpecialties> doctorSpecialties;
public Specialty() {
}
public Specialty(Integer id) {
this.specialtyId = id;
}
// getters and setters
}
DoctorSpecialties
#Entity
#Table(name = "doctor_specialties")
public class DoctorSpecialties implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "doctor_id")
private Doctor doctor;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "specialty_id")
private Specialty specialty;
#OneToMany
#JoinColumn(name = "doctor_specialties_id")
private Set<Appointment> appointments;
#OneToMany
#JoinColumn(name = "doctor_specialties_id")
private Set<DoctorSchedule> schedules;
public DoctorSpecialties(){
}
public DoctorSpecialties(Specialty specialty, Doctor doctor){
this.specialty = specialty;
this.doctor = doctor;
}
getters / setters
}
Controller
#PostMapping(value = "/saveSpecialties/{id}")
public String saveDoctorSpecialties(#RequestParam(required = false) String[] specialtiesId,
#PathVariable Integer id, RedirectAttributes message) {
if (id != null && id > 0) {
Doctor doctor = doctorService.findOne(id);
if (doctor != null) {
// It does not work
doctor.getDoctorSpecialties().forEach(ds -> doctorSpecialtiesService.delete(ds.getId()));
doctor.getDoctorSpecialties().clear();
if (specialtiesId != null) {
for (String specialtyId : specialtiesId) {
DoctorSpecialties ds = new DoctorSpecialties();
ds.setSpecialty(new Specialty(Integer.parseInt(specialtyId)));
ds.setDoctor(doctor);
doctor.getDoctorSpecialties()
.add(ds);
}
}
doctorService.update(doctor);
message.addFlashAttribute("success", "Specialties successfully saved.");
return "redirect:/doctors/profile/{id}/specialties";
}
}
// specialtiesId = new String[]{};
message.addFlashAttribute("error", "Doctor doesn't exists");
return "redirect:/doctors/list";
}
console:
2021-10-30 21:19:13.330 DEBUG 44504 --- [nio-8080-exec-7] org.hibernate.SQL : select doctor0_.doctor_id as doctor_i1_3_0_, doctor0_.doctor_cmp as doctor_c2_3_0_, doctor0_.doctor_email_address as doctor_e3_3_0_, doctor0_.doctor_name as doctor_n4_3_0_, doctor0_.doctor_phone_no as doctor_p5_3_0_, doctor0_.doctor_profile_image as doctor_p6_3_0_, doctor0_.status as status7_3_0_ from doctors doctor0_ where doctor0_.doctor_id=?
2021-10-30 21:19:13.339 DEBUG 44504 --- [nio-8080-exec-7] org.hibernate.SQL : select doctorspec0_.doctor_id as doctor_i2_2_0_, doctorspec0_.id as id1_2_0_, doctorspec0_.id as id1_2_1_, doctorspec0_.doctor_id as doctor_i2_2_1_, doctorspec0_.specialty_id as specialt3_2_1_ from doctor_specialties doctorspec0_ where doctorspec0_.doctor_id=?
2021-10-30 21:19:13.401 DEBUG 44504 --- [nio-8080-exec-8] org.hibernate.SQL : select doctor0_.doctor_id as doctor_i1_3_0_, doctor0_.doctor_cmp as doctor_c2_3_0_, doctor0_.doctor_email_address as doctor_e3_3_0_, doctor0_.doctor_name as doctor_n4_3_0_, doctor0_.doctor_phone_no as doctor_p5_3_0_, doctor0_.doctor_profile_image as doctor_p6_3_0_, doctor0_.status as status7_3_0_ from doctors doctor0_ where doctor0_.doctor_id=?
2021-10-30 21:19:13.404 DEBUG 44504 --- [nio-8080-exec-8] org.hibernate.SQL : select specialty0_.specialty_id as specialt1_7_0_, doctorspec1_.id as id1_2_1_, doctor2_.doctor_id as doctor_i1_3_2_, specialty0_.specialty_name as specialt2_7_0_, doctorspec1_.doctor_id as doctor_i2_2_1_, doctorspec1_.specialty_id as specialt3_2_1_, doctorspec1_.specialty_id as specialt3_2_0__, doctorspec1_.id as id1_2_0__, doctor2_.doctor_cmp as doctor_c2_3_2_, doctor2_.doctor_email_address as doctor_e3_3_2_, doctor2_.doctor_name as doctor_n4_3_2_, doctor2_.doctor_phone_no as doctor_p5_3_2_, doctor2_.doctor_profile_image as doctor_p6_3_2_, doctor2_.status as status7_3_2_ from specialties specialty0_ inner join doctor_specialties doctorspec1_ on specialty0_.specialty_id=doctorspec1_.specialty_id inner join doctors doctor2_ on doctorspec1_.doctor_id=doctor2_.doctor_id where doctor2_.doctor_id=?
2021-10-30 21:19:13.565 DEBUG 44504 --- [nio-8080-exec-4] org.hibernate.SQL : select specialty0_.specialty_id as specialt1_7_0_, doctorspec1_.id as id1_2_1_, doctor2_.doctor_id as doctor_i1_3_2_, specialty0_.specialty_name as specialt2_7_0_, doctorspec1_.doctor_id as doctor_i2_2_1_, doctorspec1_.specialty_id as specialt3_2_1_, doctorspec1_.specialty_id as specialt3_2_0__, doctorspec1_.id as id1_2_0__, doctor2_.doctor_cmp as doctor_c2_3_2_, doctor2_.doctor_email_address as doctor_e3_3_2_, doctor2_.doctor_name as doctor_n4_3_2_, doctor2_.doctor_phone_no as doctor_p5_3_2_, doctor2_.doctor_profile_image as doctor_p6_3_2_, doctor2_.status as status7_3_2_ from specialties specialty0_ inner join doctor_specialties doctorspec1_ on specialty0_.specialty_id=doctorspec1_.specialty_id inner join doctors doctor2_ on doctorspec1_.doctor_id=doctor2_.doctor_id where doctor2_.doctor_id=?
There is no delete statement...
------------------------
EDIT 1
------------------------
Doctor find = doctorRepository.findById(1).get();
DoctorSpecialties ds1 = new DoctorSpecialties();
ds1.setSpecialty(specialtyRepository.findById(1).get());
ds1.setDoctor(find);
DoctorSpecialties ds2 = new DoctorSpecialties();
ds2.setSpecialty(specialtyRepository.findById(2).get());
ds2.setDoctor(find);
find.getDoctorSpecialties().add(ds1);
find.getDoctorSpecialties().add(ds2);
doctorRepository.save(find);
I have done some tests and I can not understand completely. I did and it only saves once when actually I am adding two objects.
insert into doctor_specialties (id, doctor_id, specialty_id) values (null, ?, ?)
------------------------
EDIT 2
------------------------
DoctorSpecialties (Modify the constructor)
#Entity
#Table(name = "doctor_specialties")
public class DoctorSpecialties implements Serializable {
public DoctorSpecialties(Integer specialtyId, Doctor doctor) {
this.specialty = new Specialty(specialtyId);
this.doctor = doctor;
}
}
Controller
#PostMapping(value = "/saveSpecialties/{id}")
public String saveDoctorSpecialties(#RequestParam(required = false) String[] specialtiesId,
#PathVariable Integer id, RedirectAttributes message) {
if (id != null && id > 0) {
doctorService.saveDelete(id);
Doctor doctor = doctorService.findOne(id);
if (specialtiesId != null && specialtiesId.length > 0) {
for(String idSpecialty : specialtiesId){
doctorSpecialtiesService.save(new DoctorSpecialties(Integer.parseInt(idSpecialty), doctor));
}
}
message.addFlashAttribute("success", "Specialties successfully saved.");
return "redirect:/doctors/profile/{id}/specialties";
}
message.addFlashAttribute("error", "Doctor doesn't exists");
return "redirect:/doctors/list";
}
Service
#Override
#Transactional
public void saveDelete(Integer doctorId) {
Doctor doctor = this.doctorRepository
.findById(doctorId).get();
doctor.getDoctorSpecialties().clear();
}
Console:
select doctor0_.doctor_id as doctor_i1_3_0_, doctor0_.doctor_cmp as doctor_c2_3_0_, doctor0_.doctor_email_address as doctor_e3_3_0_, doctor0_.doctor_name as doctor_n4_3_0_, doctor0_.doctor_phone_no as doctor_p5_3_0_, doctor0_.doctor_profile_image as doctor_p6_3_0_, doctor0_.status as status7_3_0_ from doctors doctor0_ where doctor0_.doctor_id=?
select doctorspec0_.doctor_id as doctor_i2_2_0_, doctorspec0_.id as id1_2_0_, doctorspec0_.id as id1_2_1_, doctorspec0_.doctor_id as doctor_i2_2_1_, doctorspec0_.specialty_id as specialt3_2_1_ from doctor_specialties doctorspec0_ where doctorspec0_.doctor_id=?
update appointments set doctor_specialties_id=null where
doctor_specialties_id=?
update doctor_schedules set
doctor_specialties_id=null where doctor_specialties_id=?
delete from doctor_specialties where id=?
For the one-many relationship in a transaction, once you get the parent (Doctor) and loop over its children (DoctorSpecialties) [In other words, once you load entire the parent and its children into Persistent state], you won't be able to delete your DoctorSpecialties directly by its repository.
You could try something like the below example to see it:
#Transactional
public void removeLine(Long doctorId, Long specId) {
Doctor doctor = this.doctorRepository // (1)
.findById(doctorId)
.orElseThrow(IllegalArgumentException::new);
this.doctorSpecialtiesRepository.deleteById(specId); // (2)
}
At (1), we load doctor into the persistent state. So here, if fetch = FetchType.EAGER, this means that it will load doctor and its all doctorSpecialties into the persistent state and this cause (2) won't give you any effect.
Otherwise, if fetch = FetchType.LAZY, it only load doctor into the persistent state, and at (2) it will be deleted successfully.
Your case was similar, although fetch = FetchType.LAZY, but you looped over the children by using forEach and that loads doctorSpecialties into the persistent state. That's why you cannot delete them.
Suggestion: Using orphanRemoval = true in your parent entity
#OneToMany(mappedBy = "doctor", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<DoctorSpecialties> dss;
and just simply clear its children in your method (In #Transactional method)
doctor.getDoctorSpecialties().clear();
Whichever side has mappedBy is owning side.
This means something like: "modifications on this side of the relation
are already Mapped By the other side of the relation
, so no need to track it here separately in an extra
table."
Check this url for more information What is the "owning side" in an ORM mapping?
Let's say we have the following three domain model entities: Company, Departament, and Employee.
#Getter #Setter #NoArgsConstrutor
public class Employee {
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "department_id", nullable = false, insertable = false, updatable = false)
private Department department;
#JoinColumn(name = "department_id", nullable = false)
private int department_id;
}
#Getter #Setter #NoArgsConstrutor
public class Department {
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "company_id", nullable = false, insertable = false, updatable = false)
private Company company;
#JoinColumn(name = "company_id", nullable = false)
private int company_id;
#OneToMany(mappedBy = "department")
private List<Employee> employees;
}
#Getter #Setter #NoArgsConstrutor
private class Company {
private String name;
#OneToMany(mappedBy = "company")
private List<Department> departments;
}
For each entity, we have Repositories which extend JpaRepository, Services, and Controllers. In each Service we #Autowire the respective Repository, and in each entity Controller we call methods from the entity Service.
My issue is the following: I cannot save an entire Company, because the Departments require a Company ID, and Employees a Deparment ID. So, firstly, in my CompanyService I save and then clear the departments list, do a saveAndFlush which assigns an ID to my company. I assign the received ID to every company_id in each entity of the previously saved departments list, then attach the list back to the company and do another saveAndFlush, and I do this one more time for the employee list.
#RestController
public class CompanyController {
#Autowire
private CompanyService companyService;
#PostMapping("/companies")
public Company createCompany(#RequestBody Company newCompany) {
return companyService.createCompany(newCompany);
}
}
#Service
public class CompanyService {
#Autowire
private CompanyRepository companyRepository;
public Company createCompany(Company company) {
List<Department> departments = new ArrayList<>(company.getDepartments());
company.getDepartments().clear();
companyRepository.saveAndFlush(company);
int company_id = company.getId();
departments.forEach (department ->
department.setCompany_id(company_id);
);
//here I save a copy of the previously saved departments, because I still need the employees
company.getDepartments().addAll(departments.stream().map(department -> department.clone(department)).collect(Collectors.toList()));
company.getDepartments().forEach(department -> department.getEmployees().clear());
companyRepository.saveAndFlush(company);
//here I assign each employee it's corresponding department ID
for (int i = 0; i < company.getDepartments().size(); i++) {
Department departmentInSavedCompany = company.getDepartments().get(i);
Department departmentWhichStillHasEmployees = departments.get(i);
departmentWhichStillHasEmployees.setId(departmentInSavedCompany.getId());
departmentWhichStillHasEmployees.getEmployees().forEach(employee -> employee.setDepartment_id(departmentInSavedCompany.getId()));
}
company.getDepartments.clear();
company.getDepartments.addAll(departments);
return companyRepository.saveAndFlush(company);
}
}
#Repository
public interface CompanyRepository extends JpaRepository<Company, Integer> {
}
I currenty do not like this implementation neither do I find it good. Which is the correct approach for this situation?
When working with JPA, do not work with IDs, work with object references.
In your case, this means removing the id attributes that duplicate the references.
In order to obtain the proper entities for IDs use JpaRepository.getOne. It will return either the entity if it is already in the 1st level cache or a proxy just wrapping the id, so it won't hit the database.
This allows you to assemble your object graph and persist it in one pass starting with the entity having no references to other entities.
You might also consider configuring cascading, if you consider entities to be part of the same Aggregate, i.e. they should be loaded and persisted together.
I've 2 tables Employee & Vehicle, where one employee can have multiple vehicles.
Below is the mapping that I've defined:
Employee.java
#Entity(name = "emp_details")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int empId;
#OneToMany(cascade = CascadeType.ALL, mappedBy="employee")
private List<Vehicle> vehicles = new ArrayList<>();
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public List<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(List<Vehicle> vehicles) {
this.vehicles = vehicles;
}
}
Vehicle.java
#Entity
public class Vehicle {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int vehicleId;
#ManyToOne
#JoinColumn(name="empId")
private Employee employee;
private String name;
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public int getVehicleId() {
return vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Main class
public class HibernateTest {
public static void main(String[] args) {
Employee emp = new Employee();
Vehicle vehicle = new Vehicle();
vehicle.setName("Honda");
emp.getVehicles().add(vehicle);
SessionFactory sFactory = new Configuration().configure().buildSessionFactory();
Session session = sFactory.openSession();
session.beginTransaction();
session.save(emp);
session.getTransaction().commit();
session.close();
StandardServiceRegistryBuilder.destroy(sFactory.getSessionFactoryOptions().getServiceRegistry());
}
}
But when I execute this, Vehicle.employee_id is empty. I was expecting that my foreign key will be inserted there.
What am I missing?
Thank You
You need to show us the code that persists your entities, but my guess is that you are not setting the employee to the vehicle.
You need to manage both sides of bidirectional entity relationship. Your code should look something like this
employee.getVehicles().add(vehicle);
vehicle.setEmployee(employee);
session.save(employee);
UPDATE:
In this case, Vehicle is the owning side of the relation because the foreign key is in its database table. You just added the new vehicle to the employee's list of vehicles. When you save the employee, there's nothing to change in Employees database, and the save operation cascades to Vehicle. Vehicle does not have its employee set, it is null, so it puts null in empId column
Bottom line, you have to make sure both sides of bidirectional relationship are wired up correctly.
If you have a bidirectional relationship you have to
set the relation on both sides.
That means you have to set the employee for your vehicle also.
You can do this by calling
vehicle.setEmployee(emp);
and then store or update your entity (if it's not attached to session already).
Usually to set a bidirectional relationship you provide special methods in your entities.
public class Vehicle {
...
public void setEmployee(Employee employee) {
this.employee = employee;
employee.addVehicle(this)
}
...
}
public class Employee {
...
public void addVehicle(Vehicle v) {
if(!vehicles.contains(v)) {
vehicles.add(v);
}
if(!this.equals(v.getEmployee()) {
v.setEmployee(this);
}
}
...
}
In your Employee entity class, you haven't used #Column annotation on empId. In Vehicle class you are referencing Employee using #JoinColumn(name="employee_id"),so column employee_id must exist in emp_details table. So you need to modify your Employee class to something with
#Id
#GeneratedValue
#Column(name="employee_id")
private int empId;
I think need to edit your code. you miss the entity jpa rule. you can some search jpa entity. you read description for you. link : enter link description here
(Modified your Employee.java)
#Entity(name = "employee")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int idx;
#OneToMany(cascade = {CascadeType.ALL}, mappedBy = "employee")
private List<Vehicle> vehicle = new ArrayList<>();
...
}
(Modified your Vehicle.java)
#Entity
public class Vehicle {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int idx;
#ManyToOne
#JoinColumn(name="employee_id")
private Employee employee;
...
}
You only need to cascade onetoMany from Employee Entity
I have three classes which are country,state and suburb. Each country has many states and each state has many suburbs.
My hibernate is 4.2.1.Final.
The problem is that although FetchType of states is defined EAGER, I cant retrieve suburbs of each state.
I read this answer as well. As I do not want to retrieve all the states ad suburbs any time I am retrieving the countries. So I suppose need to override the fetching strategy using criteria rather than using
#LazyCollection(LazyCollectionOption.FALSE)
Country
#Entity
public class Country {
private List<States> states;
...
public Country(){
this.states = new ArrayList();
}
#OneToMany (cascade = CascadeType.ALL)
public List<States> getStates() {
return states;
}
....
}
States
#Entity
public class States {
private long id;
private String name;
private List<Suburbs> suburbs;
...
public States(){
this.suburbs = new ArrayList();
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public List<Suburbs> getSuburbs() {
return suburbs;
}
}
Suburbs
#Entity
public class Suburbs {
private long id;
private String name;
....
}
Code
Criteria criteria = session.createCriteria(Country.class, "country")
.createAlias("country.states", "states");
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("states.id").as("id"));
pl.add(Projections.property("states.name").as("name"));
criteria.setProjection(pl);
criteria.setResultTransformer(new
AliasToBeanResultTransformer(States.class));
criteria.add(Restrictions.eq("country.id", id));
List<States> statesList = new ArrayList();
statesList = (List<States>) criteria.list();
System.out.println(">>>"
+ statesList.get(0).getSuburbs().size());
>>>>> returns Zero
Inspired by this and link
User user = (User) session.createCriteria(User.class)
.setFetchMode("permissions", FetchMode.JOIN)
.add( Restrictions.idEq(userId) )
.uniqueResult();