MyArchiBook

Archive for the ‘Hibernate’ Category

(Spring – MVC+Hibernate –> Annotation based), MySql , Maven, JSON – Simple Example

with 20 comments

Hi! For the past few days, I have been trying out on Spring – MVC, Hibernate, Maven, MySql and JSON . So I thought, if I could blog about it today with a simple example.

In this post , I have used Hibernate to persist data in the back end  and JSON to display results in the front end.

You can get the below example’s complete source code from my GitHub link here —> https://github.com/AishwaryaThangavelu/Spring-Repository/tree/master/MusicStore.

Let’s take a look at it now.

INFORMATION:

  •  Tool used : NetBeans 7.3
  •  Framework : Spring-mvc-archetype – 3.X
  •  JPA: Hibernate
  •  Build : Maven 2.2
  •  Database Server : MySql
  •  WebApp Server :Tomcat 7

I have considered MusicStore example where I Add Songs and display a list of Songs.

OVERVIEW :

Flow

Flow of Application

STEPS:

1. TO CREATE A TABLE IN MySQL: 

  • Create DB – “CREATE DATABASE MUSIC_STORE;”
  • Create Table 
CREATE TABLE MUSIC_COLLECTIONS(
MC_ID INTEGER(50),
MC_LANGUAGE VARCHAR(50),
MC_TYPE VARCHAR(50),
MC_SONG_NAME VARCHAR(50)
);
  • To give Grant permission for accessing the Database- 

GRANT ALL PRIVILEGES ON MUSIC_STORE.* TO ‘music_store’@’localhost’ IDENTIFIED BY ‘music_store’;

Folder Structure

Folder Structure

2. CREATA A NEW SPRING-MVC PROJECT:

I have used Maven coupled Spring-mvc-archetype.

This Spring-mvc-archetype makes me too comfortable providing me the template as such.My duty is to just to work on the main coding part.

3.CREATE A POJO CLASS(Here MusicDetails.java):

@Entity
@Table(name = "MUSIC_COLLECTIONS")
public class MusicDetails implements Serializable {

 @Id
 @Column(name = "MC_ID")
 private Integer musicID;

@Column(name = "MC_LANGUAGE")
 private String musicLanguage;

 @Column(name = "MC_TYPE")
 private String musicType;

 @Column(name = "MC_SONG_NAME")
 private String songName;

public Integer getMusicID() {
 return musicID;
 }

public void setMusicID(Integer musicID) {
 this.musicID = musicID;
 }

public String getMusicLanguage() {
 return musicLanguage;
 }

public void setMusicLanguage(String musicLanguage) {
 this.musicLanguage = musicLanguage;
 }

public String getMusicType() {
 return musicType;
 }

public void setMusicType(String musicType) {
 this.musicType = musicType;
 }

public String getSongName() {
 return songName;
 }

public void setSongName(String songName) {
 this.songName = songName;
 }
}

Now let’s connect our applicationProject with the database.

4. CONFIGURATION:

Hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
                                         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory>
  <!-- Database connection settings -->
  <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="connection.url">jdbc:mysql://localhost:3306/MUSIC_STORE</property>
  <property name="connection.username">music_store</property>
  <property name="connection.password">music_store</property>
  <!-- JDBC connection pool (use the built-in) -->
  <!--<property name="connection.pool_size">20</property>-->
  <property name="hibernate.c3p0.acquire_increment">3</property>
<property name="hibernate.c3p0.idle_test_period">14400</property>
<property name="hibernate.c3p0.timeout">25200</property>
<property name="hibernate.c3p0.max_size">15</property>
<property name="hibernate.c3p0.min_size">3</property>
<property name="hibernate.c3p0.max_statements">0</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1;</property>
  <!-- SQL dialect -->
  <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
  <!-- Enable Hibernate's automatic session context management, in this case the session will be close after each transaction! -->
  <property name="current_session_context_class">thread</property>
  <!-- Disable the second-level cache -->
  <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
  <!-- Echo all executed SQL to stdout -->
  <property name="show_sql">true</property>
  <!-- auto create tables -->
  <property name="hbm2ddl.auto">update</property>
  <!-- Mappings -->
  <mapping class="aish.vaishno.musicstore.pojo.MusicDetails"/>
