Introduction - JPA/Hibernate
In this article, Java Development Company experts are explaining JPA/Hibernate use and the way to retrieve/fetch tables from database. You can read this post and try using the guidelines shared by professionals for results.
Hibernate is an Object Relational Mapping(ORM) framework that is to map the Java objects with database entities in-order to communicate with database from java efficiently.
e.g.
Table : EMS_TR_EMPLOYEE E_ID Number E_NAME Varchar2 E_SALARY Number |
@Entity @Table(name=”EMS_TR_EMPLOYEE”) class Employee { @Id @Column(name=”E_ID”) private Long id; @Column(name=”E_NAME”) private String name; @Column(name=”E_SALARY”) private Double salary; //setters and getters } |
EntityManagerFactory factory = Persistence.createEntiyManagerFaactory(“EmpManagementSystem”); Entitymanagerem = factory.createEntityManager(); Employee e = new Employee(); e.setId(1); e.setName(“xxxxx”); e.salary(64504.65); em.save(e); //insert a new row into that table EMS_TR_EMPLOYEE
Employee e = em.find(Employee.class, 1); //returns an Employee
- The ORM framework actually simplifies the communication between database and Java and it avoids lot of boiler plat codes
- Provides cache implementation in-order to improve the performance
Note: JPA is a specification (Standard for all ORM frameworks). Hibernate is one of the JPA implementation provider.
EAGER & LAZY fetch
Mostly all the entities will have relation (parent child relationship) with other entities in a real application.
Relationships like,
- ADepartment having N number of Employees (One to Many) -Employees working in a Department (Many to One)
- A Project having N number of Employees – A Employee working in N number of Projects(Many to Many)
- A Student has an Address – An Address of a Student (One to One)
EAGER/LAZY fetch defines how to retrieve/fetch tables (with relation or without relation) from database.
e.g.
@Entity @Table(name=”EMS_TR_DEPARTMENT”) class Department { @Id @Column(name=”D_ID”) private Long id; @Column(name=”D_NAME”) private String name; @OneToMany(mappedBy=”department”, fetch=FetchType.EAGER) private List<Employee> employees; //setters and getters } |
@Entity @Table(name=”EMS_TR_EMPLOYEE”) class Employee { @Id @Column(name=”E_ID”) private Long id; @Column(name=”E_NAME”) private String name; @ManyToOne @JoinColumn(name=”E_D_ID”, referencedColumnName=”D_ID”) private Department department; //setters and getters } |
EntityManagerFactory factory = Persistence.createEntiyManagerFaactory(“EmpManagementSystem”); Entitymanagerem = factory.createEntityManager();
em.find(Department.class, 1);
EAGER
Loads immediately all together that the parent and its children i.e. A department and it corresponding employees.
LAZY
- Loads on demand i.e. lazily or when needed
- Default fetch type since hibernate 3
LAZY fetch actually uses proxy pattern to loads children on demand.
e.g. Proxy class of Department
class ProxyDepartment { getId(); getName(); getEmployees(); }
When fetching the department from the database actually it has retrieved from the proxy object of the Department class - only first level of the fields(i.e. id, name) are initializing with the associated values from the database.
Field - employees does not have any value.
When you call department.getEmployees(); - at that time only it fetches the employees.
Note that if the session is closed at that time of accessing department.getEmployees(); - it will throw LazyInitializationException
e.g.
class DepartmentDao {
public Department getDepartment(Long deptId) {
EntityManagerem = EntityManagerFactory.getEntityManager(); //initialized Department department = em.find(Department.class,deptId); em.close(); //session closed department.getEmployees(); // throws LazyInitializationException, cause the session closed } }
Note: The session has to live in order to access children on LAZY fetch!
Solution and Conclusion
The real problem is trying to access an object (list of employee)that is associated with the session is closed. Solutions are,
- Prevent the session not be closed before fetching children
class DepartmentDao {
public Department getDepartment(Long deptId) {
EntityManagerem = EntityManagerFactory.getEntityManager(); //initialized Department department = em.find(Department.class, deptId); department.getEmployees(); em.close(); //session closed } }
- Use EAGER fetch
- Use if children are need to be loaded immediately otherwise it decreases the performance since it loads all the children(consider if an object have more number of children in its sub-sequent level)
Java development company experts have just shared a post with entire java development community people to assist them in understanding the JPA/Hibernate use and the process to retrieve/fetch tables from database. If you still have doubts, ask experts today.