Primary cache in Hibernate

Let us understand Primary cache in Hibernate


Primary cache is associated with Session and its enabled by default.

So we don’t need to configure anything to enable the Primary cache in our application.

Since it is associated with Session, primary cache will be available as long as hibernate session is alive.

Once the session is closed, all the objects in the cache will be lost.

Important points about Primary cache

Primary cache is always associated with “Hibernate Session

Primary cache is enabled by default and we don’t need to do any additional settings to enable it.

Primary cache can not be disabled but can be cleared.

When we query for an entity , first time it loads from database and it will keep it in the First level cache associated with the Session.

If we request the same entity using same session again , then it will be loaded from cache and no database call will be made.

If we want to remove a specific entity from primary cache , we can use evict() method.

If we want to remove all the objects stored in the primary cache, then we can use clear() method.

Lets see the complete project on this

Step 1

Create hibernate project

Please refer Hibernate setup in eclipse article on how to do it.

Project structure

primary_cache_proj_structure

Step 2

Update pom.xml with required dependnecies

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>HibernatePrimaryCache</groupId>
  <artifactId>HibernatePrimaryCache</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>HibernatePrimaryCache</name>
  <url>http://maven.apache.org</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.6.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.5</version>
        </dependency>
  </dependencies>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>HibernatePrimaryCache</groupId>
  <artifactId>HibernatePrimaryCache</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>HibernatePrimaryCache</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.2.6.Final</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>6.0.5</version>
		</dependency>
  </dependencies>
</project>

Step 3

Create the Employee class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.kb.model;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name="Employee")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "Employee_Id")
    private int employeeId;
    
    @Column(name = "FirstName")
    private String firstName;
    
    @Column(name = "LastName")
    private String lastName;
    
    @Column(name = "Age")
    private int age;
    
    @Column(name = "Education")
    private String education;
    
    @Column(name = "Salary")
    private int salary;
    
    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getEducation() {
        return education;
    }
    public void setEducation(String education) {
        this.education = education;
    }
    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
}
package com.kb.model;

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

@Entity
@Table(name="Employee")
public class Employee {
	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	@Column(name = "Employee_Id")
	private int employeeId;
	
	@Column(name = "FirstName")
	private String firstName;
	
	@Column(name = "LastName")
	private String lastName;
	
	@Column(name = "Age")
	private int age;
	
	@Column(name = "Education")
	private String education;
	
	@Column(name = "Salary")
	private int salary;
	
	public int getEmployeeId() {
		return employeeId;
	}
	public void setEmployeeId(int employeeId) {
		this.employeeId = employeeId;
	}
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getEducation() {
		return education;
	}
	public void setEducation(String education) {
		this.education = education;
	}
	public int getSalary() {
		return salary;
	}
	public void setSalary(int salary) {
		this.salary = salary;
	}
}

Step 4

Create hibernate.cfg.xml file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8"?>
<!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>
 
        <!-- Database connection properties -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/javainsimpleway</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
 
        <!-- JDBC connection pool (using the built-in) -->
        <property name="connection.pool_size">100</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>
 
        <!-- Format the generated Sql -->
        <property name="format_sql">true</property>
 
        <!-- Dont Drop and re-create the database schema on startup,Just update 
            it -->
        <property name="hbm2ddl.auto">update</property>
 
        <mapping class="com.kb.model.Employee" />
 
    </session-factory>
 
</hibernate-configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!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>

		<!-- Database connection properties -->
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="connection.url">jdbc:mysql://localhost/javainsimpleway</property>
		<property name="connection.username">root</property>
		<property name="connection.password">root</property>

		<!-- JDBC connection pool (using the built-in) -->
		<property name="connection.pool_size">100</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>

		<!-- Format the generated Sql -->
		<property name="format_sql">true</property>

		<!-- Dont Drop and re-create the database schema on startup,Just update 
			it -->
		<property name="hbm2ddl.auto">update</property>

		<mapping class="com.kb.model.Employee" />

	</session-factory>

</hibernate-configuration>

Step 5

Create hibernate utility class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.kb.util;
 
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
 
