This tutorial is very important for hibernate, it provide Eager and
Lazy Fetch Types.
Sometimes you have two entities and there's a relationship between them.
For example, you might have an entity called UserDetails and another entity
called Address.
The UserDetails entity might have some basic properties such as id, name,
etc. as well as a property called listOfAddresses:
public class UserDetails {
private int userId;
private String name;
private Collection<Address>
listOfAddresses = new ArrayList<Address>();
// setters and getters
}
Now when you load a UserDetails from the database, JPA loads its id and
name fields for you. But you have two options for listOfAddresses: to load it together with the rest of the fields
(i.e. eagerly) or to load it on-demand (i.e. lazily) when you call the UserDetails.getListOfAddresses()
method.
When a UserDetails has many addresses it is not efficient to load all of
its addresses with it when they are not needed. So in such like cases, you can
declare that you want addresses to be loaded when they are actually needed.
This is called lazy loading.
Lazy
Initialization: Here you do not initialize entire object, you only
initialize the first level variables (i.e. only first level of member variable
of the object) then you only initialize the list only when you actually access
it. FetchType LAZY - fetch when needed.
Eager Initialization: when
loading an obj that has a collection, hibernate loads collection elements ONLY
when actually you ask for them; so this improves performance, among other
advantages. It should be used only when there is requirement else we need to
strict to only Lazy initialization. FetchType
EAGER fetch immediately.
*Hibernate provides proxy user
class at back end to fetch the data from database.
HibernateTest.java
package
org.yash.hibernate;
import
org.hibernate.Session;
import
org.hibernate.SessionFactory;
import
org.hibernate.cfg.Configuration;
import
org.yash.dto.Address;
import
org.yash.dto.UserDetails;
public class HibernateTest {
public static void main(String
args[]){
UserDetails
user = new UserDetails();
user.setUserName("First
User");
UserDetails
user2 = new UserDetails();
user2.setUserName("Second
User");
Address
addr1 = new Address();
addr1.setCity("Bentonville");
addr1.setPincode("72712");
addr1.setState("Ar");
addr1.setStreet("2301 SE
Saint Andrews");
Address
addr2 = new Address();
addr2.setCity("Rogers");
addr2.setPincode("72713");
addr2.setState("AR");
addr2.setStreet("2303 SE Saint
Andrews");
user.getListOfAddresses().add(addr1);
user.getListOfAddresses().add(addr2);
SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
Session
session = sessionFactory.openSession();
/* It is used
to save all the objects and to define single unit of work */
session.beginTransaction();
session.save(user);
//session.save(user2);
session.getTransaction().commit();
session.close();
user
= null;
session
= sessionFactory.openSession();
session.beginTransaction();
user = (UserDetails)
session.get(UserDetails.class, 1);
System.out.println("User name retrieved is "+user.getUserName());
//System.out.println(user.getListOfAddresses().size());
session.close();
/*
* There is a possibility to use list of
address after session close
* We need to add
@ElementCollection(fetch=FetchType.EAGER) in UserDetails calss
* */
System.out.println("Size: "+user.getListOfAddresses().size());
}
}
UserDetails.java
package org.yash.dto;
import
java.util.ArrayList;
import
java.util.Collection;
import
javax.persistence.ElementCollection;
import
javax.persistence.Entity;
import
javax.persistence.FetchType;
import
javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import
javax.persistence.Id;
import
javax.persistence.JoinTable;
import
javax.persistence.Table;
import
javax.persistence.JoinColumn;
@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
/* @Id says
"userId" is primary key */
@Id @GeneratedValue
(strategy=GenerationType.AUTO)
private int userId;
private String userName;
@ElementCollection(fetch=FetchType.EAGER)
@JoinTable(name="USER_ADDRESS",
joinColumns=@JoinColumn(name="USER_ID")
)
private
Collection<Address> listOfAddresses = new
ArrayList<Address>();
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String
getUserName() {
return userName;
}
public void
setUserName(String userName) {
this.userName = userName;
}
public void
setListOfAddresses(Collection<Address> listOfAddresses) {
this.listOfAddresses =
listOfAddresses;
}
public
Collection<Address> getListOfAddresses() {
return listOfAddresses;
}
}
Address.java
package org.yash.dto;
import
javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class Address {
@Column(name="STREET_NAME")
private String street;
@Column(name="CITY_NAME")
private String city;
@Column(name="STATE_NAME")
private String state;
@Column(name="PIN_CODE")
private String pincode;
public String
getStreet() {
return street;
}
public void
setStreet(String street) {
this.street = street;
}
public String
getCity() {
return city;
}
public void setCity(String
city) {
this.city = city;
}
public String
getState() {
return state;
}
public void setState(String
state) {
this.state = state;
}
public String
getPincode() {
return pincode;
}
public void
setPincode(String pincode) {
this.pincode = pincode;
}
}
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration
PUBLIC
"-//Hibernate/Hibernate Configuration DTD
3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">
org.postgresql.Driver
</property>
<property name="connection.url">
jdbc:postgresql://localhost:5433/hibernatedb
</property>
<property name="connection.username">postgres</property>
<property name="connection.password">admin</property>
<!-- JDBC connection pool (use the
built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.PostgreSQLDialect
</property>
<!-- Enable Hibernate's automatic
session context management -->
<property name="current_session_context_class">thread</property>
<!-- Echo all executed SQL to stdout
-->
<property name="show_sql">true</property>
<!-- Drop and re-create the
database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<!-- create / update -->
<!-- Names the annotated entity
class -->
<mapping class="org.yash.dto.UserDetails"/>
</session-factory>
</hibernate-configuration>
No comments:
Post a Comment