Pages Navigation Menu

Coding is much easier than you think

Configuring & Adding Primary Key to Collections in Hibernate

Posted by in Hibernate, Hibernate Annotation


 
In previous article we learnt on how to persist a collection of objects of an entity class in a separate table using hibernate. And below are the following two tables are created in the database.
 

 
1. STUDENT for Student entity type object
2. Student_lisOfAddress for Address value type object (The default table name for this table gets generated based on – Entity class name_Name of the embeddable object in the entity class).
Here ‘Student_ID’ column in Student_lisOfAddress is the foreign key reference of Student tables ‘ID’. In next article we shall learn to override the default collection class table name and to add primary key to it.
 
In this post we shall learn on how to change this default table name and foreign key name of collection table and how to add primary key to this table to identify each record separately.
 

Changing table name foreign key column name of collection table

 
To do this we need to add @JoinTable annotation before the collection in Entity class as show below.
 

@ElementCollection
@JoinTable(name="ADDRESS",joinColumns=@JoinColumn(name="STUDENT_ID"))
private Collection<Address> lisOfAddress = new ArrayList<Address>();

 
In parameter of @JoinTable table we specify name of table and name of joinColumns (i.e foreign key) with another annotation @JoinColumn. When you run the test program with the above changes, the following quires are displayed in eclipse console which have our overridden table name primary key name.
 

insert into STUDENT(COLLEGE, DEPARTMENT, NAME, ID) values (?, ?, ?, ?)
insert into ADDRESS(STUDENT_ID,CITY_NAME,PIN_CODE,STATE_NAME,STREET_NAME) values (?,?,?,?,?)
insert into ADDRESS(STUDENT_ID,CITY_NAME,PIN_CODE,STATE_NAME,STREET_NAME) values (?,?,?,?,?)

 

Inserting Primary key for collection inside entity class

 
To inset the primary key collection table I have modified the collection element in Entity class as shown below.
 

@ElementCollection
@JoinTable(name="ADDRESS",joinColumns=@JoinColumn(name="STUDENT_ID"))
@GenericGenerator(name="myGenerator", strategy="increment")
@CollectionId(columns = {@Column(name="ADDRESS_ID")},
                          generator="myGenerator",type=@Type(type="int"))
private Collection<Address> lisOfAddress = new ArrayList<Address>();

 

Here are the topics of interest for our code above:
  • Since the primary key is to be created at collection table, we use the @CollectionId instead of @Id annotation before the collection in Entity class.
  • With the @GenericGenerator annotation, we will to give some information to @CollectionId and tell how it should work. First off, we name this GenericGenerator whatever we like, for my example I just named it “myGenerator” but this is completely up to you. We also tell it what ID generation strategy to use, in this case I used “INCREMENT” strategy.
  • Oh, and let’s not forget to point our @GeneratedValue annotation to our newly minted customer @ CollectionId via the generator=”myGenerator” property.

 
Address.java and hibernate.cfg.xml and HibernateUtil.java is the same as previous post.
 

Run it – Eclipse console

 
On running the Hibernate test class with above changes, the collection table gets created as below.
 

 
Here ADDRESS_ID is the primary key which gets generated due to above code change.
 
Voila!
 
download

Read More

Saving Collections in Hibernate

Posted by in Hibernate, Hibernate Annotation | 1 comment

 

 
In our last Hibernate article, we learned about Embedding value object into an entity class. In this article we’re going to focus on saving a Collection in Hibernate.
 
Consider a scenario where the student have lots of address. So in this case we need to create more no of embedded object in the student class, which is so tedious at certain point. In such case we can use Collection to solve this problem. This collection can be a list, set, map, collection, sorted set, sorted map. Hibernate provides the facility to persist the collections object via @ElementCollection annotation.
 

Entity Class

 

package entity;

import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT")
public class Student {

	@Id
	@GeneratedValue
	@Column(name = "ID")
	private int id;

	@Column(name = "NAME")
	private String name;

	@Column(name = "DEPARTMENT")
	private String department;

	@Column(name = "COLLEGE")
	private String college;

	@ElementCollection
	private Collection<Address> lisOfAddress = new ArrayList<Address>();

        // Create Getters and Setters
}

 

@ElementCollection:

Defines a collection of instances of an embeddable class, this annotation must be specified if the collection is to be mapped by means of a collection table.
 

package entity;

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;
        
        // Create Getters and Setters
}

 
hibernate.cfg.xml will be the same as in previous article.
 

HibernateTest class

 
Create the Main class to run the example.

package util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

import entity.Address;
import entity.Student;

public class HibernateUtil {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb =
                               new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
		
		Address address1 = new Address();
		address1.setStreet("Race cource");
		address1.setCity("Coimbatore");
		address1.setState("Tamilnadu");
		address1.setPincode("642001");
		
