Getting list of Users from users Table

     sessionFactory = createSessionFactory();
     Session objSession = sessionFactory.openSession();
     objSession.beginTransaction();
		
     Query objQuery = objSession.createQuery("from Users");
     List<Users> arrUsers = objQuery.list();
		
     objSession.getTransaction().commit();
     objSession.close();
		
     System.out.println(arrUsers.size());

     for (Users users : arrUsers) {
	System.out.println(users.getUserName());
     }

Pagination Using HQL

    Query objQuery = objSession.createQuery("from Users");		
    objQuery.setFirstResult(5);
    objQuery.setMaxResults(2);
    List<Users> arrUsers = objQuery.list();
				
    objSession.getTransaction().commit();
    objSession.close();
		
    System.out.println(arrUsers.size());
		
    for (Users users : arrUsers) {
	System.out.println(users.getUserName());
    }

Note: In Pagination the Starting record is specified by setFirstResult and ending record is specified by setMaxResults.

Taking a Specific Column for Entity

	Query objQuery = objSession.createQuery("select UserName from Users");		
	objQuery.setFirstResult(5);
	objQuery.setMaxResults(2);
	List<String> arrUsers = (List<String>)objQuery.list();

	objSession.getTransaction().commit();
	objSession.close();

	System.out.println(arrUsers.size());

	for (String users : arrUsers) {
		System.out.println(users);
	}

Note :
The Object Name in entity should be same as specified in class including Case. username will not work in select query but UserName does.

Parameter Binding in Hibernate
Method 1

  Query objQuery = objSession.createQuery("from Users where UserId >?");
  objQuery.setParameter(0, 5);		
  List<Users> arrUsers = (List<Users>)objQuery.list();

  for (Users users : arrUsers) {
	System.out.println(users.getUserName());
  }

Method 2

     Query objQuery = objSession.createQuery("from Users where UserId > :limit");
     objQuery.setInteger("limit", 5);
		
     List<Users> arrUsers = (List<Users>)objQuery.list();
				
     objSession.getTransaction().commit();
     objSession.close();
	
     for (Users users : arrUsers) {
	System.out.println(users.getUserName());
     }

NamedQuery vs NamedNativeQuery
NamedQuery helps to consolidate all query at particular place.

users.java

@Entity
@NamedQuery(name="Users.byUserId", query="from Users where UserId=?")
public class Users {
	@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	private int UserId;
	private String UserName;
	
	public int getUserId() {
		return UserId;
	}
	public void setUserId(int userId) {
		UserId = userId;
	}
	public String getUserName() {
		return UserName;
	}
	public void setUserName(String userName) {
		UserName = userName;
	}	
}

CreationScript.java

	sessionFactory = createSessionFactory();
	Session objSession = sessionFactory.openSession();
	objSession.beginTransaction();
		
	Query objQuery = objSession.getNamedQuery("Users.byUserId");
        objQuery.setInteger(0, 5);
		
	List<Users> arrUsers = (List<Users>)objQuery.list();
	
	for (Users users : arrUsers) {
	   System.out.println(users.getUserName());
	}

NativeQueries helps us to query the table directly by using table name instead of querying through Entity like one in NamedQuery.This is useful when we use stored procedure to take our resultSets.

users.java

@Entity
@NamedNativeQuery(name="Users.byUserId", query="SELECT * from Users where UserId=?", resultClass=Users.class)
public class Users {
	@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	private int UserId;
	private String UserName;
	
	public int getUserId() {
		return UserId;
	}
	public void setUserId(int userId) {
		UserId = userId;
	}
	public String getUserName() {
		return UserName;
	}
	public void setUserName(String userName) {
		UserName = userName;
	}	
} 

Note: resultClass=Users.class should be specified or else object class cast exception would be thrown.

There may be times where you want to retrieve data from DB, do some changes in it and save back the data.In such a time the connection could not be kept open for the whole period of time since db connections are resource intensive.

