Tuesday, February 21, 2012

Hibernate Vs JPA

 i found a very good article that describes about JPA vs Hibernate. i decided to re-post that article in my blog for to improve the availability of the article. (even if the original source is not available, you can refer the article through my blog.)


JPA vs Hibernate 


Almost all of enterprise applications are required to access relational databases regularly. But a problem faced with earlier technologies (such as JDBC) was the impedance mismatch (difference between object-oriented and relational technologies). A solution for this problem was introduced through the introduction of an abstract layer called Persistence layer, which encapsulates database access from the business logic. JPA (Java Persistence API) is a framework dedicated for the management of relational data (using the persistence layer) in Java applications. There are many vendor implementations of JPA used within the Java developer community. Hibernate is the most popular such implementation of JPA (DataNucleus, EclipseLink and OpenJPA are some others). The newest JPA version (JPA 2.0) is fully supported by Hibernate 3.5, which was released in March, 2010.

What is JPA?

JPA is a framework for managing relational data for Java. It can be used with applications utilizing JSE (Java Platform, Standard Edition) or JEE (Java Platform, Enterprise Edition). Its current version is JPA 2.0, which was released on 10 Dec, 2009. JPA replaced EJB 2.0 and EJB 1.1 entity beans (which were heavily criticized for being heavyweight by the Java developer community). Although entity beans (in EJB) provided persistence objects, many developers were used to utilizing relatively lightweight objects offered by DAO (Data Access Objects) and other similar frameworks instead. As a result, JPA was introduced, and it captured many of the neat features of the frameworks mentioned above.
Persistence as described in JPA covers the API (defined in javax.persistence), JPQL (Java Platform, Enterprise Edition) and metadata required for relational objects. State of a persistence entity is typically persisted in to a table. Instances of an entity correspond to rows of the table of the relational database. Metadata is used to express the relationships between entities. Annotations or separate XML descriptor files (deployed with the application) are used to specify metadata in entity classes. JPQL, which is similar to SQL queries, are used to query stored entities.

What is Hibernate?

Hibernate is a framework that can be used for object-relational mapping intended for Java programming language. More specifically, it is an ORM (object-relational mapping) library that can be used to map object-relational model in to conventional relational model. In simple terms, it creates a mapping between Java classes and tables in relational databases, also between Java to SQL data types. Hibernate can also be used for data querying and retrieving by generating SQL calls. Therefore, the programmer is relieved from the manual handling of result sets and converting objects. Hibernate is released as a free and open source framework distributed under GNU license. An implementation for JPA API is provided in Hibernate 3.2 and later versions. Gavin King is the founder of Hibernate.

What is the difference between JPA and Hibernate?

JPA is a framework for managing relational data in Java applications, while Hibernate is a specific implementation of JPA (so ideally, JPA and Hibernate cannot be directly compared). In other words, Hibernate is one of the most popular frameworks that implements JPA. Hibernate implements JPA through Hibernate Annotation and EntityManager libraries that are implemented on top of Hibernate Core libraries. Both EntityManager and Annotations follow the lifecycle of Hibernate. The newest JPA version (JPA 2.0) is fully supported by Hibernate 3.5. JPA has the benefit of having an interface that is standardized, so the developer community will be more familiar with it than Hibernate. On the other hand, native Hibernate APIs can be considered more powerful because its features are a superset of that of JPA.

source :- http://www.differencebetween.com/difference-between-jpa-and-vs-hibernate/

Thanks and Credits should go to the Original Author who compose this valuable article.

cheers!!!
Chathuranga Tennakoon
chathuranga.t@gmail.com

Monday, February 20, 2012

Spring Security - User Authentication with UserDetailService

http://stackoverflow.com/questions/4489703/how-to-use-spring-security-with-jpa

Create your own HTTP 403 Access Denied Page in Spring Security

http://www.mkyong.com/spring-security/customize-http-403-access-denied-page-in-spring-security/

http://krams915.blogspot.com/2010/12/spring-security-mvc-integration_18.html

Friday, February 17, 2012

Many to Many mapping in JPA annotations

ER diagram
------





Student.java
package org.convey.user.registration.model;

import javax.persistence.*;
import java.util.List;

/**
 * Name: Chathuranga Tennakoon
 * Mobile: 0094759610139
 * Blog: chathurangat.blogspot.com
 * Email: chathuranga.t@gmail.com
 */
@Entity
@Table(name="student")
public class Student {

