Proxy Object in Hibernate
1) Proxy User Class is a dynamic subset of Original User Class.
2) When session.get(User.class,1) is called, hibernate returns Proxy User class which pulls only ist level fields from DB . This is called lazy initialization as hibernate isn’t returning Addresses in this case.
3) When user.getListOfAddresses() is called, hibernate gives call to Hibernate and fetches all the addresses.
UserDetailsDTO.java
@Entity
@Table(name="USER_DETAILS")
public class UserDetailsDTO implements java.io.Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name="USER_NAME")
private String userName;
@ElementCollection(fetch=FetchType.EAGER) // Collection in hibernate
@JoinTable(name="USER_ADDRESS",joinColumns=@JoinColumn(name="USER_ID"))
//To change the default TN UserDetailsDTO_listOfAddresses to USER_ADDRESS
@GenericGenerator(name="hilo-gen",strategy="hilo")
// To make an explicit Generator for Address_Id(Primary Key)
@CollectionId(columns={@Column(name="ADDRESS_ID")},generator="hilo- gen",
type= @Type(type="long"))*/
// GenericGenerator and CollectionId is hibernate specific annotations.
// ADDRESS_ID is a primary key in USER_ADDRESS table
private Collection<Address> listOfAddresses= new ArrayList<>();
// Changing from Set to ArrayList(Index) to add Primary Key in Address Table
public Collection<Address> getListOfAddresses() {
return listOfAddresses;
}
public void setListOfAddresses(Collection<Address> listOfAddresses) {
this.listOfAddresses = listOfAddresses;
}
/*private Set<Address> listOfAddresses = new HashSet<Address>();
public Set<Address> getListOfAddresses() {
return listOfAddresses;
}
public void setListOfAddresses(Set<Address> listOfAddresses) {
this.listOfAddresses = listOfAddresses;
}*/
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;
}
}
Address.java
@Embeddable
@Table(name = "ADDRESS")
// It must be Table and not Entity
public class Address {
@Column(name = "STREET")
private String street;
@Column(name = "BUILDING")
private String building;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getBuilding() {
return building;
}
public void setBuilding(String building) {
this.building = building;
}
}
HibernateTest.java
public class HibernateTest {
public static void main(String[] args) {
UserDetailsDTO user =new UserDetailsDTO();
user.setUserName("Paras");
Address addr1 = new Address();
addr1.setBuilding("722/18 Shastri Nagar, ROhtak");
addr1.setStreet("Street number 5");
Address addr2 = new Address();
addr2.setBuilding("Kamla Nagar, New Delhi");
addr2.setStreet("Street number 6");
user.getListOfAddresses().add(addr1);
user.getListOfAddresses().add(addr2);
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
System.out.println("WOrking till now");
user=null;
session = sessionFactory.openSession();
user=(UserDetailsDTO) session.get(UserDetailsDTO.class,1);
System.out.println(user.getUserName()+" " + user.getUserId());
session.close();
/*Below method isn't called if fetch is Lazy, it will give Exception as session is closed and hibernate won't be able to make call to DB
For user.getListOfAddresses(), a call to DB is required and thus session should be open if fetch is lazy(by default)*/
For user.getListOfAddresses(), a call to DB is required and thus session should be open if fetch is lazy(by default)*/
System.out.println("Session CLosed");
/* Below will start working even if session is closed when fetch is set to be EAGER
*/
*/
System.out.println(user.getListOfAddresses().size());
}
}
Output :
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into USER_DETAILS (USER_NAME, userId) values (?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, BUILDING, STREET) values (?, ?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, BUILDING, STREET) values (?, ?, ?)
WOrking till now
Hibernate: select userdetail0_.userId as userId0_0_, userdetail0_.USER_NAME as USER2_0_0_, listofaddr1_.USER_ID as USER1_0_2_, listofaddr1_.BUILDING as BUILDING2_, listofaddr1_.STREET as STREET2_ from USER_DETAILS userdetail0_ left outer join USER_ADDRESS listofaddr1_ on userdetail0_.userId=listofaddr1_.USER_ID where userdetail0_.userId=?
Paras 1
Session CLosed
2
Output :
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into USER_DETAILS (USER_NAME, userId) values (?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, BUILDING, STREET) values (?, ?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, BUILDING, STREET) values (?, ?, ?)
WOrking till now
Hibernate: select userdetail0_.userId as userId0_0_, userdetail0_.USER_NAME as USER2_0_0_, listofaddr1_.USER_ID as USER1_0_2_, listofaddr1_.BUILDING as BUILDING2_, listofaddr1_.STREET as STREET2_ from USER_DETAILS userdetail0_ left outer join USER_ADDRESS listofaddr1_ on userdetail0_.userId=listofaddr1_.USER_ID where userdetail0_.userId=?
Paras 1
Session CLosed
2
No comments:
Post a Comment