So I will fetch the object -> close the Session -> Do some operations -> Open new session again -> Update the Object -> Close the Session.

	sessionFactory = createSessionFactory();
	Session objSession = sessionFactory.openSession();
	objSession.beginTransaction();		
	Users objUser = objSession.get(com.mugil.user.Users.class, 11);
	objSession.getTransaction().commit();
	objSession.close();

	objUser.setUserName("Updated");

	objSession = sessionFactory.openSession();
	objSession.beginTransaction();
	objSession.update(objUser);
	objSession.getTransaction().commit();
	objSession.close();

Now the way Hibernate works is it first runs the select query for the value which should be changed and updates the value.So 2 queries for the whole process.Now there are chance’s the value fetched from DB may or may not be changed.So we can do a check which checks the fetched and updated value for uniquess before running the update query.If the fetched data is not changed th update query wont be run.

The Annotation for that is as below.

 @Entity
 @org.hibernate.annotations.Entity(selectBeforeUpdate=true)

 	objSession.beginTransaction();		
	Users objUser = new Users();
	objUser.setUserName("Max");
	.
	.
	.
	----Transient State----
	.
	.		
	objSession.save(objUser);
	.
	.
	.
	----Persistent State----
	.
	.		
	objUser.setUserName("Max Muller");
	.
	.
	.
	----Persistent State----
	.
	.
	objSession.getTransaction().commit();
	objSession.close();
	.
	.
	.
	----Detached State----
	.
	.
	//Doesnot get reflected
	objUser.setUserName("Max Muller");
	.
	.
  • The object will be in Transient State until it is saved.An object is in transient state if it just has been instantiated using the new operator and there is no reference of it in the database i.e it does not represent any row in the database.
  • The object will be in Persistent State until the session is closed.An object is in the persistent state if it has some reference in the database i.e it represent some row in the database and identifier value is assigned to it. If any changes are made to the object then hibernate will detect those changes and effects will be there in the database that is why the name Persistent. These changes are made when session is closed. A persistent object is in the session scope.
  • The object will be in Detached State once the session is closed.An object that has been persistent and is no longer in the session scope. The hibernate will not detect any changes made to this object. It can be connected to the session again to make it persistent again.

The changes done after the session close will not get reflected

Image Showing Values in Table with and Without DiscriminatorColumn defined

  • By Default Hibernate follows Single Table Inheritance
  • DiscriminatorColumn tells hibernate the name in which DiscriminatorColumn should be save or else it would be saved as DType
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="VEHICLE_TYPE",
		     discriminatorType=DiscriminatorType.STRING)

Vehicles.java

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="VEHICLE_TYPE",
		     discriminatorType=DiscriminatorType.STRING)
public class Vehicles {
	@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	private int VehicleId;	
	private String name;
		
	public int getVehicleId() {
		return VehicleId;
	}
	public void setVehicleId(int vehicleId) {
		VehicleId = vehicleId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
}

TwoWheelers.java

@Entity
@DiscriminatorValue("Bike")
public class TwoWheelers extends Vehicles{
	private String steeringHolder;

	public String getSteeringHolder() {
		return steeringHolder;
	}

	public void setSteeringHolder(String steeringHolder) {
		this.steeringHolder = steeringHolder;
	}
}

FourWheelers.java

@Entity
@DiscriminatorValue("Car")
public class FourWheelers extends Vehicles{
	
	private String steeringWheel;

	public String getSteeringWheel() {
		return steeringWheel;
	}

	public void setSteeringWheel(String steeringWheel) {
		this.steeringWheel = steeringWheel;
	}
	
}

By Using the below annotation individual tables would be created for all the subclasses instead of placing all the values getting placed in a single class.

InheritanceType.TABLE_PER_CLASS

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

InheritanceType.JOINED

@Inheritance(strategy=InheritanceType.JOINED)

Using InheritanceType.JOINED gets more normalized table compared to InheritanceType.TABLE_PER_CLASS

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;