    @Id
    @GeneratedValue
    @Column(name = "student_id")
    private int studentId;

    @Column(name="student_name")
    private String studentName;

    @Column(name="student_address")
    private String studentAddress;

    @Column(name="version")
    private long version;

    @ManyToMany
    @JoinTable(
            name="student_course",
            joinColumns = {@JoinColumn(name = "studentID",referencedColumnName = "student_id")},
            inverseJoinColumns = {@JoinColumn(name = "courseID", referencedColumnName = "course_id")})
    private List courses;


    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getStudentAddress() {
        return studentAddress;
    }

    public void setStudentAddress(String studentAddress) {
        this.studentAddress = studentAddress;
    }

    public long getVersion() {
        return version;
    }

    public void setVersion(long version) {
        this.version = version;
    }

    public List getCourses() {
        return courses;
    }

    public void setCourses(List courses) {
        this.courses = courses;
    }
}



Course.java

package org.convey.user.registration.model;

import javax.persistence.*;
import java.util.List;

/**
 * Name: Chathuranga Tennakoon
 * Mobile: 0094759610139
 * Blog: chathurangat.blogspot.com
 * Email: chathuranga.t@gmail.com
 */
@Entity
@Table(name="course")
public class Course {

    @Id
    @GeneratedValue
    @Column(name="course_id")
    private int courseId;

    @Column(name="course_name")
    private String courseName;


    @Column(name="course_description")
    private String courseDescription;

    @Column(name="version")
    private long version;

    @ManyToMany
    @JoinTable(
            name="student_course",
            joinColumns = {@JoinColumn(name = "courseID",referencedColumnName = "course_id")},
            inverseJoinColumns = {@JoinColumn(name = "studentID", referencedColumnName = "student_id")})
    private List<Student>  students;


    public int getCourseId() {
        return courseId;
    }

    public void setCourseId(int courseId) {
        this.courseId = courseId;
    }

    public String getCourseName() {
        return courseName;
    }

    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }

    public String getCourseDescription() {
        return courseDescription;
    }

    public void setCourseDescription(String courseDescription) {
        this.courseDescription = courseDescription;
    }

    public long getVersion() {
        return version;
    }

    public void setVersion(long version) {
        this.version = version;
    }

    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }

}//course


  • Student can register for many courses.
  • A given course has many registered students
therefore many to many relationship exists between these two entities.therefore @ManyToMany Annotation is used to map the relationship between these two entities.

@JoinTable annotation is declared in the POJO class that owns the relationship. since this is many to many relationship, both class own the relationship. therefore @JoinTable annoatation is declared in the both classes. (therefore referential integrity constraint will be accurately maintained)

hope this will helpful for you!

 

Thursday, February 16, 2012

persist() vs merge() in Hibernate JPA

http://blog.xebia.com/2009/03/23/jpa-implementation-patterns-saving-detached-entities/

http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge

Wednesday, February 15, 2012

JasperReport with Spring MVC (fully working example with source code and explanation)

Today i am going to discuss how to integrate  jasper report with Spring MVC. i will be using following sample Spring MVC Application to show how the spring mvc and jasper report is integrated. you can download this application through following URL or GitHub repository.

https://github.com/chathurangat/spring-mvc-jpa-example

or

4shared URL

once you download the project, load it with your preferable development IDE. i have use Intelli J IDEA. the project structure is shown in the below screen shot.



the jasper report will be designed to display a list of Users who are already in the database(in User Table). this User table has been mapped to the User.java model that is available inside the org.convey.user.registration.model package. you can see the source code of the User.java model as follows.

User.java

package org.convey.user.registration.model;

import javax.persistence.*;
import java.util.Date;
import java.util.List;


@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private int id;

    @Column(name = "username" , nullable = false , unique = true)
    private String userName;

    @Column(name = "password" , nullable = false)
    private String passWord;

    @Column(name = "email" , nullable = false , unique = true)
    private String email;

    @Column(name = "confirmation_code",length = 20)
    private String confirmationCode;

    @Column(name = "first_name" , length = 50,nullable = false)
    private String firstName;

    @Column(name = "last_name" , length = 50)
    private String lastName;

    @Column(name = "register_date")
    private Date registeredDate;

    @Column(name = "activate_status")
    private boolean  activate;

    @Version
    private int version;

    @ManyToMany
    @JoinTable(name ="user_module",
            joinColumns = {@JoinColumn(name = "userID", referencedColumnName = "user_id")},
            inverseJoinColumns = {@JoinColumn(name = "moduleID", referencedColumnName ="module_id")})
    private List<Module> modules;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getConfirmationCode() {
        return confirmationCode;
    }

    public void setConfirmationCode(String confirmationCode) {
        this.confirmationCode = confirmationCode;
    }

    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 Date getRegisteredDate() {
        return registeredDate;
    }

    public void setRegisteredDate(Date registeredDate) {
        this.registeredDate = registeredDate;
    }

    public boolean isActivate() {
        return activate;
    }

    public void setActivate(boolean activate) {
        this.activate = activate;
    }


    public List<Module> getModules() {
        return modules;
    }

    public void setModules(List<Module> modules) {
        this.modules = modules;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

}//User




