Hibernate JPA CRUD Operations

Hi friends,

Create, Read, Update and Delete are the four basic operations of persistence storage. We can say these operations collectively as an acronym CRUD. Here we are going to see how these operations are implemented in JPA. Here we can see the Hibernate implementation of JPA API.

What is JPA ?

  • JPA is a JAVA API Specification.
  • It’s an Entity persistence model for EJB 3.0.
  • It’s a POJO based framework for Java Persistence.
  • It Manages Relational Data in JAVA applications.

Benefits of JPA

JPA provides complete ORM solution for J2SE and J2EE applications. It’s easy to use, no need to implement any framework interfaces or classes. It facilitates test driven development and It’s annotation driven.

The major benefits of JPA are given below.

  • JDBC was a low level API, It is simple, but error prone.
  • JPA leverages best ideas from ORM community.
  • Developers can choose between different implementations.
  • Vendor Independence.

JPA Architecture

jpa_architecture

JPA Vendors

These are the major JPA vendors.

jpa_vendors

What is an ORM ?

ORM stands for Object Relational Mapping. It converts data between incompatible type systems in object-oriented programming languages. It creates a “virtual object DB“. It makes RDBMS looks like ODBMS.

orm

What is Hibernate ?

  • It’s a well known ORM tool.
  • It’s the most popular JPA API implementation.
  • It maps the Relational Model in the database to the Object Model in Java.

Hibernate Architecture

hibernate_architecture

CRUD Operations in JPA

These are the four methods used for CRUD operations in JPA API.

  • Persist()
  • Find()
  • Merge()
  • Remove()

Okay, now let’s move on to the example

log4j.properties

log4j.rootLogger = INFO, FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=C://log.out
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=#[%d{dd/MMM/yyyy HH:mm:ss}] - File[%F] - Method[%M] - Line[%L] - Priority[%p] - Message[%m]%n

Crud.java

package com.ddkr.jpahibernate.biz;