		Address address2 = new Address();
		address2.setStreet("Besant nagar");
		address2.setCity("Chennai");
		address2.setState("Tamilnadu");
		address2.setPincode("600001");
		
		Student student = new Student();

		student.setName("Lahir Nisha");
		student.setDepartment("ECE");
		student.setCollege("SKCET");
		
		//adding addresses object to the list of address
		student.getLisOfAddress().add(address1);
		student.getLisOfAddress().add(address2);

                session.save(student);
        
		tx.commit();
		session.close();
		sf.close();
	}
}

 

Rut it – Eclipse Console

 

 
When you run the above program two tables are created in database, first table is for Student entity “STUDENT” and second table is for the embeddable object (Address) – “Student_lisOfAddress” (The default table name for this table gets generated based on – Entity class name_Name of the embeddable object in the entity class).
 
Here the ‘Student_ID’ column in ‘Student_lisOfAddress’ is the foreign key reference of Student tables ‘ID’. In next article we shall learn to override the default collection class table name and to add primary key to it.
 
download

Read More

Value object & Entity object in Hibernate mapping

Posted by in Hibernate, Hibernate Annotation

So far we have learnt how to write a model object and we learnt to annotate a model object so that hibernate create a table for us, then we learnt how to save, retrieve, update and delete the entity object in the database.
 

 
Still now we have created the entity class based on the assumption that each member variable inside the entity class will have a single column in database.
 
In Above table the type of fields of the class STUDENT CLASS is as below.

              ID            is INTEGER type
              Name          is VARCHAR type
              DEPARTMENT    is VARCHAR type
              ADDRESS       is VARCHAR type
              COLLEGE       is VARCHAR type

Now what if one of these member variable is an object instead of a simple data type. For example
 

 
Here STUDENT CLASS have a field Address object, this means in the database there are no meaning for Address object, as this Address object in turn have four other fields like.

1. Street
2. City
3. State
4. Pin code

Now the question is how can we save this address object into the database.
 

Value object

 
One way of saving the Address Object is to treat the member variable of address objects as the member variable of Student object itself.
 

 
Here without having a Student object the use of Address object doesn’t make any sense. So the purpose of address object is just provide value to the Student object; And this is what differentiate an Entity object from a Value object.
 

So what the heck is Value object?

 
Entity object is the one which have meaning on its own, where a value object has no meaning on its own, the value object belongs to an entity instance and its persistent state is embedded in the table row of the owning entity.
In the above example the Student object represents an Entity object and Address object represents a Value object.
 

Long story short here:

 
Entity Object: Has its own database identity (Student table)
Value Object: Doesn’t not have its own database identity
 
Now let’s create an class for Address (Value object)
 

package entity;

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;
        
        // Create getters and setters
}

 
Now in order to make this class of value type, and in order to tell hibernate not to create a separate table for address class, I have used @Embeddable annotation in the Address class, Also we need to use @Embedded annotation in the member variable of Address object in Student entity class as shown below.
 

package entity;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT")
public class Student {

	@Id
	@GeneratedValue
	@Column(name = "ID")
	private int id;

	@Column(name = "NAME")
	private String name;

	@Column(name = "DEPARTMENT")
	private String department;

	@Column(name = "COLLEGE")
	private String college;

	// For value type object
	@Embedded
	private Address address;

       // Getters and Setters
}

 

Hibernate Configuration file

 
File: hibernate.cfg.xml

<hibernate-configuration>
<session-factory>
	<!-- Database connection settings -->
	<property name="hibernate.connection.driver_class">
                 oracle.jdbc.driver.OracleDriver
        </property>
	<property name="hibernate.connection.username">system</property>
	<property name="hibernate.connection.password">admin</property>
	<property name="hibernate.connection.url">
                jdbc:oracle:thin:@127.0.0.1:1521:XE
        </property>

	<!-- SQL dialect -->
	<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

	<!-- Echo all executed SQL to sysout -->
	<property name="show_sql">true</property>

	<!-- Drop and re-create the database schema on startup -->
	<property name="hibernate.hbm2ddl.auto">create</property>
	<!-- Map Entity Class -->
    <mapping class="entity.Student"></mapping>

</session-factory>

</hibernate-configuration>

 

HibernateTest class

 
Create the Main class to run the example.

package util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

import entity.Address;
import entity.Student;

public class HibernateUtil {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb =
                         new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();

		Student student = new Student();

		student.setName("Lahir Nisha");
		student.setDepartment("ECE");
		student.setCollege("SKCET");

		Address address1 = new Address();
		address1.setStreet("Race cource");
		address1.setCity("Coimbatore");
		address1.setState("Tamilnadu");
		address1.setPincode("642001");
		student.setAddress(address1);
                session.save(student);

		tx.commit();
		session.close();
		sf.close();
	}
}

 