</session-factory>
</hibernate-configuration>
  • line 8 , connection with the particular DB with specific grant permitted username and password is specified
  • In line 31 POJO class maping is specified.

5.HIBERNATE SESSION MANAGER:

public class HibernateSessionManager {

 private static SessionFactory sessionFactory = buildSessionFactory();

 private static SessionFactory buildSessionFactory(){
 try{
   sessionFactory=new Configuration().configure("/hibernate.cfg.xml").buildSessionFactory();
   return sessionFactory;
 }
 catch(Throwable ex){
   System.err.println("Session Factory Initialization error"+ex);
   throw new ExceptionInInitializerError(ex);
  }
 }

 public static SessionFactory getSessionFactory() {
   return sessionFactory;
 }

 public static void shutdownConnection(){
   getSessionFactory().close();
 }
}

Specify mySql-connector-java.jar and javassist.jar dependency in pom.xml to establish connection with DB

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.15</version>
</dependency>

<dependency>
  <groupId>javassist</groupId>
  <artifactId>javassist</artifactId>
  <version>3.12.0.GA</version>
</dependency>

6.PERSISTENCE LAYER:

    • MusicStore DAO Interface creation:

Here I have created 2 methods as specified earlier,
 One method:  to add new songs
Second method: to get the List of Songs available

public interface IMusicStoreDao {

   public String addSong(MusicDetails musicDetails);
   public List getSongList();

}
  • Music Store Dao Implementation Class:

Here I have specified @Service inorder to inject it into Service Layer class.

@Service
public class MusicStoreDaoImpl implements IMusicStoreDao{

 @Override
 public String addSong(MusicDetails musicDetails) {
   SessionFactory sessionFactory= HibernateSessionManager.getSessionFactory();
   Session session=sessionFactory.openSession();
   Transaction transaction=session.beginTransaction();
   try{
     transaction.begin();
     session.save(musicDetails);
     session.flush();
     transaction.commit();
     return "Music Details has been entered";
   }catch(HibernateException hb){
     transaction.rollback();
     System.err.println("error"+hb);
     return "Sorry some problem has occured. Try Again";
   }finally{
     session.close();
   }
 }

 @Override
 public List getSongList() {
   SessionFactory sessionFactory=HibernateSessionManager.getSessionFactory();
   Session session=sessionFactory.getCurrentSession();
   Transaction transaction=session.beginTransaction();
   try{
     transaction.begin();
     List songList=session.createQuery("from MusicDetails").list();
     return songList;
   }finally{
     session.close();
   }
  }
 }

7.SERVICE LAYER:

  •     Service Layer Interface Creation :
public interface IMusicStoreService {
  public String addSong(MusicDetails musicDetails);
  public List getSongList();
}
  •    Music Service Implemetation Class Creation :

I have annotated this class with @Service because later , in the controller I will be Injecting this class.You can see that IMusicStoreDao is Autowired which means I have injected it in this class and that is why I specified @Service annotation in MusicStoreDao class.

@Service
public class MusicStoreServiceImpl implements IMusicStoreService{

 @Autowired
 private IMusicStoreDao musicStoreDao;

@Override
 public String addSong(MusicDetails musicDetails) {
   return musicStoreDao.addSong(musicDetails);
 }

@Override
 public List getSongList() {
    return musicStoreDao.getSongList();
 }
 }

I have also specified @ComponentScan in Configuration class to scan through the packages containing the respective classes with @Service annotation.

8.PRESENTATION LAYER:

Controller:

I have Autowired IMusicStoreService class

@Controller
public class HomeController {

@Autowired
 private IMusicStoreService musicStoreService;

 @RequestMapping(value="/")
 public ModelAndView test(HttpServletResponse response) throws IOException{
    return new ModelAndView("home","musicDetForm",new MusicDetails());
 }

 @RequestMapping(value="AddSong",method = RequestMethod.POST)
 @ResponseBody
 public String addSong(@ModelAttribute("musicDetForm") MusicDetails musicDetails){
    return musicStoreService.addSong(musicDetails);
 }

 @RequestMapping(value="SongList/",method = RequestMethod.GET)
 @ResponseBody
 public List<MusicDetails> getSongList(){
    return musicStoreService.getSongList();
 }
}