public class HibernateUtil {
    private static final SessionFactory sessionFactory = buildSessionFactory();
 
    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception to track it
            System.err.println("SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
 
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    
    public static void shutdown() {
        // Optional but can be used to Close caches and connection pools
        getSessionFactory().close();
    }
 
}
package com.kb.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception to track it
            System.err.println("SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    
    public static void shutdown() {
    	// Optional but can be used to Close caches and connection pools
    	getSessionFactory().close();
    }

}

Step 6

Populate the data in DB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.kb.db;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
 
import com.kb.model.Employee;
import com.kb.util.HibernateUtil;
 
public class PopulateData {
public static void main(String[] args) {
 
    // Get session factory using Hibernate Util class
    SessionFactory sf = HibernateUtil.getSessionFactory();
    // Get session from Sesson factory
    Session session = sf.openSession();
 
    // Begin transaction
    Transaction t = session.beginTransaction();
    
    //Create Employee  data
    Employee employee1 = new Employee();
    employee1.setFirstName("John");
    employee1.setLastName("KC");
    employee1.setAge(28);
    employee1.setEducation("PG");
    employee1.setSalary(25000);
    
    Employee employee2 = new Employee();
    employee2.setFirstName("Jacob");
    employee2.setLastName("JC");
    employee2.setAge(30);
    employee2.setEducation("PG");
    employee2.setSalary(30000);
    
    Employee employee3 = new Employee();
    employee3.setFirstName("Martin");
    employee3.setLastName("A");
    employee3.setAge(24);
    employee3.setEducation("UG");
    employee3.setSalary(20000);
    
    Employee employee4 = new Employee();
    employee4.setFirstName("Peter");
    employee4.setLastName("M");
    employee4.setAge(25);
    employee4.setEducation("UG");
    employee4.setSalary(22000);
    
    Employee employee5 = new Employee();
    employee5.setFirstName("Roshan");
    employee5.setLastName("B");
    employee5.setAge(29);
    employee5.setEducation("PG");
    employee5.setSalary(45000);
    
    
    session.save(employee1);
    session.save(employee2);
    session.save(employee3);
    session.save(employee4);
    session.save(employee5);
 
    // Commit the transaction and close the session
    t.commit();
    
    session.close();
    System.out.println("successfully persisted Employee details");
 
  }
}
package com.kb.db;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.kb.model.Employee;
import com.kb.util.HibernateUtil;

public class PopulateData {
public static void main(String[] args) {

	// Get session factory using Hibernate Util class
	SessionFactory sf = HibernateUtil.getSessionFactory();
	// Get session from Sesson factory
	Session session = sf.openSession();

	// Begin transaction
	Transaction t = session.beginTransaction();
	
	//Create Employee  data
	Employee employee1 = new Employee();
	employee1.setFirstName("John");
	employee1.setLastName("KC");
	employee1.setAge(28);
	employee1.setEducation("PG");
	employee1.setSalary(25000);
	
	Employee employee2 = new Employee();
	employee2.setFirstName("Jacob");
	employee2.setLastName("JC");
	employee2.setAge(30);
	employee2.setEducation("PG");
	employee2.setSalary(30000);
	
	Employee employee3 = new Employee();
	employee3.setFirstName("Martin");
	employee3.setLastName("A");
	employee3.setAge(24);
	employee3.setEducation("UG");
	employee3.setSalary(20000);
	
	Employee employee4 = new Employee();
	employee4.setFirstName("Peter");
	employee4.setLastName("M");
	employee4.setAge(25);
	employee4.setEducation("UG");
	employee4.setSalary(22000);
	
	Employee employee5 = new Employee();
	employee5.setFirstName("Roshan");
	employee5.setLastName("B");
	employee5.setAge(29);
	employee5.setEducation("PG");
	employee5.setSalary(45000);
	
	
	session.save(employee1);
	session.save(employee2);
	session.save(employee3);
	session.save(employee4);
	session.save(employee5);

	// Commit the transaction and close the session
	t.commit();
	
	session.close();
	System.out.println("successfully persisted Employee details");

  }
}

Step 7

Check the output and queries executed

primary_cache_data_populate

Step 8

Create test class for loading object within same session

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.kb.db;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
 
import com.kb.model.Employee;
import com.kb.util.HibernateUtil;
 
public class PrimaryCacheWithinSameSession {
    public static void main(String[] args) {
        // Get session factory using Hibernate Util class
        SessionFactory sf = HibernateUtil.getSessionFactory();
        // Get session from Session factory
        Session session = sf.openSession();
        
        //Load the Employee details whose Id is 1
        Employee employee = (Employee) session.load(Employee.class, new Integer(1));
        displayEmployeeDetails(employee);
        
        //Load the same Employee again within the same Session
        employee = (Employee) session.load(Employee.class, new Integer(1));
        displayEmployeeDetails(employee);
        session.close();
    }
 
