Cascade is used when multiple objects in entities wants to be saved in a single shot.

For Example

 session.save(objUserDetail1);
 session.save(objVeh1);
 session.save(objVeh2);
 session.save(objVeh3);

can be replaced by

 session.persist(objUserDetail1);

UserDetails.java

@Entity
@Table(name="USER_DETAIL")
public class UserDetails 
{	
	@Id @GeneratedValue(strategy = GenerationType.AUTO)	
	private int UserId;	
	private String UserName;
	
	@OneToMany(cascade=CascadeType.PERSIST)
	private List<Vehicles> arrVehicles = new ArrayList<Vehicles>();
	  
	public List<Vehicles> getArrVehicles() {
		return arrVehicles;
	}
	public void setArrVehicles(List<Vehicles> arrVehicles) {
		this.arrVehicles = arrVehicles;
	}
	
	public int getUserId() {
		return UserId;
	}
	public void setUserId(int userId) {
		UserId = userId;
	}
	public String getUserName() {
		return UserName;
	}
	public void setUserName(String userName) {
		UserName = userName;
	}
}

CreateTables.java

public static void main(String[] args) 
  {	
	UserDetails objUserDetail1 =  new UserDetails();
	objUserDetail1.setUserName("Mugil");

	Vehicles objVeh1 = new Vehicles();
	objVeh1.setVehicleName("Suzuki");
	objUserDetail1.getArrVehicles().add(objVeh1);

	Vehicles objVeh2 = new Vehicles();
	objVeh2.setVehicleName("Maruthi");
	objUserDetail1.getArrVehicles().add(objVeh2);

	Vehicles objVeh3 = new Vehicles();
	objVeh3.setVehicleName("Volkswagon");
	objUserDetail1.getArrVehicles().add(objVeh3);
							
	SessionFactory sessionFact = createSessionFactory();
	Session session = sessionFact.openSession();

	session.beginTransaction();				
	session.persist(objUserDetail1);		

	session.getTransaction().commit();
	session.close();  
  }

1.What is the difference between annotations @Id and @GeneratedValue

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id") 
private Integer id;

@Id
In a Object Relational Mapping context, every object needs to have a unique identifier. You use the @Id annotation to specify the primary key of an entity.

@GeneratedValue
The @GeneratedValue annotation is used to specify how the primary key should be generated. In your example you are using an Identity strategy which indicates that the persistence provider must assign primary keys for the entity using a database identity column.

Notes

  • The difference between @Id and @GeneratedValue can be clearly observed while switching from OneToOne and OneToMany Mapping where the OneToOne Mapping requires only ID to insert values for both the table whereas OneToMany Mapping table insertion depends on values inserted in one and other table.
  • @GeneratedValue creates a sequence maintained at database

2.Sequence vs Identity
Sequence and identity both used to generate auto number but the major difference is Identity is a table dependant and Sequence is independent from table.

If you have a scenario where you need to maintain an auto number globally (in multiple tables), also you need to restart you interval after particular number and you need to cache it also for performance, here is the place where we need sequence and not identity.

When @Id is used the value count starts from 0 where as when @GeneratedValue is used the count starts from 1

3.What is difference between OneToMany and ManyToOne Mapping?
For example, if a user, a company, a provider all have many addresses, it would make sense to have a unidirectional between every of them and Address, and have Address not know about their owner.

Suppose you have a User and a Message, where a user can have thousands of messages, it could make sense to model it only as a ManyToOne from Message to User, because you’ll rarely ask for all the messages of a user anyway.

In One-to-many you keep the reference of many objects via (set, list) for the associated objects. You may not access the parent object from the items it is associated with. E.g. A person has many skills. If you go to a particular skill you may not access the persons possessing such skills. This means given a Skill ,s, you’ll not be able to do s.persons.

In Many-to-one many items/objects will have reference to a particular object. E.g. Users x and y apply to some job k. So both classes will have their attribute Job job set to k but given a reference to the job k you many not access the objects that have it as an attribute job. So to answer the question “Which users have applied to the job k?”, you’ll have to go through the Users list.

One-to-Many: One Person Has Many Skills, a Skill is not reused between Person(s)
Unidirectional: A Person can directly reference Skills via its Set
Bidirectional: Each “child” Skill has a single pointer back up to the Person (which is not shown in your code)

