I am trying to fetch data from database using hibernate annotation but it is not working as my expected. I have a two table Employee and Department. the java code is as below :
Employee class
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeBO {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "EMPID")
private int empId;
@Column(name = "EMPNAME")
private String empName;
@Column(name = "SALARY")
private int empSalary;
@Column(name = "EMPADDRESS")
private String empAddress;
@Column(name = "EMPAGE")
private int empAge;
@Column(name = "DEPTID")
private Integer deptId;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="DEPTID", nullable = true, insertable = false, updatable = false)
private DepartmentBO departmentBO;
// getter and setter
}
Department class :
@Entity
@Table(name = "DEPARTMENT")
public class DepartmentBO {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "DEPTID")
private int deptid;
@Column(name = "DEPTNAME")
private String deptName;
// getter and setter.
}
spring-servlet.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<!--?xml version="1.0" encoding="UTF-8"?-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="com.web"></context:component-scan>
<context:property-placeholder location="file:D:/EasyProp/db.properties" ignore-unresolvable="false"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="basicDataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driver.classname}" />
<property name="url" value="${driver.url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<!-- <property name="initialSize" value="10"/> -->
<!-- <property name="maxActive" value="25"/> -->
<!-- <property name="maxIdle" value="25"/> -->
<!-- <aop:scoped-proxy/> -->
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
<!-- <bean id="dbUtil" class="com.web.utility.OnLoadStartUp" init-method="initialize">
<property name="dataSource" ref="basicDataSource" />
</bean> -->
<!-- <bean id="loadOnStartUp" class="com.web.utility.LoadOnStartUp">
<property name="baseService" ref="baseService"></property>
</bean> -->
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="basicDataSource" />
<property name="annotatedClasses">
<list>
<value>com.web.bo.EmployeeBO</value>
<value>com.web.bo.DepartmentBO</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hmb2ddl.auto">validate</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.jdbc.fetch_size">10</prop>
<prop key="hibernate.jdbc.batch_size">25</prop>
<prop key="hibernate.jdbc.batch_versioned_data">true</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.default_batch_fetch_size">8</prop>
<prop key="hibernate.order_updates">true</prop>
<prop key="hibernate.connection.release_mode">on_close</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
<prop key="hibernate.bytecode.provider">javassist</prop>
</props>
</property>
</bean>
</beans>
when i trying to fetch all data from employee and department table but it only returns the data from employee table my code for hit hql query as below :
List<EmployeeBO> empList = null;
empList = sessionFactory.getCurrentSession().createQuery("From "+employeeBO.getClass().getName()).list();
above query is hit as below on database.
select employeebo0_.EMPID as EMPID0_, employeebo0_.DEPTID as DEPTID0_, employeebo0_.EMPADDRESS as EMPADDRESS0_, employeebo0_.EMPAGE as EMPAGE0_, employeebo0_.EMPNAME as EMPNAME0_, employeebo0_.SALARY as SALARY0_ from EMPLOYEE employeebo0_
But i want all data of the employee table and department table using Eager fetching.
I think you have missed the anotation for lazy loading.
You have to use (fetch=FetchType.LAZY) on a association which you want to lazy load
It works as expected. The EmployeeBO contains a DepartmentBO. The DepartmentBO will automatically be filled the moment you access it.
This is not true, if the Hibernate session containing the EmployeeBO has ended. Then the EmployeeBO is transient and hibernate will not fetch the missing object.
To enforce filling the DepartmentBO, you can add a
fetch
clause to your hql code. But that is not lazy fetching any more.The HQL
should do the job (replace the EmployeeBO with the actual entity name).
See here in the hibernate docs: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html and for the fetching strategies here https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-fetching
From the comments, you actually want eager fetching on the relationship, so you need to declare the fetchtype to be eager:
should fix it. Adding another doc here: https://docs.oracle.com/javaee/6/api/javax/persistence/ManyToOne.html
Hibernate by default has Lazy loading. i.e. it would not fetch the data of another table. In you case if you want the data of department table, you will have to call getter of departmentBO if you are in hibernate session. Note: it will fire another query. else you can also use
If you want by default to get the department data. use the following code
There are two ways to do this: 1) use EAGER fetch type 2) call getDepartmentBO() on each employee after you get the employee