    private static void displayEmployeeDetails(Employee employee) {
        System.out.println(
                "ID: " + employee.getEmployeeId() + " Age: " + employee.getAge() + " Salary: " + employee.getSalary());
    }
 
}
package com.kb.db;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.kb.model.Employee;
import com.kb.util.HibernateUtil;

public class PrimaryCacheWithinSameSession {
	public static void main(String[] args) {
		// Get session factory using Hibernate Util class
		SessionFactory sf = HibernateUtil.getSessionFactory();
		// Get session from Session factory
		Session session = sf.openSession();
		
		//Load the Employee details whose Id is 1
		Employee employee = (Employee) session.load(Employee.class, new Integer(1));
		displayEmployeeDetails(employee);
		
		//Load the same Employee again within the same Session
		employee = (Employee) session.load(Employee.class, new Integer(1));
		displayEmployeeDetails(employee);
		session.close();
	}

	private static void displayEmployeeDetails(Employee employee) {
		System.out.println(
				"ID: " + employee.getEmployeeId() + " Age: " + employee.getAge() + " Salary: " + employee.getSalary());
	}

}

Step 9

Check the output and queries executed

primary_cache_same_session_output

We can observe in the output that query is executed only once as same enity is loaded using same session and hence it is loaded from primary cache.

Step 10

Create test class for loading object with new session

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.kb.db;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
 
import com.kb.model.Employee;
import com.kb.util.HibernateUtil;
 
public class PrimaryCacheWithNewSession {
    @SuppressWarnings("deprecation")
    public static void main(String[] args) {
        
        // Get session factory using Hibernate Util class
        SessionFactory sf = HibernateUtil.getSessionFactory();
        
        // Get session from Session factory
        Session session1 = sf.openSession();
 
        // Load the Employee details whose Id is 1
        Employee employee = (Employee) session1.load(Employee.class, new Integer(1));
        displayEmployeeDetails(employee);
 
        //Create a new Session
        Session session2 = sf.openSession();
        // Load the same Employee again with new Session
        employee = (Employee) session2.load(Employee.class, new Integer(1));
        displayEmployeeDetails(employee);
        session1.close();
        session2.close();
    }
    private static void displayEmployeeDetails(Employee employee) {
        System.out.println(
                "ID: " + employee.getEmployeeId() + " Age: " + employee.getAge() + " Salary: " + employee.getSalary());
    }
 
}
package com.kb.db;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.kb.model.Employee;
import com.kb.util.HibernateUtil;

public class PrimaryCacheWithNewSession {
	@SuppressWarnings("deprecation")
	public static void main(String[] args) {
		
		// Get session factory using Hibernate Util class
		SessionFactory sf = HibernateUtil.getSessionFactory();
		
		// Get session from Session factory
		Session session1 = sf.openSession();

		// Load the Employee details whose Id is 1
		Employee employee = (Employee) session1.load(Employee.class, new Integer(1));
		displayEmployeeDetails(employee);

		//Create a new Session
		Session session2 = sf.openSession();
		// Load the same Employee again with new Session
		employee = (Employee) session2.load(Employee.class, new Integer(1));
		displayEmployeeDetails(employee);
		session1.close();
		session2.close();
	}
	private static void displayEmployeeDetails(Employee employee) {
		System.out.println(
				"ID: " + employee.getEmployeeId() + " Age: " + employee.getAge() + " Salary: " + employee.getSalary());
	}

}

Step 11

Check the output and queries executed

primary_cache_new_session_output

We can observe in the output that,same query is executed twice for the same entity as it is loaded using different session.

Step 12

Create test class for clearing session cache and evict() methods

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.kb.db;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
 
import com.kb.model.Employee;
import com.kb.util.HibernateUtil;
 
public class PrimaryCacheEvict {
    public static void main(String[] args) {
        // Get session factory using Hibernate Util class
        SessionFactory sf = HibernateUtil.getSessionFactory();
        // Get session from Session factory
        Session session = sf.openSession();
 
        // Load the Employee details whose Id is 1
        Employee employee = (Employee) session.load(Employee.class, new Integer(1));
        displayEmployeeDetails(employee);
 
        session.evict(employee);
        
        // Load the same Employee again within the same Session but after evict
        employee = (Employee) session.load(Employee.class, new Integer(1));
        displayEmployeeDetails(employee);
 
        
 
        // Load the Employee details whose Id is 2
        Employee employee1 = (Employee) session.load(Employee.class, new Integer(2));
        displayEmployeeDetails(employee1);
 
        // Load the Employee details whose Id is 3
        Employee employee2 = (Employee) session.load(Employee.class, new Integer(3));
        displayEmployeeDetails(employee2);
 
        session.clear();
 
        //Load the employees after clearing the primary cache
        
        // Load the Employee details whose Id is 2
        employee1 = (Employee) session.load(Employee.class, new Integer(2));
        displayEmployeeDetails(employee);
 
        // Load the Employee details whose Id is 3
        employee2 = (Employee) session.load(Employee.class, new Integer(3));
        displayEmployeeDetails(employee2);
 
        session.close();
    }
 