One-to-Many: One Person Has Many Skills, a Skill is not reused between Person(s)
Unidirectional: A Person can directly reference Skills via its Set
Bidirectional: Each “child” Skill has a single pointer back up to the Person (which is not shown in your code)

Many-to-Many: One Person Has Many Skills, a Skill is reused between Person(s)
Unidirectional: A Person can directly reference Skills via its Set
Bidirectional: A Skill has a Set of Person(s) which relate to it.

4.Difference between Unidirectional and Bidirectional associations?
Bidirectional relationship provides navigational access in both directions, so that you can access the other side without explicit queries. Also it allows you to apply cascading options to both directions.

When we have a bidirectional relationship between objects, it means that we are able to access Object A from Object B, and Object B from Object A.

Unidirectional – means only allow navigating from one side of the mapping to another. For example in the case of a one-many mapping, only allow navigation from the one side to the many side. Bi-directional means to allow navigation both ways.

Continue reading

OnetoOne
UserDetails.java

@Entity
@Getter
@Setter
@Table(name="USER_DETAIL")
public class UserDetails 
{	
	@Id @GeneratedValue(strategy = GenerationType.AUTO)	
	private int UserId;	
	private String UserName;
	  
	@OneToOne
	private Vehicles veh;
}

Vehicles.java

@Entity
@Getter
@Setter
public class Vehicles 
{
	@Id @GeneratedValue
	private int vehicleId;
	
private String vehicleName;
}

CreateTable.java

public static void main(String[] args) 
  {
		UserDetails objUserDetail1 =  new UserDetails();
		objUserDetail1.setUserName("Mugil Vannan");
		
		Vehicles objVeh = new Vehicles();
		objVeh.setVehicleName("Suzuki");
		objUserDetail1.setVeh(objVeh);
		
		UserDetails objUserDetail2 =  new UserDetails();
		objUserDetail2.setUserName("Mani");
		
		Vehicles objVeh2 = new Vehicles();
		objVeh2.setVehicleName("Maruthi");
		objUserDetail2.setVeh(objVeh2);
		
		SessionFactory sessionFact = createSessionFactory();
		Session session = sessionFact.openSession();
		
		session.beginTransaction();				
		session.save(objUserDetail1);
		session.save(objVeh);
		session.save(objUserDetail2);
		session.save(objVeh2);
		session.getTransaction().commit();
		session.close();
  }

OnetoMany
UserDetails.java

@Getter
@Setter
@Entity
@Table(name="USER_DETAIL")
public class UserDetails 
{	
	@Id @GeneratedValue(strategy = GenerationType.AUTO)	
	private int UserId;	
	
        private String UserName;
	  
	@OneToMany	
        @JoinTable(joinColumns=@JoinColumn(name="USER_ID"),
	           inverseJoinColumns=@JoinColumn(name="VEHICLE_ID"))
	private List<Vehicles> arrVeh = new ArrayList<Vehicles>();
}

Vehicles.java

@Getter
@Setter
@Entity
public class Vehicles 
{
	@Id @GeneratedValue
	private int vehicleId;
	
        private String vehicleName;
}

CreateTables.java

 public static void main(String[] args) 
  {
        UserDetails objUserDetail1 =  new UserDetails();
        objUserDetail1.setUserName("Mugil Vannan");

        Vehicles objVeh = new Vehicles();
        objVeh.setVehicleName("Suzuki");
        objUserDetail1.getArrVeh().add(objVeh);

        Vehicles objVeh2 = new Vehicles();
        objVeh2.setVehicleName("Maruthi");
        objUserDetail1.getArrVeh().add(objVeh2);

        SessionFactory sessionFact = createSessionFactory();
        Session session = sessionFact.openSession();

        session.beginTransaction();				
        session.save(objUserDetail1);
        session.save(objVeh);
        session.save(objVeh2);
        session.getTransaction().commit();
        session.close();	
  }

ManytoOne
UserDetails.java

@Getter
@Setter
@Entity
@Table(name="USER_DETAIL")
public class UserDetails {	
	@Id @GeneratedValue(strategy = GenerationType.AUTO)	
	private int UserId;	
	
        private String UserName;
}

Vehicles.java

@Getter
@Setter
@Entity
public class Vehicles {
	@Id @GeneratedValue
	private int vehicleId;
	