now it is the time to design the report using iReport. you can follow the below instructions to design your jasper report with iReport designer.

  • run the iReport tool. then File->New . then you will get the following set of available jasper report templates


  • In my case i have selected the Blank A4 report template. once you select the required report template, click Open this Template button to open the template.then you will get the following window.


then give a name for the report and select a location where the jrxml file should be saved.then click Next . after finishing all required operations you can see the selected template is loaded and ready o start the designing. please see the below.




if the palette is not automatically loaded in your designer, you can load it manually(window->palette)


you will see an another window called Report Inspector. you can add  the required fields for the report through this window. this can be done as follows.


right click on the Fields and select Add new Field Option.then you can see that newly added field is available under the Fields. you can change its attributes (name,type etc...) through the properties window. (Add up to four new fields)

Important:

when naming the fields, please make sure to name each field that is exactly same as the attribute name. In addition the data type (Field class) should also be same as the data type of identical attribute in the class. for more details, please see the below window. (we are going to design the report based on only the four attributes of the User class. therefore we need to create only four fields for the report). make sure to change the necessary properties of the newly added fields to reflect the below values.

attribute name(User class)     Field Name      Data Type(User class)     Field Class
 id                                              id                    int                                      Integer
 userName                                userName       String                                 String
 email                                        email               String                                 String
 firstName                                firstName        String                                 String


you can see that both attribute names and field names are identical. in addition there data types are also identical.now i assume that you have added new fields and changed their names and data types to meet above requirements. you can see all newly added fields as follows.



now you have loaded required components for your report design. now you can start  the design of your report. i will show you how to added newly created fields for your report.


drag and drop the newly added fields to the Detail 1 section of your report. please refer the below screen shot.



you can preview the design with the preview button.

now it is the time to start the jasper report integration with the spring mvc web application.suppose you have already downloaded the sample application given above for proceeding with this tutorial. you need to place the created jrxml file  in the class path. (in my case chathuranga-test-report.jrxml ).

 the jrxml file should be placed in the spring-mvc-jpa-jasper-report-example/src/main/resources location of the above downloaded project.

 then follow the instructions given below.

1. add the following maven dependencies to the pom.xml file.


<dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>3.7.6</version>
            <type>jar</type>
            <scope>compile</scope>           
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.6</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.lowagie</groupId>
            <artifactId>itext</artifactId>
            <version>2.1.7</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>

        <dependency>
            <groupId>commons-digester</groupId>
            <artifactId>commons-digester</artifactId>
            <version>2.1</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>1.7.0</version>
        </dependency> 
 
 
2. add the following Report controller to your controller package.
(available in spring-mvc-jpa-jasper-report-example/src/main/java/org/convey/user/registration/controller )

ReportController.java

package org.convey.user.registration.controller;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.convey.user.registration.dao.UserDao;
import org.convey.user.registration.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;



@Controller
@RequestMapping("/report/")
public class ReportController {


    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    UserDao userDao;

    @RequestMapping(method = RequestMethod.GET , value = "pdf")
    public ModelAndView generatePdfReport(ModelAndView modelAndView){

        logger.debug("--------------generate PDF report----------");

        Map<String,Object> parameterMap = new HashMap<String,Object>();

        List<User> usersList = userDao.retrieveAllRegisteredUsers();

        JRDataSource JRdataSource = new JRBeanCollectionDataSource(usersList);

        parameterMap.put("datasource", JRdataSource);

        //pdfReport bean has ben declared in the jasper-views.xml file
        modelAndView = new ModelAndView("pdfReport", parameterMap);

        return modelAndView;

    }//generatePdfReport



