MyArchiBook

Archive for the ‘JPA’ Category

Spring + JPA – Example with Exception/Error – Fixing

with 7 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 🙂