Pages

Sunday 2 June 2013

 One To One Mapping in Hibernate

Using hibernate, if we want to put relationship between two entities means two Pojo classes, then in the database tables, there must exist foreign key relationship, we call it as Referential integrity.

there are many ways to do the mapping in Hibernate. lets see one of such way "one to one ".

we have 2 entities here 1)Author 2)AuthorContactDetails

we need to establish one to one relationship between these 2 entities now. means one author ms have one contact details .

in DB we will have 2 separate tables one for author and other one for author contact details.

in java also we will have 2 separate classes for each of the above tables.

then how can we give the associations between these 2 tables.  lets do it using hibernate annotation.

1)Author class
package com.kb.model;

import javax.persistence.Entity;

@Entity
public class Author {
 @Id
 @GeneratedValue
 private int authodNo;
 private String name;
 private String aboutAuthor;
 @OneToOne
 @JoinColumn(name="Author_Contact_Id")
 private AuthorContactDetails contactDetails;

 public int getAuthodNo() {
  return authodNo;
 }

 public void setAuthodNo(int authodNo) {
  this.authodNo = authodNo;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getAboutAuthor() {
  return aboutAuthor;
 }

 public void setAboutAuthor(String aboutAuthor) {
  this.aboutAuthor = aboutAuthor;
 }

 public void setContactDetails(AuthorContactDetails contactDetails) {
  this.contactDetails = contactDetails;
 }

 public AuthorContactDetails getContactDetails() {
  return contactDetails;
 }

}
2)AuthorContactDetails class
package com.kb.model;

import javax.persistence.Entity;

@Entity
public class AuthorContactDetails {
@Id
@GeneratedValue
private int id;
private String email;
private String mobile;
public int getId() {
 return id;
}
public void setId(int id) {
 this.id = id;
}
public String getEmail() {
 return email;
}
public void setEmail(String email) {
 this.email = email;
}
public String getMobile() {
 return mobile;
}
public void setMobile(String mobile) {
 this.mobile = mobile;
}
}

look at the Author class very closely, we can find the association between them.
we have used @onetoone annotation to indicate hibernate that this class has one dependent table in the DB.
and please do the mapping(take primary key of that contact table and put in the author table as a foreign key)
so now mapping is done between these 2 tables. whenever we persist the author object it expects contact details to be persisted in the DB.
so persist contact details  and author and leave the mapping for hibernate, then we can see one column which is used as a mapping between 2 tables.

see below program for the same




package com.kb.dao;

import org.hibernate.Session;

public class OneToOne {

 public static void main(String[] args) {
  SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
  Session session = sessionFactory.openSession();
  Author author = new Author();
  author.setName("kb");
  author.setAboutAuthor("good one");
  
  AuthorContactDetails contactDetails = new AuthorContactDetails();
  contactDetails.setEmail("abc@abcd.com");
  contactDetails.setMobile("1234567891");
  
  author.setContactDetails(contactDetails);
  
  try {
   session.beginTransaction();
   session.save(author);
   session.save(contactDetails);
   session.getTransaction().commit();
  } catch (Exception e) {
  session.getTransaction().rollback();
  }
  finally{
   session.close();
  }
  
  session=sessionFactory.openSession();
  author = (Author)session.load(Author.class, 1);

  System.out.println("name of the author is "+author.getName());
 }

}
now run the above program we will get the below output

name of the author is kb

Saturday 1 June 2013

Serialization and externalization in java

Serialization is the process of writing an object state into the file.
state of an object means atrributes and its values and in future if we need that object we can rebuild it from the file and  we call that process as "de serialization"
so to achive serialization in java,  any class must implement one marker interface.
that marker interface is "serializable".
lets understand this process through below example
package com.kb.model;

import java.io.Serializable;

public class Employee implements Serializable{

 private String name;
 private int age;
 private String designation;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getDesignation() {
  return designation;
 }
 public void setDesignation(String designation) {
  this.designation = designation;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
}

package com.kb.client;

import java.io.File;

public class Serialize {

