MyArchiBook

Posts Tagged ‘JPA

Spring + JPA – Example with Exception/Error – Fixing

with 8 comments

In this post ,I have given a  simple example on how to use JPA in Spring Framework.
You can find the source code of the below example in my Github link here.

I have considered a MusicStore example, where i just get the list of Songs from the database.

TOOLS USED:

Framework: Spring
Persistence API : JPA 2.0
Build : Maven
Database : MySQL
JPA Provider : Hibernate-JPA Provider

While I was working on integrating JPA into Spring , I felt that, the most important part to concentrate on , is the CONFIGURATION area.

So,let’s get started with application-context.xml and persistence.xml

app-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  xsi:schemaLocation="
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/jdbc
   http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">
   
 

<context:component-scan base-package="aish.vaishno.*" />    
 
<tx:annotation-driven transaction-manager="transactionManager"/>
 
<bean id="transactionManager"
  class="org.springframework.orm.jpa.JpaTransactionManager">
     <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

 <bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource" p:persistenceUnitName="simple-jpa">
 </bean>
 
 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/MUSIC_STORE"/>
        <property name="username" value="music_store"/>
        <property name="password" value="music_store"/>  
    </bean>
    
</beans>

  • DIFFERENCE BETWEEN <context:annotation-config> AND <context:component-scan base-package=”…..”>

<context:annotation-config> -Enables the usage of JPA annotations(@Service, @Component, @Repository, @Controller  and etc.,)
<context:component-scan base-package=”…..”> – This component-scan tag also enables the usage of JPA annotations.

Then the difference ???

(i) annotation-config —> enables the usage of JPA annotations , only in the beans specified in the context.xml whereas (ii) component-scan —> scans through all the packages specified, records all the  project beans having JPA annotations, into this context.xml. Therefore it enables JPA annotaion usage in (beans specified in context.xml)+(Project Beans).

Inshort, <component-scan> extends <annotation-config>.

When we use <component-scan> in the app-context.xml, it’s not necessary to use  <annotation-config> again.

Even if both  the tags are specified, it’s not a problem because, the spring container would take care of running the process only once.

  • <tx:annotation-driven transaction-manager=”transactionManger”/> – It checks for @Transactional annotation  in any of the classes. This tag is like a Transactional Switch that turns on the transactional behaviour.Here Transaction Manager is being injected .
  • <bean id=”transactionManager”>– Here Transaction Manager is setup.

Here EntityManagerFactory is being injected.

  • <bean id=”entityManagerFactory”>– Here EntityManagerFactory is setup .Data Source reference and Persistence UnitName Reference is specified.
  • <bean id=”dataSource”> – DB connection details are specified.
  • Persistence UnitName Reference – Based on the PersistenceUnit name, the corresponding portion of persistence.xml is accessed (a Project can have multiple persistenceUnitNames)

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="simple-jpa" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>aish.vaishno.musicstorespringjpa.pojo.MusicDetails</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> 
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.max_fetch_depth" value="3"/> 
    </properties>
  </persistence-unit>
</persistence>

Here in persistence.xml,

  • persistence-unitName is declared
  • provider – In this example, I have used Hibernate provider.
  • Entity Bean Class is specified
  • properties- Few settings(like showSQL=true) required are specified.

Configuration part is over. Now that, it’s time to use the annotations in our Dao class to make the Spring – JPA work.

POJO : MusicDetails.java

DaoInterface :

public interface IMusicStoreDao {
   public List getMusicList();
}

DaoImplementation :

@Service(value = "MusicCollections")
@Repository(value = "MusicCollections")
@Transactional
public class MusicStoreDaoImpl implements IMusicStoreDao{

  @PersistenceContext(unitName = "simple-jpa")
    private EntityManager entityManager;

   @Override
     public List getMusicList(){
     List musicDetailsList= entityManager.createQuery("select c from MusicDetails c").getResultList();
     return musicDetailsList;
    }
}

Executer:

public class Executer {
   public static void main(String[] args){
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("META-INF/app-context.xml");
        IMusicStoreDao musicStoreDao=(IMusicStoreDao) applicationContext.getBean("MusicCollections");
        System.out.println("MusicList: \n"+musicStoreDao.getMusicList());
    }
}

Now , when you run this main class, for sure , you would only get Errors and Exceptions :-P.
Because, we have not yet added the DEPENDENCY JARS.
Below , I have given a note on the Errors and Exceptions that would arise and the corresponding jars to be added to clear that particular problem.

You can find the Maven dependency tags for the below jars in my Github pom.xml

ERRORS/EXCEPTIONS AND THE CORRESPONDING JARS TO BE ADDED:

  • ERRORException in thread “main” java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/transaction/SystemException. 
  • JAR: javaee5-api.jar . Do not forget to specify the scope as “provided”, otherwise the error will still persist.
  • ERROR: Exception in thread “main” java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/persistence/EntityManager.
  • JAR: hibernate-jpa2-api.jar
  • EXCEPTION: ClassNotFoundException : org.hibernate.ejb.HibernatePersistence
  • JAR: hibernate-entitymanager.jar
  • ERROR: NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
  • JARS: slf4j-api.jar, slf4j-jcl-over.jar ( scope-RUNTIME ), slf4j-log4j12.jar ( scope-RUNTIME )
  • Do not forget to add the respective JDBC jar.

Now the program can be executed.

RESULT:

Result

Have a great day 🙂

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