        private String vehicleName;
	
	@ManyToOne	
	private UserDetails objUserDetails;
}

CreateTables.java

public static void main(String[] args) 
  {	
	Vehicles objVeh1 = new Vehicles();
        objVeh1.setVehicleName("Suzuki");

	Vehicles objVeh2 = new Vehicles();
	objVeh2.setVehicleName("Maruthi");

	UserDetails objUserDetail1 =  new UserDetails();
	objUserDetail1.setUserName("Mugil Vannan");
	
	objVeh1.setObjUserDetails(objUserDetail1);
	objVeh2.setObjUserDetails(objUserDetail1);
			
	SessionFactory sessionFact = createSessionFactory();
	Session session = sessionFact.openSession();

	session.beginTransaction();				
	session.save(objUserDetail1);		
	session.save(objVeh1);
	session.save(objVeh2);
	session.getTransaction().commit();
	session.close();	
  }

ManytoMany
UserDetails.java

@Getter
@Setter
@Entity
@Table(name="USER_DETAIL")
public class UserDetails {	
	@Id @GeneratedValue(strategy = GenerationType.AUTO)	
	private int UserId;	
	
        private String UserName;
	
	@ManyToMany
	private List<Vehicles> arrVehicles = new ArrayList<Vehicles>();
}

Vehicles.java

@Getter
@Setter
@Entity
public class Vehicles {
	@Id @GeneratedValue
	private int vehicleId;
	
        private String vehicleName;
	
	@ManyToMany(mappedBy="arrVehicles") 
	private List<UserDetails> arrUserDetails = new ArrayList<UserDetails>();
}

CreateTables.java

public static void main(String[] args) 
  {	
	Vehicles objVeh1 = new Vehicles();
	objVeh1.setVehicleName("Suzuki");
	
	Vehicles objVeh2 = new Vehicles();
	objVeh2.setVehicleName("Maruthi");
	
	UserDetails objUserDetail1 =  new UserDetails();
	objUserDetail1.setUserName("Mugil Vannan");
	
	UserDetails objUserDetail2 =  new UserDetails();
	objUserDetail2.setUserName("Mani");
	
	objVeh1.getArrUserDetails().add(objUserDetail1);
	objVeh1.getArrUserDetails().add(objUserDetail2);
	
	objUserDetail1.getArrVehicles().add(objVeh1);
	objUserDetail1.getArrVehicles().add(objVeh2);
							
	SessionFactory sessionFact = createSessionFactory();
	Session session = sessionFact.openSession();
	
	session.beginTransaction();				
	session.save(objUserDetail1);
	session.save(objUserDetail2);		
	session.save(objVeh1);
	session.save(objVeh2);
	session.getTransaction().commit();
	session.close();	
  }
   

@Entity
public class UserDetails 
{
@GenericGenerator(name="sequence-gen",strategy="sequence")
	@CollectionId(columns={@Column(name="Address_Id")}, generator="sequence-gen", type=@Type(type="long"))
private List<Address> arrList = new ArrayList<Address>();
.
.
.
}

While working with collection if you want the details to be stored in a seperate table using @ElementCollection solves the purpose

UserDetails.java

 public class UserDetails {
  @ElementCollection
  private List<Address> arrList = new ArrayList<Address>();

 }

Address.java

@Embeddable
public class Address 
{
  private String DoorNo;
  private String Street;
  private String Location;
  private String Pincode;
  .
  .
  .
 }

createTables.java

public class CreateTables {   
  public static void main(String[] args) 
  {
    UserDetails objUserDetail1 =  new UserDetails();

    Address objAddr = new Address();
    objAddr.setDoorNo("13");
    objAddr.setStreetName("Poes Road");
    objAddr.setLocation("Teynampet");
    objAddr.setPincode("600018");
    
    
    Address objAddr2 = new Address();
    objAddr2.setDoorNo("256");
    objAddr2.setStreetName("Sriman Srinivasan Road");
    objAddr2.setLocation("Alwarpet");
    objAddr2.setPincode("600018");
    
    objUserDetail1.getArrList().add(objAddr);
    objUserDetail1.getArrList().add(objAddr2);
  }
}

Giving Names to Joined Tables

  • New Table will be created under USER_ADDRESS Name
  • joinColumns decides which column should be used for joining two tables