RUNTIME DEPENDENCY JAR’S TO BE ADDED:
Below are few runtime dependencies to be added in pom.xml to avoid Logging Factory and Load Class error.

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>jcl-over-slf4j</artifactId>
   <version>1.6.1</version>
   <scope>runtime</scope>
 </dependency>
 <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.1</version>
    <scope>runtime</scope>
 </dependency>
 <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.16</version>
    <scope>runtime</scope>
</dependency>

RESULTS:

1.ADD SONG :  I created the form using Simple-Spring Form Handling.You can find details about it in this link, refer to

https://aishwaryavaishno.wordpress.com/2013/06/22/simple-form-handling-and-performing-dependency-injection-in-spring-mvc-framework-using-netbeans/ 

and I have displayed the result .

AddSongResult

AddSongResult

MusicStoreForm

MusicStoreForm

2.SONG LIST DISPLAY :Here I have used JSON format to display result.
JSON:

  •   JSON(Java Script Object Notation) is a data transfer format,used for exchanging data between client and server-side application.
  • It is much like XML. No, actually it is easier than XML bcoz it is easy to understand, language independent and has parsers available for most of the languages(one eg: eval()).
  • It provides me the flexibility of writing just one application and runnning it on any type of application.

For this application, all that u need to know about JSON is, just

  • add the below Jackson Library dependency into the pom.xml
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.12</version>
</dependency>
 
  • Specify @ResponseBody JSON-REST Service.
  • Specify the Mapping properly in the Controller .

The “REST” JSON will take care.

Now when you hit the URL link, the JSON result will be as below for SongList.
SongList

That’s it.. 🙂

Hope it’s informative.. Have a great day !!!!

Advertisements

Written by thangaveluaishwarya

July 12, 2013 at 10:09 AM

Hibernate Persistence Context and Object’s LifeCycle

with 4 comments

A Software Industry mainly works on Enterprise Applications. When Persistence Frameworks are being used in the application, then it is better to know about the Persistence Context and Object’s Life Cycle, inorder to deal with the complexities.

BASICS:

  • Object Oriented Programming(OOP)  plays a major central role for developing any application. It is a design concept. It can be imagined as a Collection Of  Interacting Objects.
  • Relational Database Management System helps to store these entity objects into the Database objects(tables).
  • Object Relational Mapping (ORM) relates  objects from Object Oriented domain with relational Data model via mapping.

JPA

    Java Persistence API(JPA exists in JEE5 and higher ) is a specification which  has the features that will make the ORM work.It deals with , how Java Objects(“persistent entites”)are stored in the relational database, how they can be accessed and how the object’s state can be stored so that it can be  restored when the appication is restarted .

Hibernate 3.2,EJB 3 ,TopLink and etc., are frameworks that implement this JPA.

In this post I have briefed on Hibernate’s Persistence Context Pattern and the Object’s LifeCycle.

HIBERNATE PERSISTENCE CONTEXT PATTERN AND OBJECT’S LIFE CYCLE:

  • HIBERNATE is a Simple Persistence Framework . It is a flexible framework even.Flexible, because  it can be used even with or without an application server.
  • Hibernate provides functionality that persists objects of an object-oriented programming environment into some persistent store. These persisted objects are called Persistent Objects.
  • The place where the persistent objects are created,modified and retrieved is called the Persistence Context.
  • The three most importantly used classes of Hibernate’s Persistence API are,
  1. org.hibernate.SessionFactory
  2. org.hibernate.Session
  3. org.hibernate.Transaction

object-life-cycle

  • SessionFactory has the contract to create session instances for the application.Usually one data source has a single session factory instance. In an application, the threads servicing client requests, obtain Session Instances from this factory.
  • Session is THE Hibernate’s Persistence Context.The lifetime of a session is bound between the beginning and the end of a transaction.As said earlier, the persistent objects are created,modified and retrieved only in this session. While carrying out these operations on the objects, they might exist in one of these three states,
  1. transient state
  2. persistent state
  3. detached state
  • Transaction defines the UNIT OF WORK for an application.It is instantiated when Session.beginTransaction() is called.

Let’s get into examples to understand the Object’s life cycle with respect to Persistence Context.Here I have considered an example related to Company and its Chairman.

Attributes: Company Name and Chairman..

CASE 1:

public class CompanyDao {
	public void enterCompanyDetails(){
		Session session=HibernateSessionManager.getInstance().getHibernateSession();
		Transaction transaction=session.beginTransaction();
		try{
			transaction.begin();
			CompanyDetails companyDetails=new CompanyDetails();
			companyDetails.setCompanyName("Apple");
			companyDetails.setCompanyChairman("Steve Jobs");
			session.save(companyDetails);
            EmployeeDetails employeeDetails=new EmployeeDetails();
            employeeDetails.setNoOfEmployees(100000);
            transaction.commit();
		}catch (HibernateException e) {
			transaction.rollback();
		}finally{
			session.close();
		}
	}
}

Logic:SAVE —> COMMIT

  • Line 8 and 9 – the company name and chairman are set to the CompanyDetails object. Now this object’s instance which is a new one exists in the transient State.
  • Line 10- the object’s instance is being saved, which means it is being persisted in the Persistence Context. Now it is in the persistent state.
  • Line 11- a new employeeInstance is created.
  • Line 12- attribute is set to the instance. The instance now exists in the transient state.
  • When the transaction is committed, only the objects in the Persistence Context gets persisted in the Database as a record.i.e.,Here the persistent object companyDetails gets persisted but employeeDetails does not get persisted because it is in transient state.

Check out if you can answer this question ,

Qn.When you  Insert a data and update the same data in a session , will a new memory object be created in the Persistence Context or will it get Updated in the existing object in the Persistence Context…???

Ans: No, a new object is not created in Persistence Context while updating. Instead , the persistent object created when saving the object in the persistence context gets updated.

The answer is explained with an example below,

CASE 2:

public class CompanyDao {
	public void enterCompanyDetails(){
		Session session=HibernateSessionManager.getInstance().getHibernateSession();
		Transaction transaction=session.beginTransaction();
		try{
			transaction.begin();
			CompanyDetails companyDetails=new CompanyDetails();
			companyDetails.setCompanyName("Infosys");
			companyDetails.setCompanyChairman("K.V.Kamath");
			session.save(companyDetails);
			companyDetails.setCompanyChairman("Narayana Murthy");
			session.update(companyDetails);
            transaction.commit();
		}catch (HibernateException e) {
			transaction.rollback();
		}finally{
			session.close();
		}
	}
}

Logic: SAVE –> UPDATE –> COMMIT
TRUE 1

  • Line 8,9 – the attributes are set to the object.The object’s instance is in the transient state.
  • Line 10-The instance is saved. So , it moves to the Persistence Context and becomes a persistent object.
  • Line 11- the instance is again set.
  • Line 12- the instance is updated in the Persistence Context. I mean, already an object is created in the persistence context and that object gets modified/updated. New object is not created in the persistence context.
  • Line 13 – The persistent object is committed/persisted to the DB.

Note:Update() can be performed only on Persistent Objects and not on transient/detached objects whereas saveOrUpdate() automatically converts a transient/detached object to persistent object.

CASE 3:

public class CompanyDao {
	public void enterCompanyDetails(){
		Session session=HibernateSessionManager.getInstance().getHibernateSession();
		Transaction transaction=session.beginTransaction();
		try{
			transaction.begin();
			CompanyDetails companyDetails=new CompanyDetails();
			companyDetails.setCompanyName("Infosys");
			companyDetails.setCompanyChairman("K.V.Kamath");
			session.save(companyDetails);
			companyDetails.setCompanyChairman("Narayana Murthy");
			session.saveOrUpdate(companyDetails);
			session.clear();
			System.out.println("Company Details present : "+session.contains(companyDetails));
            transaction.commit();
		}catch (HibernateException e) {
			transaction.rollback();
		}finally{
			session.close();
		}
	}
}

Logic: SAVE –> UPDATE –> CLEAR –> COMMIT
false

Here in the above code,

  • Line 8,9 -Instance is set.It exists in the transient state.
  • Line 10 -Instance is saved to Persistence Context.It is in the persistent state now.
  • Line 11,12 – instance is set and updated in the Persistence Context
  • Line 13- All instances in the Persistance context are cleared. It has no instance in the context now. This means , the instance is in detached state now.

Like clear() there is also another method evict().The difference is ,evict() detaches a particular instance from the context but clear() detaches all the instances from the Persistence Context.
Hope this post has added an extra feather to your understanding.

Written by thangaveluaishwarya

June 7, 2013 at 9:56 PM