    @RequestMapping(method = RequestMethod.GET , value = "xls")
    public ModelAndView generateXlsReport(ModelAndView modelAndView){

        logger.debug("--------------generate XLS report----------");

        Map<String,Object> parameterMap = new HashMap<String,Object>();

        List<User> usersList = userDao.retrieveAllRegisteredUsers();

        JRDataSource JRdataSource = new JRBeanCollectionDataSource(usersList);

        parameterMap.put("datasource", JRdataSource);

        //xlsReport bean has ben declared in the jasper-views.xml file
        modelAndView = new ModelAndView("xlsReport", parameterMap);

        return modelAndView;

    }//generatePdfReport


    @RequestMapping(method = RequestMethod.GET , value = "csv")
    public ModelAndView generateCsvReport(ModelAndView modelAndView){

        logger.debug("--------------generate CSV report----------");

        Map<String,Object> parameterMap = new HashMap<String,Object>();

        List<User> usersList = userDao.retrieveAllRegisteredUsers();

        JRDataSource JRdataSource = new JRBeanCollectionDataSource(usersList);

        parameterMap.put("datasource", JRdataSource);

        //xlsReport bean has ben declared in the jasper-views.xml file
        modelAndView = new ModelAndView("csvReport", parameterMap);

        return modelAndView;

    }//generatePdfReport



    @RequestMapping(method = RequestMethod.GET , value = "html")
    public ModelAndView generateHtmlReport(ModelAndView modelAndView){

        logger.debug("--------------generate HTML report----------");

        Map<String,Object> parameterMap = new HashMap<String,Object>();

        List<User> usersList = userDao.retrieveAllRegisteredUsers();

        JRDataSource JRdataSource = new JRBeanCollectionDataSource(usersList);

        parameterMap.put("datasource", JRdataSource);

        //xlsReport bean has ben declared in the jasper-views.xml file
        modelAndView = new ModelAndView("htmlReport", parameterMap);

        return modelAndView;

    }//generatePdfReport


}//ReportController





3. add the following jasper-view.xml file to the same directory where the applicationContext.xml file contains. (in this example, it is should be placed under the spring-mvc-jpa-jasper-report-example/src/main/webapp/WEB-INF/spring/app directory.

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

     <!--here all the url value should contains the valid path for the jrxml file-->
    
    <bean id="pdfReport"
          class="org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView"
          p:url="classpath:chathuranga-sample-report.jrxml"
          p:reportDataKey="datasource" />


    <bean id="xlsReport"
          class="org.springframework.web.servlet.view.jasperreports.JasperReportsXlsView"
          p:url="classpath:chathuranga-sample-report.jrxml"
          p:reportDataKey="datasource" />


    <bean id="htmlReport"
          class="org.springframework.web.servlet.view.jasperreports.JasperReportsHtmlView"
          p:url="classpath:chathuranga-sample-report.jrxml"
          p:reportDataKey="datasource" />


    <bean id="csvReport"
          class="org.springframework.web.servlet.view.jasperreports.JasperReportsCsvView"
          p:url="classpath:chathuranga-sample-report.jrxml"
          p:reportDataKey="datasource"/>


</beans>

here all the url properties should contains the valid reference for a jrxml file that should be used as the report template.


4. then make the below XmlViewResolver bean declaration in your  applicationContext.xml file

    <beans:bean class="org.springframework.web.servlet.view.XmlViewResolver">
        <beans:property name="location" value="/WEB-INF/spring/app/jasper-views.xml"/>
        <beans:property name="order" value="0"/>
    </beans:bean>  

the value of location property should contains the reference for the xml file where the jasper view declarations are available.(in this case jasper-view.xml)


In addition, import the jasper-view.xml file to your applicationContext.xml file by placing the below import statement in your applicationContext.xml 


<beans:import resource="jasper-views.xml"/> 

Please make sure to change your database properties in the spring-mvc-jpa-jasper-report-example/src/main/resources/db.properties file.

then build your project with maven and deploy it in the tomcat server. then use following urls for getting the report you need.

PDF Report
 http://localhost:8080/common-user-registration/spring/report/pdf

XLS Report
 http://localhost:8080/common-user-registration/spring/report/xls

CSV Report
 http://localhost:8080/common-user-registration/spring/report/csv

HTML Report
 http://localhost:8080/common-user-registration/spring/report/html


you can download the fully example of this application through the  following git repository .

https://github.com/chathurangat/spring-mvc-jpa-jasper-report-example

Hope this will helpful for you !!!

Regards
Chathuranga Tennakoon
chathuranga.t@gmail.com