Format for Join Table

  @JoinTable(name="JOIN_TABLE_DESIRED_NAME", 
	     joinColumns= @JoinColumn(name="userId"))
  @JoinTable(name="USER_ADDRESS", 
	     joinColumns= @JoinColumn(name="userId"))
  private Set<Address> addressSet = new HashSet();
  .
  .

There are two types of objects in Hibernate
1. Value Object
2. Entities

Value Objects are the objects which can not stand alone. Take Address, for example. If you say address, people will ask whose address is this. So it can not stand alone.
Entity Objects are those who can stand alone like College and Student.

So in case of value objects preferred way is to Embed them into an entity object. In the example below Address class does not derive the meaning of its own. So Address is Value Object and is Embeddable. Whereas UserDetails(Entities) could stand on its own and it could have Embedded Objects

Address.java

 import javax.persistence.Embeddable;

@Embeddable
public class Address {
	private String Street;
	private String Location;
	private String City;
	
	public String getStreet() {
		return Street;
	}
	public void setStreet(String street) {
		Street = street;
	}
	public String getLocation() {
		return Location;
	}
	public void setLocation(String location) {
		Location = location;
	}
	public String getCity() {
		return City;
	}
	public void setCity(String city) {
		City = city;
	}
}

UserDetails.java

public class UserDetails 
{
 @Embedded
 private Address address;
 .
 .
 .
}

The above code explains how the Embedded and Embeddable annotations can be used in the code.

CreateUser.java

  Address objAddress = new Address();
  objUserDetail.setAddress(objAddress);

Attribute Override

@Embedded
@AttributeOverride (name="Street",column=@Column(name="HOME_STREET"))
private Address addr;

Multiple Attribute Overrides

@Embedded
 @AttributeOverrides({
	@AttributeOverride(name="doorNo", column=@Column(name="Office_DoorNo")),
	@AttributeOverride(name="streetName", column=@Column(name="Office_streetName")),
	@AttributeOverride(name="location", column=@Column(name="Office_location")),
	@AttributeOverride(name="pincode", column=@Column(name="Office_pincode"))
})
private Address addr;
  @Id @GeneratedValue(strategy=GenerationType.AUTO)
  private int userId;

By using @GeneratedValue annotation we can create primary key in table.The annotations takes 4 parameter as strategy attribute.

@GeneratedValue(strategy=GenerationType.AUTO)
Auto tells the Hibernate to do the primary key addition from hibernate side

@GeneratedValue(strategy=GenerationType.IDENTITY)
IDENTITY tells the Hibernate to do the primary key addition from DB side when set to auto increment.

@GeneratedValue(strategy=GenerationType.SEQUENCE)
SEQUENCE tells the Hibernate to do the primary key addition as defined by sequence in DB.

@GeneratedValue(strategy=GenerationType.TABLE)
TABLE tells the Hibernate to create a seperate table in DB and maintain the last inserted values.
The table contains only one row with last inserted value.

15

Retrieve value from Database using Session

public static void main(String[] args)
{
	UserDetails objUserDetail =  new UserDetails();
	.
	session.getTransaction().commit();

	objUserDetail = null;

	/*Retriving UserDetails from DB Using Session*/
	session = sessionFact.openSession();
	session.beginTransaction();
	objUserDetail = (UserDetails)session.get(UserDetails.class, 105);
	System.out.println(objUserDetail.getUserName());
}

To retrieve the value from session we use the primary key for the table in the above case.

 objUserDetail = (UserDetails)session.get(UserDetails.class, 105);
 System.out.println(objUserDetail.getUserName());

105 – is the UserId which is primary key for the USER_DETAILS table in DB.

Defining Dialect in Hibernate

MySQL Dialect
MySQL Dialect

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>  
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.password">pass</property>
        
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

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

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</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">update</property>
        
        <!-- Name of the Annotated Entity class -->
        <mapping class="com.mugil.dto.UserDetails"/>
    </session-factory>
</hibernate-configuration>

If hbm2ddl.auto is set to create the table will be created every time when java class is Run.The old records will be deleted.

<property name="hbm2ddl.auto">create</property>

When set to update the records will be added without new table creation

<property name="hbm2ddl.auto">update</property>

More Annotations

3

@Transient tells not to create Column
@Column tells the Hibernate the Name under which column need to be
created in Db table.