 public static void main(String[] args) {
  Employee emp = new Employee();
  emp.setAge(25);
  emp.setDesignation("se");
  emp.setName("kb");
  File file = new File("employee.ser");
  FileOutputStream fout = null;
  ObjectOutputStream oout = null;
  try {
   fout = new FileOutputStream(file);
   oout = new ObjectOutputStream(fout);
   oout.writeObject(emp);
  } catch (IOException e) {
  } catch (Exception e) {

  }

  finally {
   if (oout != null) {
    try {
     oout.flush();
     oout.close();
     oout = null;
    } catch (IOException e) {
     e.printStackTrace();
    }
    if (fout != null) {
     try {
      fout.close();
      fout = null;
     } catch (IOException e) {
      e.printStackTrace();
     }

    }
   }
  }
 }

}


when we execute the above program, one file gets created in our project names as "employee.ser". this file contains the information about the employee object which we have written into this file.
this process is called serialization.

Now lets see de-serialization.
its just reading a serialized object from the file into the object back.
means retaining the object state.
lets do it as below
package com.kb.client;

import java.io.File;

public class DeSerialize {

 public static void main(String[] args) {
  File file = new File("employee.ser");

  FileInputStream fin = null;
  ObjectInputStream oin = null;

  try {
   fin = new FileInputStream(file);
   oin = new ObjectInputStream(fin);
   Employee emp = (Employee) oin.readObject();
   System.out.println(emp.getAge());
   System.out.println(emp.getDesignation());
   System.out.println(emp.getName());
  } catch (Exception e) {
   // TODO: handle exception
  }

  finally {
   if (oin != null) {
    try {
     oin.close();
     oin = null;
    } catch (IOException e) {
     e.printStackTrace();
    }
    ;

   }

   if (fin != null) {
    try {
     fin.close();
     fin = null;
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  }

 }

}

now run the above program and see the below output


25
se
kb

Remember in serialization
1)If we dont want to save any of the attribute from the serializable class then we can make such attributes as "transient".
2)all static fields can not be serializable sine its a class attribute not a object attribute.

in the above example if we dont want to save attribute designation then make it as transient as below
transient String designation;
then run both the program, in the output we can see "null " for that designation in the de-serializable program output.

now what if the employee class has address class reference and if address class is not serialized then while serializing employee object we will get an exception

scenario explained above through program is as below
address class - not implemented serializable interface.

package com.kb.model;

public class Address {
 private String street;
 private String location;
 public String getStreet() {
  return street;
 }
 public void setStreet(String street) {
  this.street = street;
 }
 public String getLocation() {
  return location;
 }
 public void setLocation(String location) {
  this.location = location;
 }

}
now consider below employee class
package com.kb.model;

import java.io.Serializable;

public class Employee implements Serializable{

 private String name;
 private int age;
 private transient String designation;
 private Address address;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getDesignation() {
  return designation;
 }
 public void setDesignation(String designation) {
  this.designation = designation;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public Address getAddress() {
  return address;
 }
 public void setAddress(Address address) {
  this.address = address;
 }
}
now see the below client program to serialize
package com.kb.client;

import java.io.File;

public class Serialize {

 public static void main(String[] args) {
  
  
  Employee emp = new Employee();
  emp.setAge(25);
  emp.setDesignation("se");
  emp.setName("kb");
  Address address = new Address();
  address.setLocation("bang");
  address.setStreet("rajajinagar");
  emp.setAddress(address);
  File file = new File("employee.ser");
  FileOutputStream fout = null;
  ObjectOutputStream oout = null;
  try {
   fout = new FileOutputStream(file);
   oout = new ObjectOutputStream(fout);
   oout.writeObject(emp);
   System.out.println("done");
  } catch (IOException e) {
  } catch (Exception e) {

  }

  finally {
   if (oout != null) {
    try {
     oout.flush();
     oout.close();
     oout = null;
    } catch (IOException e) {
     e.printStackTrace();
    }
    if (fout != null) {
     try {
      fout.close();
      fout = null;
     } catch (IOException e) {
      e.printStackTrace();
     }

    }
   }
  }
 }

}
run this , we will end up with an exception "not serializable exception"

so to serialize any object , if its clas is having any derived type reference like address then those derived types class must also be serialized first otherwise we will end with the above exception.

we will see about externalization and its flexibility and advantages over serialization in next post.

Thanks for reading