Run it – Eclipse Console

 

 

Database Output

 

 

@AttributeOverride annotation:

 
So far we have seen that an Entity Type Object Student has a Value Object(or Embeddable Object ) ADDRESS with corresponding fields name street, city, pin-code and state save to the database table STUDENT with value object’s column name (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME).
 
Suppose in the above scenario if a Student have two addresses like Local Address and Permanent Address then how to manage the column names of these two value objects in the database table STUDENT.
 
In order to overcome this problem, we have to override the Attribute name of the Value objects. Hibernate has provided @AttributeOverride annotation for this purpose.
 
Example:-

Student.java

 

package entity;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT")
public class Student {

	@Id
	@GeneratedValue
	@Column(name = "ID")
	private int id;

	@Column(name = "NAME")
	private String name;

	@Column(name = "DEPARTMENT")
	private String department;

	@Column(name = "COLLEGE")
	private String college;

	@Column(name = "ADDRESS")
	@Embedded
	@AttributeOverrides({
	   @AttributeOverride(name = "street", column = @Column(name = "HOME_STREET_NAME")),
	   @AttributeOverride(name = "city", column = @Column(name = "HOME_CITY_NAME")),
	   @AttributeOverride(name = "state", column = @Column(name = "HOME_STATE_NAME")),
	   @AttributeOverride(name = "pincode", column = @Column(name = "HOME_PIN_CODE")) })
	private Address homeAddress;

	@Embedded
	private Address permanentAddress;
        // Create getters and setters
}

 

HibernateTest class

 
Create the Main class to run the example.

package util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

import entity.Address;
import entity.Student;

public class HibernateUtil {

	public static void main(String[] args) {

		Configuration cf = new Configuration().configure("hibernate.cfg.xml");

		StandardServiceRegistryBuilder srb
                             = new StandardServiceRegistryBuilder();
		srb.applySettings(cf.getProperties());
		ServiceRegistry sr = srb.build();
		SessionFactory sf = cf.buildSessionFactory(sr);

		Session session = sf.openSession();
		Transaction tx = session.beginTransaction();
		
		Address homeAddress = new Address();
		homeAddress.setStreet("Race cource");
		homeAddress.setCity("Coimbatore");
		homeAddress.setState("Tamilnadu");
		homeAddress.setPincode("642001");
		
		Address permanantAddress = new Address();
		permanantAddress.setStreet("Besant nagar");
		permanantAddress.setCity("Chennai");
		permanantAddress.setState("Tamilnadu");
		permanantAddress.setPincode("600001");
		
		Student student = new Student();

		student.setName("Lahir Nisha");
		student.setDepartment("ECE");
		student.setCollege("SKCET");
		student.setPermanentAddress(permanantAddress);
		student.setHomeAddress(homeAddress);

                session.save(student);
        
		tx.commit();
		session.close();
		sf.close();
	}
}

 