import com.ddkr.jpahibernate.entity.Employee;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Crud {

private EntityManagerFactory emf = null;
private EntityManager em = null;

public static void main(String[] args) throws Exception {
try {
Crud.class.newInstance().create();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
}

public Crud() {
try {
emf = Persistence.createEntityManagerFactory("JPA-Hibernate-PU");
em = emf.createEntityManager();
} catch (Exception e) {
System.out.println(e.getCause());
}
}

private void create() throws Exception {
try {
em.getTransaction().begin();
Employee employee = new Employee("Angelina", "Jolie", 'F', 39);
em.persist(employee);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
System.out.println(e.getLocalizedMessage());
throw new Exception(e);
} finally {
em.close();
}
}

private void read() throws Exception {
try {
em.getTransaction().begin();
Object empObj = em.find(Employee.class, 1L);
System.out.println(empObj);
em.getTransaction().commit();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
throw new Exception(e);
} finally {
em.close();
}
}

private void update() throws Exception {
try {
em.getTransaction().begin();
Employee employee = em.find(Employee.class, 1L);
employee.setFirstName("Jennifer");
employee.setLastName("Lawrence");
employee.setAge(23);
em.merge(employee);
em.getTransaction().commit();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
throw new Exception(e);
} finally {
em.flush();
em.close();
}
}

private void delete() throws Exception {
try {
em.getTransaction().begin();
Employee employee = em.find(Employee.class, 1L);
em.remove(employee);
em.getTransaction().commit();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
throw new Exception(e);
} finally {
em.flush();
em.close();
}
}
}

Journey through JPA

Hi friends,

Here you can have a look into the concise explanation of JPA implemented by the prominent Hibernate. These are the slides from one of the presentations having presented by me in my previous company.

WHAT ?

Slide2

BENEFITS ?

Slide3

GOALS ?

Slide4

REQUIREMENTS ?

Slide5

ANNOTATIONS

Slide6

Slide7

Slide8

Slide9

Slide10

Slide11

Slide12

ARCHITECTURE

Slide13

RELEVANT CLASSES

Slide14

Slide15

Slide16

Slide17

LIFE CYCLE

Slide18

VENDORS

Slide19

WHAT IS ORM ?

Slide20

WHAT IS HIBERNATE ?

Slide21

Here, you can see all the hibernate related posts.

HIBERNATE ARCHITECTURE

Slide22

JPA AND HIBERNATE

Slide23

JPA CRUD OPERATIONS

Slide24

JPA QUERIES

Slide25

Slide26

ASSOCIATION

Slide27

Slide28

DEMERITS

Slide29

 

You can also download the original presentation from here.

Thank you.

Struts 2 – Spring Security – Hibernate Custom Form Example

Hi All,

In the previous post, we have seen how to set up the Spring Security with Struts2 forms. In this example we are going to see how to integrate Hibernate framework with Spring Security. Let’s move on to the example.

BEHIND THE SCENE

  • NetBeans IDE 7.1.1
  • Spring-Core-3.2.1.RELEASE
  • Spring-Security-3.2.1.RELEASE
  • Struts-core-2.3.15.3
  • Hibernate 3
  • JDK 1.7
  • Apache Tomcat 7.0.22.0
  • Microsoft SQL Server 2012

IMPLEMENTATION STEPS

Here are the steps to be followed for implementing spring security in our application.

1. web.xml

Here, we have to enable spring support for our application by adding a listener in the deployment descriptor. Also we have added spring security filter and struts2 filter.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
       
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-database.xml
            /WEB-INF/spring-security.xml
        </param-value>
    </context-param>
       
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
        
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>/redirect.jsp</welcome-file>
    </welcome-file-list>
</web-app>

2. spring-database.xml

It depicts the custom user service. We represent our custom user service as a spring bean with an id “userDetailsService”. Spring creates an instance of this bean in the spring context when the application initializes. Please note that the file has been added to web.xml (line no. 7).


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
    <bean id="userDetailsService" class="com.ssh.service.UserService"/>
   
</beans>    

3. spring-security.xml

It describes the custom login form, “daoAuthenticationProvider” and “authenticationManager”. This file has also been added to web.xml (line no. 8).


<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/security
	http://www.springframework.org/schema/security/spring-security-3.2.xsd">
            
 
    <http auto-config="true">
        
        <intercept-url pattern="/admin" access="ROLE_ADMIN" />
        
        <access-denied-handler error-page="/WEB-INF/Content/403.jsp" />
        
        <form-login 
            login-page="/login" 
            default-target-url="/admin" 
            authentication-failure-url="/login?error" 
            username-parameter="username"
            password-parameter="password" />
        <logout logout-success-url="/login?logout" />
        
    </http>
    
    <beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <beans:property name="userDetailsService" ref="userDetailsService"/>
    </beans:bean>
    
    
    <beans:bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
        <beans:property name="providers">
            <beans:list>
                <beans:ref local="daoAuthenticationProvider" />
            </beans:list>
        </beans:property>
    </beans:bean>
    
    <authentication-manager erase-credentials="false">
        <authentication-provider user-service-ref="userDetailsService">
        </authentication-provider>
    </authentication-manager>
    
</beans:beans>

3. UserService.java

This is our user service class.

package com.ssh.service;

import com.ssh.dao.UserDao;
import com.ssh.entity.Role;
import com.ssh.entity.User;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import javax.persistence.EntityNotFoundException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class UserService implements UserDetailsService {

    UserDao dao = new UserDao();

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = null;
        try {
            user = dao.findUser(username);
            if (user == null) {
                throw new UsernameNotFoundException("user not found");
            }
        } catch (Exception e) {
            throw new EntityNotFoundException(e.getCause().getMessage());
        }
        String uname = user.getUsername();
        String password = user.getPassword();
        boolean enabled = user.getEnabled();
        boolean accountNonExpired = Boolean.TRUE;
        boolean credentialsNonExpired = Boolean.TRUE;
        boolean accountNonLocked = Boolean.TRUE;
        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        for (Iterator it = user.getRoles().iterator(); it.hasNext();) {
            Role role = (Role) it.next();
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return new org.springframework.security.core.userdetails.User(
                uname, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
    }
}

4. UserDao.java

The DAO class.

package com.ssh.dao;

import com.ssh.entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class UserDao {

    SessionFactory sessionFactory = null;
    Session session = null;

    public User findUser(String username) throws Exception {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            session = sessionFactory.openSession();
            User user = (User) session.createQuery("from User where username=:username").setParameter("username", username).uniqueResult();
            return user;
        } catch (Exception e) {
            throw new Exception(e);
        } finally {
            session.flush();
            session.close();
        }
    }
}

In this example, we need two entities namely “Role” and “User” which in turn creates two relational database tables “role” and “users” using Hibernate framework. A separate join table namely “user_roles” is also created .

5. Role.java

Here’s the role entity.

package com.ssh.entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Role implements Serializable {

    private Long id;
    private String name;

    @Id
    @GeneratedValue
    @Column(name = "roleId")
    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

6. User.java

The user entity.

package com.ssh.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;

@Entity
@Table(name = "users")
public class User implements Serializable {

    private Long id;
    private String username, password;
    private Boolean enabled;
    private List<Role> roles = new ArrayList<Role>();

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "user_roles", joinColumns = {
        @JoinColumn(name = "userId"),}, inverseJoinColumns = {
        @JoinColumn(name = "roleId")})
    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public Boolean getEnabled() {
        return enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

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

    @Id
    @GeneratedValue
    @Column(name = "userId")
    public Long getId() {
        return id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

Now we persist users and roles by using the following code snippet.

public void saveRole() throws Exception {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            session = sessionFactory.openSession();
            session.getTransaction().begin();
            Role role = new Role();
            role.setName("ROLE_ADMIN");
            session.save(role);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    public void saveUser() throws Exception {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            session = sessionFactory.openSession();
            session.getTransaction().begin();
            User user = new User();
            user.setUsername("ddkr");
            user.setPassword("1986");
            Role role = (Role) session.get(Role.class, 1L);
            List<Role> roles = new ArrayList<Role>();
            roles.add(role);
            user.setRoles(roles);
            session.save(user);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

public void saveRole() throws Exception {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            session = sessionFactory.openSession();
            session.getTransaction().begin();
            Role role = new Role();
            role.setName("ROLE_MANAGER");
            session.save(role);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    public void saveUser() throws Exception {
        try {
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            session = sessionFactory.openSession();
            session.getTransaction().begin();
            User user = new User();
            user.setUsername("arun");
            user.setPassword("1234");
            Role role = (Role) session.get(Role.class, 2L);
            List<Role> roles = new ArrayList<Role>();
            roles.add(role);
            user.setRoles(roles);
            session.save(user);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

The generated sql and table structure is given below.

USE [Spring]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Role](
	[roleId] [numeric](19, 0) IDENTITY(1,1) NOT NULL,
	[name] [varchar](255) NULL,
PRIMARY KEY CLUSTERED 
(
	[roleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

USE [Spring]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[users](
	[userId] [numeric](19, 0) IDENTITY(1,1) NOT NULL,
	[enabled] [tinyint] NULL,
	[password] [varchar](255) NULL,
	[username] [varchar](255) NULL,
PRIMARY KEY CLUSTERED 
(
	[userId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

USE [Spring]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[user_roles](
	[userId] [numeric](19, 0) NOT NULL,
	[roleId] [numeric](19, 0) NOT NULL,
UNIQUE NONCLUSTERED 
(
	[roleId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[user_roles]  WITH CHECK ADD  CONSTRAINT [FK73429949537304F6] FOREIGN KEY([roleId])
REFERENCES [dbo].[Role] ([roleId])
GO

ALTER TABLE [dbo].[user_roles] CHECK CONSTRAINT [FK73429949537304F6]
GO

ALTER TABLE [dbo].[user_roles]  WITH CHECK ADD  CONSTRAINT [FK7342994958C85A60] FOREIGN KEY([userId])
REFERENCES [dbo].[users] ([userId])
GO

ALTER TABLE [dbo].[user_roles] CHECK CONSTRAINT [FK7342994958C85A60]
GO

This is how the tables look like.

spring_security_table_values

 

 

 

 

 

 

This is the table structure

spring_security_table_structure

 

 

 

 

 

 

 

 

 

 

 

 

 

 

7. struts.xml

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    
    <package name="default" extends="struts-default" namespace="/">
        
        <action name="admin" class="com.ssh.actions.AdminAction" method="execute">
            <result name="success">/WEB-INF/Content/admin.jsp</result>
        </action>
        <action name="login">  
            <result>/WEB-INF/Content/login.jsp</result>  
        </action>  
    </package>
</struts>

8. hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
        <property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
        <property name="hibernate.connection.url">jdbc:sqlserver://localhost:1433;databaseName=Spring</property>
        <property name="hibernate.connection.username">username</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping class="com.ssh.entity.Role"/>
        <mapping class="com.ssh.entity.User"/>
    </session-factory>
</hibernate-configuration>

9. AdminAction.java

package com.ssh.actions;

import com.opensymphony.xwork2.ActionSupport;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

public class AdminAction extends ActionSupport {

    private String username;
    private String password;

    @Override
    public String execute() {

        //Principal principal = ServletActionContext.getRequest().getUserPrincipal();
        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        System.out.println("username: " + userDetails.getUsername());
        System.out.println("password: " + userDetails.getPassword());
        Collection<SimpleGrantedAuthority> authorities = (Collection<SimpleGrantedAuthority>) userDetails.getAuthorities();
        for (Iterator it = authorities.iterator(); it.hasNext();) {
            SimpleGrantedAuthority authority = (SimpleGrantedAuthority) it.next();
            System.out.println("Role: " + authority.getAuthority());
        }

        return SUCCESS;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }
}

Next we move to the UI part.

10. redirect.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=login">

This JSP page has been set as welcome page in the deployment descriptor. When this page is loaded in the browser, the URL gets redirected to “login” action.

11. login.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
    <body>
        <h1>Struts2 - Spring Security Demo</h1> 
        <s:if test="%{#parameters.error != null}">
            <div style="color: red">Invalid User</div>
        </s:if>
        <s:form name="loginForm" action="j_spring_security_check" method="post">
            <s:textfield name="username" label="Username"/>
            <s:password name="password" label="Password"/>
            <s:submit value="Login"/>
        </s:form>
    </body>
</html>

12. admin.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page session="true"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Admin Page</title>
    </head>
    <body>
        <h1>Hello ${pageContext.request.userPrincipal.name}</h1>  
        <a href="j_spring_security_logout">Logout</a>
    </body>
</html>

13. 403.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Access Denied</title>
    </head>
    <body>
        <h1>Access Denied for ${pageContext.request.userPrincipal.name}!!!</h1>
        <a href="login">Back</a>
    </body>
</html>

DIRECTORY STRUCTURE

directory_structure_ssh

 

 

 

 

 

 

 

 

 

 

 

The above said example says, the access to the URL pattern “/admin” is restricted only to the users with role name “ROLE_ADMIN”. Then we create a user with username “ddkr” and password “1986” and assign him the role “ROLE_ADMIN”. So obviously he can access the URL pattern “/admin”. We have also created another user “arun” who is having “ROLE_MANAGER” role. When “arun” tries to access “/admin” URL, he is redirected to access-deny page. When some other unauthorized users try to access the “/admin” URL, the spring security tries to authenticate them but gets failed and they are redirected to the login page again.

SCREEN SHOTS

1. Login Screen

login_ssh_new

2. Login as “ddkr”, an authorized user

login_before_ddkr_ssh_new

login_after_ddkr

3. Logout

logout_ssh_new

4. Login as “arun”, an unauthorized user

login_before_arun_ssh_new

login_after_arun_ssh_new

5. Login as a non-existing user

login_before_invalid_ssh_new

login_invalid_ssh_new

Thanks.

Hibernate many-to-many unidirectional mapping using annotation

Hi all,

We have seen one-to-one unidirectional, bidirectional, one-to-many unidirectional, bidirectional and many-to-one unidirectional, bidirectional mappings in previous posts. Here we talk about many-to-many unidirectional mapping using annotations. So let’s start.

Here we gonna see a many-to-many relationship between “Course” and “Student”, ie., “many courses will have many students, the same student can be enrolled in many courses”.

Course_Student_ER

 

 

 

In the following example, Course is the parent entity and Student is the child entity. Our mapping flows from Course to Student.

Since the relation is unidirectional, the child details can be obtained by fetching parent details, but the reverse is not possible.

Here’s the parent entity class, Course.java

package com.hibernateApp.entity;

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

@Entity
public class Course implements Serializable {

    private long id;
    private String name;
    private List students;

    @Id
    @GeneratedValue
    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "Enrollment", joinColumns = {
        @JoinColumn(name = "Course_Id", insertable = false, updatable = false, nullable = false)}, inverseJoinColumns = {
        @JoinColumn(name = "Student_Id", insertable = false, nullable = false, updatable = false)})
    public List getStudents() {
        return students;
    }

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

    public void setName(String name) {
        this.name = name;
    }

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

In the above class, we have created a join table namely “Enrollment”, which maps courses to students.

Course_Student

 

 

 

 

 

 

 

Here’s the child entity class, Student.java

package com.hibernateApp.entity;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Student implements Serializable {

    private long id;
    private String name;

    @Id
    @GeneratedValue
    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }
}

The generic dao class, DAO.java

package com.hibernateApp.dao;

import com.hibernateApp.util.HibernateUtil;
import org.hibernate.FlushMode;
import org.hibernate.Session;

public abstract class DAO {

    private static final ThreadLocal THREAD = new ThreadLocal();

    public static Session getSession() {
        Session session = (Session) DAO.THREAD.get();
        if (session == null) {
            session = HibernateUtil.getSessionFactory().openSession();
            DAO.THREAD.set(session);
            getSession().setFlushMode(FlushMode.COMMIT);
        }
        return session;
    }

    protected static void begin() {
        getSession().beginTransaction();
    }

    protected static void commit() {
        getSession().getTransaction().commit();
    }

    protected static void rollback() {
        getSession().getTransaction().rollback();
        getSession().close();
        DAO.THREAD.set(null);
    }

    protected static void flush() {
        getSession().flush();
    }

    protected static void close() {
        getSession().close();
        DAO.THREAD.set(null);
    }
}

The main class, CourseStudent.java. Note that this class extends the above said DAO.java.

package com.hibernateApp.biz;

import com.hibernateApp.dao.DAO;
import com.hibernateApp.entity.Course;
import com.hibernateApp.entity.Student;
import java.util.ArrayList;
import java.util.List;

public class CourseStudent extends DAO {

    public void save1() throws Exception {
        try {
            begin();
            Course course = new Course();
            course.setName("MCA");
            Student student1 = new Student();
            Student student2 = new Student();
            List students = new ArrayList();
            student1.setName("Rahul");
            student2.setName("Sachin");
            students.add(student1);
            students.add(student2);
            course.setStudents(students);
            getSession().save(course);
            commit();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            rollback();
        } finally {
            flush();
            close();
        }
    }

    public void save2() throws Exception {
        try {
            begin();
            Course course = new Course();
            course.setName("MBA");
            List students = getSession().createCriteria(Student.class).list();
            course.setStudents(students);
            getSession().save(course);
            commit();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            rollback();
        } finally {
            flush();
            close();
        }
    }

    public void listCourses() throws Exception {
        try {
            begin();
            List courses = getSession().createCriteria(Course.class).list();
            for (Course course : courses) {
                System.out.println("Course Id: " + course.getId());
                System.out.println("Course Name: " + course.getName());
                for (Student student : course.getStudents()) {
                    System.out.println("Student Id: " + student.getId());
                    System.out.println("Student Name: " + student.getName());
                }
            }
            commit();
        } catch (Exception e) {
            rollback();
            System.out.println(e.getMessage());
        } finally {
            flush();
            close();
        }
    }

    public void deleteOrphan() throws Exception {
        try {
            begin();
            Course course = (Course) getSession().load(Course.class, new Long(1));
            Student student1 = (Student) getSession().load(Student.class, new Long(1));
            Student student2 = (Student) getSession().load(Student.class, new Long(2));
            course.getStudents().remove(student1);
            course.getStudents().remove(student2);
            getSession().delete(course);
            commit();
        } catch (Exception e) {
            rollback();
            System.out.print(e.getMessage());
        } finally {
            flush();
            close();
        }
    }

    public static void main(String[] args) throws Exception {
        new CourseStudent().listCourses();
    }
}

When we execute the save1() method, it outputs

Hibernate: 
    insert 
    into
        Course
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        Student
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        Student
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        Enrollment
        (Course_Id, Student_Id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Enrollment
        (Course_Id, Student_Id) 
    values
        (?, ?)

And the data will be stored in our database tables.

o2o_u_save1

 

 

 

 

 

 
When we execute the save2() method, it outputs

Hibernate: 
    select
        this_.id as id2_0_,
        this_.name as name2_0_ 
    from
        Student this_
Hibernate: 
    insert 
    into
        Course
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        Enrollment
        (Course_Id, Student_Id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Enrollment
        (Course_Id, Student_Id) 
    values
        (?, ?)

And we will have our tables like this.

o2o_u_save2

 

 

 

 

 

 

 
The configuration file, hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
        <property name="hibernate.connection.url">jdbc:sqlserver://localhost:1433;databaseName=TEST</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping class="com.hibernateApp.entity.Course"/>
        <mapping class="com.hibernateApp.entity.Student"/>
    </session-factory>
</hibernate-configuration>

The output of the listCourses() method looks like this.

Hibernate:
    select
        this_.id as id1_0_,
        this_.name as name1_0_
    from
        Course this_
Course Id: 1
Course Name: MCA
Hibernate:
    select
        students0_.Course_Id as Course1_1_,
        students0_.Student_Id as Student2_1_,
        student1_.id as id2_0_,
        student1_.name as name2_0_
    from
        Enrollment students0_
    left outer join
        Student student1_
            on students0_.Student_Id=student1_.id
    where
        students0_.Course_Id=?
Student Id: 1
Student Name: Rahul
Student Id: 2
Student Name: Sachin
Course Id: 2
Course Name: MBA
Hibernate:
    select
        students0_.Course_Id as Course1_1_,
        students0_.Student_Id as Student2_1_,
        student1_.id as id2_0_,
        student1_.name as name2_0_
    from
        Enrollment students0_
    left outer join
        Student student1_
            on students0_.Student_Id=student1_.id
    where
        students0_.Course_Id=?
Student Id: 1
Student Name: Rahul
Student Id: 2
Student Name: Sachin

Platform

OS: Windows 7 Enterprise SP 1
IDE: Netbeans 7.1.1
Java: 7 Update 51
Hibernate: 3.2.5
Database: Microsoft SQL Server 2012

Thanks.

Learn Spring By Example – Struts+Spring+Hibernate Integration

Hi friends,

Finally after a long time, we are back. Here we’ve yet another example, as the title says, it is an Integration example in which we are going to see how Struts, Spring and Hibernate are getting integrated together.

In the following example, Struts is used for view layer and also works as a controller, spring for IOC and transaction layers, hibernate for ORM (model layer).

Platform

OS: Windows XP Professional SP3.
IDE: Eclipse Juno.
Java: 1.6.0
Application Server: Apache Tomcat 6.0.37
Frameworks: Struts 2.1.8, Spring 3.2.1, Hibernate 3.2.0.
Databse: MySQL 5.1.32-community.

Ok, let’s start. The heart of the application is applicationContext.xml, where these frameworks are integrated. The file looks like this.

applicationContext.xml

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

	<tx:annotation-driven transaction-manager="transactionManager" />

	<context:annotation-config />

	<context:component-scan
		base-package="com.stringer.action,com.stringer.bo,com.stringer.dao" />

	<context:property-placeholder location="/WEB-INF/jdbc.properties" />

	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${driver}" />
		<property name="url" value="${url}" />
		<property name="username" value="${username}" />
		<property name="password" value="${password}" />
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="hibernateProperties" ref="hibernateProperties" />
		<property name="packagesToScan" value="com.stringer.model"></property>
	</bean>

	<bean id="hibernateProperties"
		class="org.springframework.beans.factory.config.PropertiesFactoryBean">
		<property name="locations">
			<list>
				<value>/WEB-INF/hibernate.properties</value>
			</list>
		</property>
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager"
		p:sessionFactory-ref="sessionFactory">
	</bean>

</beans>

It’s sorry to say that I’m not going to explain each and every point of the above configuration file. You can find out these definitions in every nook and corner of the web. Anyway I shall explain in brief.

<context:property-placeholder location="/WEB-INF/jdbc.properties" />

The above line tells spring to load property file from the specified location. We can also load multiple property files simultaneously like this.

<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${driver}" />
		<property name="url" value="${url}" />
		<property name="username" value="${username}" />
		<property name="password" value="${password}" />
	</bean>

The above bean definition says all about the database connection, i.e., driver, username, password, url etc.

<bean id="hibernateProperties"
		class="org.springframework.beans.factory.config.PropertiesFactoryBean">
		<property name="locations">
			<list>
				<value>/WEB-INF/hibernate.properties</value>
			</list>
		</property>
	</bean>

The above bean definition tells spring to load hibernate properties from the specified file.

<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="hibernateProperties" ref="hibernateProperties" />
		<property name="packagesToScan" value="com.stringer.model"></property>
	</bean>

The above definition creates a “sessionFactory” object using “dataSource” and “hibernateProperties”. The property “packagesToScan” specifies the path where the scanning for hibernate entities is to be performed. In this example, all model entities are encapsulated in “com.stringer.model” package.

Here comes the definition for creating a transaction manger object.

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager"
		p:sessionFactory-ref="sessionFactory">
	</bean>

The given piece of line used to enable spring annotation.

<context:annotation-config />

Finally, the below tag is used to scan for spring components in an application. The location of where to scan for classes is also specified.

<context:component-scan
		base-package="com.stringer.action,com.stringer.bo,com.stringer.dao" />

As it is already discussed in one of the previous post, spring scans for classes that are annotated with one of the following annotations.

  • @Component
  • @Controller
  • @Repository
  • @Service
  • Any custom annotation that is itself annotated with @Component

Ok, now let’s look into property files.

jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/Stringer
username=root
password=password

hibernate.properties

hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update

Now we’ve finished spring configuration. Next we are going to see struts configuration.

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

	<package name="default" extends="struts-default" namespace="/">

		<global-results>
			<result name="StringerException" type="chain">
				<param name="actionName">StringerExceptionAction</param>
			</result>
			<result name="error">/WEB-INF/Content/error.jsp</result>
		</global-results>

		<global-exception-mappings>
			<exception-mapping exception="java.lang.Exception"
				result="StringerException" />
		</global-exception-mappings>

		<action name="StringerExceptionAction" class="com.stringer.util.StringerException">
			<result name="StringerExceptionResult">/WEB-INF/Content/error.jsp</result>
		</action>

	</package>

	<include file="struts-user.xml" />
	<include file="struts-account.xml" />
	<include file="struts-index.xml" />

</struts>

In the above file, we can see global-results and global-exceptions are mapped. Also, it includes some other action mapping files. Struts supports split the overall mappings into several mapping files. One of the mapping file is given below. The given file is used for action mappings of user module.

struts-user.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

	<package name="User" extends="default" namespace="/User">

		<action name="*" method="{1}" class="UserAction">
			<result name="success">/WEB-INF/Content/User/home.jsp</result>
			<result name="input">/WEB-INF/Content/User/login.jsp</result>
			<result name="list">/WEB-INF/Content/User/list.jsp</result>
			<result name="profile">/WEB-INF/Content/User/profile.jsp</result>
			<result name="home">/WEB-INF/Content/User/home.jsp</result>
			<result name="create">/WEB-INF/Content/User/register.jsp</result>
			<result name="redirect" type="redirect">list.htm</result>
		</action>

	</package>

</struts>

Just look into the highlighted line given above, where we can see an attribute namely “class” and its value “UserAction”. Here, it’s not the class name actually, but the name of a spring bean. Just scroll up to the UserAction.java and we can see that the class has been annotated(@Controller) as a Controller and the controller’s name is given as “UserAction”. When we annotate a class as a controller, it becomes a spring component and we can reuse it anywhere in the application. How we could use it in this way because we add struts-spring integration plugin to the application and it helps us out.

struts.properties

struts.action.extension=htm
struts.ognl.allowStaticMethodAccess=true
struts.objectFactory= org.apache.struts2.spring.StrutsSpringObjectFactory
struts.objectFactory.spring.autoWire=type
struts.convention.result.path=/WEB-INF/content/
struts.devMode=true
struts.custom.i18n.resources=global

Here some of the struts properties defined, in which struts objectFactory and spring autowire default mode are notable. Here, we set default autowire mode as “type”. It allows a property to be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown. You can get to know more about spring autowiring from here.

This is for logging, which is optional.

log4j.properties

log4j.rootLogger = INFO, FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=C://log.out
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=#[%d{dd/MMM/yyyy HH:mm:ss}] - File[%F] - Method[%M] - Line[%L] - Priority[%p] - Message[%m]%n

And the following two files stand for struts internationalization(i18n) or localization(i10n) purpose.

package.properties

lbl.user.fname=First Name
lbl.user.lname=Last Name
lbl.user.age=Age
lbl.user.place=Place
lbl.user.uname=Username
lbl.user.pwd=Password
lbl.acc.no=Account Number
lbl.acc.name=Account Name
lbl.acc.desc=Account Description
lbl.acc.type=Account Type
lbl.acc.opbal=Opening Balance
btn.login=Login
btn.reg=Register
btn.sou=Save / Update
btn.home=Home

global.properties

msg.user.invalid=Invalid Username or Password !
msg.user.notfound=A User with username "$1" not found !

Finally, the most indispensable configuration.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>Stringer</display-name>
	<welcome-file-list>
		<welcome-file>/redirect.jsp</welcome-file>
	</welcome-file-list>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

<listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
<listener>
    <listener-class>
      com.stringer.util.StringerListener
    </listener-class>
  </listener>
  
  <session-config>
  <session-timeout>600</session-timeout>
  </session-config>
  
</web-app>

Please note how struts filter and spring listener are configured up here. We could see a user defined listener, namely StringerListener, which has also been set up there.

Ok, finally all the configurations come to an end. Next we shall go to the source. First off, let’s see the welcome page.

redirect.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=index.htm">

Here, we are going to discuss the complete flow of user registration.

register.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Register</title>
</head>
<body>
	<fieldset style="width: 20%; background-color: lightyellow">
		<s:form action="saveOrUpdate" namespace="/User">
			<s:hidden name="user.id" />
			<s:hidden name="user.version" />
			<s:textfield name="user.firstName" key="lbl.user.fname" />
			<s:textfield name="user.lastName" key="lbl.user.lname" />
			<s:textfield name="user.userName" key="lbl.user.uname" />
			<s:password name="user.password" key="lbl.user.pwd" />
			<s:textfield name="user.age" key="lbl.user.age" />
			<s:textfield name="user.place" key="lbl.user.place" />
			<s:submit key="btn.sou" />
		</s:form>
	</fieldset>
</body>
</html>

UserPOJO.java

package com.stringer.pojo;

import com.opensymphony.xwork2.conversion.annotations.TypeConversion;

public class UserPOJO {
	private String firstName, lastName, userName, password, place;
	private int age;
	private Long id, salt, version;
	private Boolean isObsolete;

	public Boolean getIsObsolete() {
		return isObsolete;
	}

	public void setIsObsolete(Boolean isObsolete) {
		this.isObsolete = isObsolete;
	}

	public Long getId() {
		return id;
	}

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

	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 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 getPlace() {
		return place;
	}

	public void setPlace(String place) {
		this.place = place;
	}

	public int getAge() {
		return age;
	}

	@TypeConversion(converter = "com.stringer.util.IntegerConverter")
	public void setAge(int age) {
		this.age = age;
	}

	public Long getVersion() {
		return version;
	}

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

	public Long getSalt() {
		return salt;
	}

	public void setSalt(Long salt) {
		this.salt = salt;
	}
}

There’s another class, namely UserDTO.java, which is used to transfer values between action and service.

UserDTO.java

package com.stringer.dto;

public class UserDTO {
	private String firstName, lastName, userName, password, place;
	private int age;
	private Long id, salt, version;
	private Boolean isObsolete;

	public Long getId() {
		return id;
	}

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

	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 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 getPlace() {
		return place;
	}

	public void setPlace(String place) {
		this.place = place;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Long getVersion() {
		return version;
	}

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

	public Long getSalt() {
		return salt;
	}

	public void setSalt(Long salt) {
		this.salt = salt;
	}

	public Boolean getIsObsolete() {
		return isObsolete;
	}

	public void setIsObsolete(Boolean isObsolete) {
		this.isObsolete = isObsolete;
	}

}

UserAction.java

package com.stringer.action;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.stringer.bo.UserBO;
import com.stringer.dto.UserDTO;
import com.stringer.pojo.FetchType;
import com.stringer.pojo.SortBy;
import com.stringer.pojo.SortOrder;
import com.stringer.pojo.UserPOJO;
import com.stringer.util.ApplicationUtils;

@Controller("UserAction")
@Scope("prototype")
public class UserAction extends BaseAction {

	private UserPOJO user = null;
	private UserDTO userDto = null;
	private @Autowired
	UserBO userBO;

	public UserPOJO getUser() {
		return user;
	}

	public void setUser(UserPOJO user) {
		this.user = user;
	}

	public String Register() {
		return CREATE;
	}

	public String Login() {
		return INPUT;
	}

	public String saveOrUpdate() throws StrutsActionException {
		try {
			userDto = ApplicationUtils.copyProperties(user, UserDTO.class);
			userBO.saveOrUpdate(userDto);
			if (isNull(session.get("loggedUser"))) {
				session.put("loggedUser", userDto);
			}
			return HOME;
		} catch (Exception e) {
			throw new StrutsActionException(e);
		}
	}

}

Here, UserAction.java works as a controller; see the highlighted line.

UserBO.java

package com.stringer.bo;

import com.stringer.dto.UserDTO;

public interface UserBO extends BaseBO {

	public void saveOrUpdate(final UserDTO userDTO) throws BOException;

}

It provides an interface to the Service layer.

UserBOImpl.java

package com.stringer.bo;

import java.io.Serializable;
import java.util.Collection;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.stringer.dao.UserDAO;
import com.stringer.dto.UserDTO;
import com.stringer.model.Account;
import com.stringer.model.User;
import com.stringer.pojo.FetchType;
import com.stringer.pojo.GenericPojo;
import com.stringer.pojo.SortBy;
import com.stringer.pojo.SortOrder;
import com.stringer.util.ApplicationUtils;

@Service("userBO")
@Transactional(value = "transactionManager", timeout = 30, readOnly = true, propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = java.lang.Exception.class)
public class UserBOImpl extends BaseBOImpl implements UserBO {

	private User user = null;
	private @Autowired
	BaseDAO baseDAO;

	@Override
	@Transactional(readOnly = false)
	public void saveOrUpdate(final UserDTO userDTO) throws BOException {
		try {
			user = isNull(userDTO.getId()) ? ApplicationUtils
					.createInstance(User.class) : (User) userDAO
					.findEntityById(User.class, userDTO.getId());
			ApplicationUtils.copyProperties(userDTO, user);
			Long salt = ApplicationUtils.salt();
			user.setPassword(ApplicationUtils.uniquePassword(
					userDTO.getPassword(), salt));
			user.setSalt(salt);
			user.setIsObsolete(Boolean.FALSE);
			baseDAO.saveOrUpdate(user);
		} catch (Exception e) {
			throw new BOException(e);
		}
	}

}

This is the implementation class of UserBO.java.

BaseDAO.java

package com.stringer.dao;

package com.stringer.dao;

public interface BaseDAO {

	public <T> void saveOrUpdate(final T entity) throws DAOException;

}

}

This is an interface to the DAO layer.

BaseDAOImpl.java

package com.stringer.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


@Repository("baseDAO")
public class BaseDAOImpl implements BaseDAO {

	private @Autowired
	SessionFactory sessionFactory;

	protected final Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	@Override
	public <T> void saveOrUpdate(final T obj) throws DAOException {
		try {
			getSession().saveOrUpdate(obj);
		} catch (Exception e) {
			throw new DAOException(e);
		}
	}

}

This is the implementation class of BaseDAO.java.

Finally the hibernate entity class,

User.java

package com.stringer.model;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Version;
import com.stringer.util.ApplicationConstants;

@Entity
@Table(name = ApplicationConstants.USER_TABLE, catalog = ApplicationConstants.CATALOG)
public class User implements Serializable {

	private String firstName, lastName, place, userName, password;
	private Integer age;
	private Long salt, id, version;
	private Boolean isObsolete;

	public void setIsObsolete(Boolean isObsolete) {
		this.isObsolete = isObsolete;
	}

	public Boolean getIsObsolete() {
		return isObsolete;
	}

	@Column(unique = true, nullable = false)
	public String getUserName() {
		return userName;
	}

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

	@Column(unique = true, nullable = false)
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Column(unique = true, nullable = false)
	public Long getSalt() {
		return salt;
	}

	public void setSalt(Long salt) {
		this.salt = salt;
	}

	@TableGenerator(name = ApplicationConstants.GENERATOR_NAME, table = ApplicationConstants.GENERATOR_TABLE, pkColumnName = ApplicationConstants.GENERATOR_PK_COLUMN_NAME, valueColumnName = ApplicationConstants.GENERATOR_VALUE_COLUMN_NAME, pkColumnValue = ApplicationConstants.USER_TABLE, allocationSize = ApplicationConstants.USER_ALOC_SIZE, initialValue = ApplicationConstants.USER_INIT_VALUE)
	@GeneratedValue(strategy = GenerationType.TABLE, generator = ApplicationConstants.GENERATOR_NAME)
	@Id
	@Column(unique = true, nullable = false, updatable = false)
	public Long getId() {
		return id;
	}

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

	@Column(nullable = false)
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	@Column
	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@Column
	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Column
	public String getPlace() {
		return place;
	}

	public void setPlace(String place) {
		this.place = place;
	}

	@Version
	public Long getVersion() {
		return version;
	}

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

The folder structure and the list of libraries used are given below.

Stringer_1
Stringer_2

  • antlr-2.7.6
  • aopalliance
  • asm-3.2
  • asm-attrs
  • cglib-2.2.3
  • commons-beanutils-1.8.3
  • commons-collections-2.1.1
  • commons-fileupload-1.2.1
  • commons-io-1.3.2
  • commons-lang3-3.1
  • commons-logging-1.0.4
  • commons-logging-1.1.1
  • dom4j-1.6.1
  • ehcache-1.2.3
  • ejb3-persistence
  • freemarker-2.3.15
  • hibernate3
  • hibernate-annotations
  • hibernate-commons-annotations
  • hibernate-entitymanager
  • hibernate-tools
  • javassist
  • jdbc2_0-stdext
  • jta
  • log4j-1.2.14
  • mysql-connector-java-5.1.6-bin
  • ognl-2.7.3
  • spring-aop-3.2.1.RELEASE
  • spring-aspects-3.2.1.RELEASE
  • spring-beans-3.2.1.RELEASE
  • spring-build-src-3.2.1.RELEASE
  • spring-context-3.2.1.RELEASE
  • spring-context-support-3.2.1.RELEASE
  • spring-core-3.2.1.RELEASE
  • spring-expression-3.2.1.RELEASE
  • spring-instrument-3.2.1.RELEASE
  • spring-instrument-tomcat-3.2.1.RELEASE
  • spring-jdbc-3.2.1.RELEASE
  • spring-jms-3.2.1.RELEASE
  • spring-orm-3.2.1.RELEASE
  • spring-oxm-3.2.1.RELEASE
  • spring-struts-3.2.1.RELEASE
  • spring-test-3.2.1.RELEASE
  • spring-tx-3.2.1.RELEASE
  • spring-web-3.2.1.RELEASE
  • spring-webmvc-3.2.1.RELEASE
  • spring-webmvc-portlet-3.2.1.RELEASE
  • struts2-core-2.1.8.1
  • struts2-spring-plugin-2.1.8
  • xwork-core-2.1.6

Conclusion

So far we were going through an example which integrates struts, spring and hibernate frameworks. I hope all of you get to know the example well and expected to try out this.

Thanks.