@Transient 
@Column (name="User_Name") 
private String userName; 

@Temporal tells the option of selective addition.Below I am adding Date rather than
Date & time as Timestamp

 @Temporal (TemporalType.DATE) 
 private Date DOJ;

@Lob – Large Object, Telling Hibernate to create Large Object Datatype fro Column
@Lob over String creates CLOB
@Lob over Byte creates BLOB

 @Lob
 private String userDescription;

Simple Hibernate Table Creation from Scratch

Hibernate Required Jar Files List
Hibernate Required Jar Files List

Step1: Create a Bean for which Table should be created in Database
Step2: Create a Class which uses the bean.

Step 1

package com.mugil.dto;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity 
public class UserDetails {
	@Id	
	private int userId;
	private String userName;
	
	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;
	}
}

Step 2

package com.mugil.access;

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

import com.mugil.dto.UserDetails;

public class CreateUser {
	private static ServiceRegistry serviceRegistry;
	private static SessionFactory sessionFactory;
	
	public static void main(String[] args) {
		UserDetails objUserDetail =  new UserDetails();
		objUserDetail.setUserId(101);
		objUserDetail.setUserName("Mugil");
		
		SessionFactory sessionFact = createSessionFactory();
		Session session = sessionFact.openSession();
		session.beginTransaction();
		session.save(objUserDetail);
		session.getTransaction().commit();	
	}
	
	
	public static SessionFactory createSessionFactory() {
	    Configuration configuration = new Configuration();
	    configuration.configure();
	    serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
	            configuration.getProperties()).build();
	    sessionFactory = configuration.buildSessionFactory(serviceRegistry);
	    return sessionFactory;
	}
}

In Some cases the hibernate.cfg.xml might become unrecognized.In such case the code should be changed to force the config to be picked from the file location.

public static SessionFactory createSessionFactory() 
{
  Configuration configuration = new Configuration().configure();	  
  configuration.configure("hibernate.cfg.xml");	  
  configuration.addAnnotatedClass(com.mugil.tutor.UserDetails.class);
	  
  serviceRegistry = new   StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
  sessionFactory = configuration.buildSessionFactory(serviceRegistry);
  return sessionFactory;
}

Hibernate uses SessionFactory pattern internally as below

SessionFactory sessionFact = createSessionFactory();
Session session = sessionFact.openSession();
session.beginTransaction();
session.save(objUserDetail);
session.getTransaction().commit();	

1.Create Object for SessionFactory
2.Open Session to begin Transaction
3.Begin Transaction using beginTransaction() Method
4.Save the Object by Passing Object of the bean
5.Complete the Transaction using commit

Annotations
@Entity – Means entity as a whole>table would be created by the Name of the Entity
@Id – Tells the Primary Key

Having a Different table name from Class Name
Annotations

@Entity(name="User_Details")
public class Users 
{
 .
 .
}

Table with User_Details would be created instead of Users

Having a Different Column name from Object Name
Annotations

@Entity(name="User_Details")
public class Users 
{
 @Id
 @Column(name="USER_ID")
 private String UserId;
 .
 .
}

Columns with User_Id would be created instead of UserId

Appending String to Getters

public void setName(String name) 
{
  Name = name + " Append Test ";
}

Appending String to Getters

@Entity
@Table (name="User_Details")
public class Users 
{

}

The Entity Name Still remains the same but the table Name is different.

@Basic Annotation – Tells Hibernate to persist which it does by default

public class Users 
{
 @Basic
 private String UserName;
 . 
 .
}

@Basic has 2 Parameters – Fetch, optional. The only time you use @Basic is while applying the above options.

@Transient Annotation – Tells Hibernate to not store data in database

public class Users 
{
 @Transient
 private String UserName;
 . 
 .
}

@Temporal Annotation – Tells Hibernate to specify Date or Time

public class Users 
{
 @Temporal (TemporalType.Date)
 private String joinedDate;
 . 
 .
}

Without @Temporal the joinedDate is store along with TimeStamp in DB. Now using TemporalType(which is ENUM) you can select the type of data which can be stored in Database.

@Lob – Tells Hibernate to specify Date or Time

public class Users 
{
 @Lob
 private String Address;
 . 
 .
}

Tells the database field should be created as CLOB instead of VARCHAR(255).