Eclipse console after running this program


 
Hibernate: insert into STUDENT (COLLEGE, DEPARTMENT, HOME_CITY_NAME, HOME_PIN_CODE, HOME_STATE_NAME, HOME_STREET_NAME, NAME, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
 
In our next article we shall learn about Saving Collections in Hibernate Read More

Composite Primary Keys In Hibernate

Posted by in Hibernate, Hibernate Annotation


 
If the table has a primary key then in Entity class we configure that column using @Id annotation. Even when the table doesn’t need a primary key, we must configure one column as id (one primary key is must).
 
Now If the database table has more than one column as primary key then we call it as composite primary key, so if the table has multiple primary key columns , then in order to configure these primary key columns we need to create a new @Embeddable class containing the PK fields:
 

@Embeddable
public class RegistrationId implements Serializable{

	@Column(name = "STUDENT_ID")
	private int studentId;

	@Column(name = "DEPARTMENT")
	private String department;

        // Create getters and Setters
}

 
And we should use it in the @Entity as a @EmbeddedId:
 

@Entity
@Table(name = "STUDENT")
public class StudentEntity {

	@EmbeddedId
	private RegistrationId regid;
        ...
        // Create Getters and Setters
}

 
To persist the entity:
 

   RegistrationId regId = new RegistrationId();
   regId.setStudentId(1);
   regId.setDepartment("ECE");

   StudentEntity student = new StudentEntity();
   student.setRegid(regId);
	
   session.save(student);

 
The following rules must apply for composite primary keys:

  • The primary key class must be public.
  • If property-based access is used, the properties of the primary key class must be public or protected.
  • The primary key class must be serializable. We shall explore the reason for implementing this interface in our upcoming tutorial.
  • A composite primary key must be represented and mapped as an embeddable class (EmbeddedId Annotation).

We shall explore the concept behind this composite primary keys in the next article.
 

Other Hibernate tutorial from our Blog

 

Read More

Auto Generate Primary key in Hibernate

Posted by in Hibernate, Hibernate Annotation

 

 
In our early tutorials I have used @Id annotation to mark a particular field as primary key, this Primary key is used to fetch data via get or load method. And we set the value of primary key manually each time when we are about to create a new record.
 
In this article we shall learn to Auto Generate this Primary key value in Hibernate. Before getting into the above topic, let us have a discussion about Natural key and Surrogate key.
 

Natural Key

 
A natural key is a single column or set of columns which are made up of real data. When I say “real data” I mean data that has meaning and occurs naturally in the world of data. Some examples of natural keys values are Email id, Social Security Number etc.
 

Surrogate key

 
Surrogate key is “a system-generated value used to uniquely identify a row”. Its value is typically generated at run time right before the record is inserted into a table. Unlike natural keys, Surrogate key have no business meaning. Surrogate keys are commonly a numeric number.
 
So if we are having a natural key, it would make sense for us to provide the value via application, because it’s of business significance and we need to control its value.
 
But if it’s a Surrogate key then it’s not necessary that we have to provide it via our application. We can just ask hibernate to do the job for us, because it does not matter for us that what its value is going to be, we just need to make sure that its value had to be unique and not null.
 
To indicate hibernate to generate value for a primary key (Surrogate key) while inserting a new record in a table, we have to use @GeneratedValue. This annotation makes the column to be auto generated.
 
Example:
 

Entity Class

 

package entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STUDENT")
public class StudentEntity {

	@Id
	@GeneratedValue
	@Column(name = "ID")
	private int id;

	@Column(name = "NAME")
	private String name;

	@Column(name = "DEPARTMENT")
	private String department;

	@Column(name = "COLLEGE")
	private String college;
	 
        //Create Getters and Setters
}

 

Hibernate Utility

 
Create the Main class to run the example.

public class HibernateUtil {

	public static void main(String[] args) {

	Configuration cf = new Configuration().configure("hibernate.cfg.xml");

	StandardServiceRegistryBuilder srb = new StandardServiceRegistryBuilder();
	srb.applySettings(cf.getProperties());
	ServiceRegistry sr = srb.build();
	SessionFactory sf = cf.buildSessionFactory(sr);

	Session session = sf.openSession();
	Transaction tx = session.beginTransaction();
	
	StudentEntity student1 = new StudentEntity();

	student1.setName("Jamil");
	student1.setDepartment("ECE");
	student1.setCollege("SKCET");
	
	StudentEntity student2 = new StudentEntity();

	student2.setName("Hp");
	student2.setDepartment("IT");
	student2.setCollege("SKCET");

	StudentEntity student3 = new StudentEntity();

	student3.setName("Lahr");
	student3.setDepartment("CSE");
	student3.setCollege("MCET");

        session.save(student1);
        session.save(student2);
        session.save(student3);

	tx.commit();
	session.close();
	sf.close();
	}
}

File hibernate.cfg.xml is same as in HelloWorld tutorial.
 

Database output

 
On running the above program, we get the following values in database.

 
Here the values in column ID is auto generated via @GeneratedValue.
 
In our next article we shall learn about configuring Composite Primary Keys In Hibernate.
 

Other Hibernate tutorial from our Blog

 

Read More

Difference Between Update and Merge methods In Hibernate

Posted by in Hibernate, Hibernate Annotation | 4 comments

 
update merge in hibernate
 
Often times, you will notice Hibernate developers mix use of session.update() and session.merge()

At first look both update() and merge() methods seems similar because both of them are used to convert the object which is in detached state into persistence state, but the major difference between update and merge is that update method cannot be used when the same object exists in the session. Let’s look at those difference with simple example.
 
Example :-
 

	Student current = (Student)session.get(Student.class, 100);
	System.out.println("Before merge: " + current.getName());
	Student changed = new Student();
	changed.setId(100);
	changed.setName("Changed new Name");
	// session.update(changed); // Throws NonUniqueObjectException
	session.merge(changed);
	System.out.println("After merge: " + current.getName());

 

Explanation

 
In the above program I have loaded a Student object of ID ‘100’ at line no 1. After that I have created a new Student object ‘changed’ with same ID ‘100’. Now if I try to call update method on this ‘changed’ object, then Hibernate will through a NonUniqueObjectException, because the same object (Student) with Id ‘100’ already exists in session.
 
Now at line no ‘7’, I have called session.merge(changed); this merge() will work fine and the name will get changed and saved into the database. After this on printing the current object, it will print the latest changed value, since when the merge occurs the value loaded in session gets changed.
 
Done and done! So there you have it, you now know the exact difference between merge() and update() method in Hibernate framework and actually the usage of merge() methods will come into picture when ever we try to load the same object again and again into the database.
 

Other Hibernate tutorial from our Blog

 

Read More