    private static void displayEmployeeDetails(Employee employee) {
        System.out.println(
                "ID: " + employee.getEmployeeId() + " Age: " + employee.getAge() + " Salary: " + employee.getSalary());
    }
 
}
package com.kb.db;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.kb.model.Employee;
import com.kb.util.HibernateUtil;

public class PrimaryCacheEvict {
	public static void main(String[] args) {
		// Get session factory using Hibernate Util class
		SessionFactory sf = HibernateUtil.getSessionFactory();
		// Get session from Session factory
		Session session = sf.openSession();

		// Load the Employee details whose Id is 1
		Employee employee = (Employee) session.load(Employee.class, new Integer(1));
		displayEmployeeDetails(employee);

		session.evict(employee);
		
		// Load the same Employee again within the same Session but after evict
		employee = (Employee) session.load(Employee.class, new Integer(1));
		displayEmployeeDetails(employee);

		

		// Load the Employee details whose Id is 2
		Employee employee1 = (Employee) session.load(Employee.class, new Integer(2));
		displayEmployeeDetails(employee1);

		// Load the Employee details whose Id is 3
		Employee employee2 = (Employee) session.load(Employee.class, new Integer(3));
		displayEmployeeDetails(employee2);

		session.clear();

		//Load the employees after clearing the primary cache
		
		// Load the Employee details whose Id is 2
		employee1 = (Employee) session.load(Employee.class, new Integer(2));
		displayEmployeeDetails(employee);

		// Load the Employee details whose Id is 3
		employee2 = (Employee) session.load(Employee.class, new Integer(3));
		displayEmployeeDetails(employee2);

		session.close();
	}

	private static void displayEmployeeDetails(Employee employee) {
		System.out.println(
				"ID: " + employee.getEmployeeId() + " Age: " + employee.getAge() + " Salary: " + employee.getSalary());
	}

}

Step 13

Check the output and queries executed

primary_cache_evict1
primary_cache_evict2
primary_cache_evict3

We can observe in the output that, after evict() and clear() method execution ,cache is getting cleared and hence queries are executed to get the data from DB.


Download this project HibernatePrimaryCache.zip

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on