Wednesday, March 13, 2013

Spring Hibernate Java Maven war example

1. Project structure

C:.
├───.settings
├───src
│   └───main
│       ├───java
│       │   └───com
│       │       └───xyz
│       │           └───persistence
│       ├───resources --> where Status.hbm.xml and web-application-config.xml are
│       └───webapp
│           ├───META-INF
│           └───WEB-INF
└───target

2.Status.java POJO code - This represents a row in the mapped table
public class Status implements Serializable {

    private static final long serialVersionUID = 1L;

    public Status() {
        super();
    }

    private String statusCode;

    private String statusDescr;

    private Integer severity;

    private Date createTimestamp;

    private String createUserId;

    private String updUserId;

    private Date updTimestamp;

3. StatusDAO.java interface code
public interface StatusDAO {
    void save(Status status);
    void update(Status status);
    void delete(Status status);
    Status findByStatusCode(String statusCode);
}

4. StatusDAOImpl.java code

import java.util.List;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class StatusDAOImpl extends HibernateDaoSupport implements StatusDAO {

    public void save(Status status) {
        getHibernateTemplate().save( status );
    }

    public void update(Status status) {
        getHibernateTemplate().update(status);
        
    }

    public void delete(Status status) {
        getHibernateTemplate().delete(status);        
    }

    public Status findByStatusCode(String statusCode) {
        List list = getHibernateTemplate().find(
                "from Status where statusCode=?",statusCode
          );
    return (Status)list.get(0);
    }

}


5. TestDriver.java code for running CRUD test cases

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class TestDriver {
    
    private StatusDAO statusDAO;
    
    public static void main(String[] args) {
        TestDriver driver = new TestDriver();
        try {
            driver.create();
            driver.retrieve();
            driver.update();
            driver.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public TestDriver() {
        super();        
        ApplicationContext appContext = 
            new ClassPathXmlApplicationContext("/web-application-config.xml");
        statusDAO = (StatusDAO)appContext.getBean("statusDAO");
    }

    public void create() throws Exception {    
        
        Status status = createStatus();
        
        // create a new status in db
        createStatus(status);

        // retrieve a status from db
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // delete a status
        deleteStatus(retrievedStatus);
    }

    public void retrieve() throws Exception {        
        create();
    }

    public void update() throws Exception {    
        Status status = createStatus();

        // create a new status in db
        createStatus(status);

        // retrieve a status
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // update a status
        updateStatus();    

        // delete a status
        deleteStatus(retrievedStatus);
    }

    public void delete() throws Exception {        
        Status status = createStatus();

        createStatus(status);

        // retrieve a status
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // update a status
        updateStatus();

        // delete a status
        deleteStatus(retrievedStatus);
    }

    private Status createStatus() {
        Status status = new Status();

        status.setStatusCode("RR");
        status.setCreateTimestamp(new Date());
        status.setCreateUserId("sssss");
        status.setSeverity(new Integer(22));
        status.setStatusDescr("testing-sss");
        status.setUpdTimestamp(new Date());
        status.setUpdUserId("sssss");
        return status;
    }

    private void createStatus(Status status) {
        statusDAO.save(status);
    }

    private void updateStatus() {
        Status retrievedStatus = statusDAO.findByStatusCode("RR");
        retrievedStatus.setStatusDescr("updated description");
        statusDAO.update(retrievedStatus);
    }

    private void deleteStatus(Status retrievedStatus) {
        statusDAO.delete(retrievedStatus);
    }

6. Status.hbm.xml file
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.xyz.persistence">
    <class name="Status" table="AUTH_STAT" mutable="false">
        <id name="statusCode" column="AUTH_STAT_CD" type="string"/>

        <property name="statusDescr" column="AUTH_STAT_DSC" type="string"/>
        <property name="severity" column="AUTH_SEREVITY_ID" type="integer"/>
        <property name="createTimestamp" column="CREATE_TS" type="timestamp"/>
        <property name="createUserId" column="CREATE_USER_ID" type="string"/>
        <property name="updUserId" column="UPD_USER_ID" type="string"/>
        <property name="updTimestamp" column="UPD_TS" type="timestamp"/>
    </class>
</hibernate-mapping>

7. Spring bean configuration file - web-application-config.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:context="http://www.springframework.org/schema/context"
    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">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url"
            value="jdbc:oracle:thin:@dbhost:20009:sid" />
        <property name="username" value="ddd" />
        <property name="password" value="ddd" />
    </bean>

    <!-- Hibernate session factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <property name="dataSource">
            <ref bean="dataSource" />
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.default_schema">SchemaName</prop>
            </props>
        </property>

        <property name="mappingResources">
            <list>
                <value>/Status.hbm.xml</value>
            </list>
        </property>

    </bean>

    <!-- Status Data Access Object -->
    <bean id="statusDAO" class="com.xyz.persistence.StatusDAOImpl">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
</beans>


8. index.jsp code to call test driver
<?xml version="1.0" encoding="UTF-8" ?>

<%@ page import="com.xyz.persistence.TestDriver"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hibernate + Oracle 11g DB CRUD test page</title>
</head>

<body>
    <%
        try {                
            TestDriver driver = new TestDriver();
            driver.create();
            out.println("Create Status succeeded");
            out.println("<br>");
            
            driver.retrieve();
            out.println("Retrieve Status succeeded");
            out.println("<br>");
            
            driver.update();
            out.println("Update Status succeeded");
            out.println("<br>");
            
            driver.delete();
            out.println("Delete Status succeeded");
            out.println("<br>");
            
            out.println("All CRUD operations succeeded");
        } catch (Exception e) {
            out.println("An exception occurred: " + e.getMessage());
        }
    %>
</body>

</html>


9. maven po.xml dependencies
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.3.2.GA</version>
        </dependency>

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

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.0</version>
            <scope>test</scope>
        </dependency>

Tuesday, March 12, 2013

Hibernate Java Maven war example

1. Project structure
C:\workspace\testWebApp>tree
Folder PATH listing
Volume serial number is BED9-803F
C:.
├───.settings
├───src
│   └───main
│       ├───java
│       │   └───com
│       │       └───xyz
│       │           └───persistence
│       ├───resources --copy *.hbm.xml and hibernate.cfg.xml here
│       └───webapp
│           ├───META-INF
│           └───WEB-INF
└───target

2. Create Status Java POJO class - omitted getters and setters
import java.io.Serializable;
import java.util.Date;

public class Status implements Serializable {

 public Status() {
  super();
 }

 private String statusCode;

 private String statusDescr;

 private Integer severity;

 private Date createTimestamp;

 private String createUserId;

 private String updUserId;

 private Date updTimestamp;

3. Create status.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.xyz.persistence">
 <class name="Status" table="AUTH_STAT" mutable="false">
  <id name="statusCode" column="AUTH_STAT_CD" type="string"/>

  <property name="statusDescr" column="AUTH_STAT_DSC" type="string"/>
  <property name="severity" column="AUTH_SEREVITY_ID" type="integer"/>
  <property name="createTimestamp" column="CREATE_TS" type="timestamp"/>
  <property name="createUserId" column="CREATE_USER_ID" type="string"/>
  <property name="updUserId" column="UPD_USER_ID" type="string"/>
  <property name="updTimestamp" column="UPD_TS" type="timestamp"/>
 </class>
</hibernate-mapping>

4. Create 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.bytecode.use_reflection_optimizer">false</property>
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@dbhost.company.com:20009:sid</property>
        <property name="hibernate.connection.username">userName</property>
        <property name="hibernate.connection.password">password</property>
        <property name="show_sql">true</property>
        <property name="hibernate.default_schema">SID</property>
        <mapping resource="Status.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

5. Create a test driver class (DAO)
public class TestDriver {
 
 public static void main(String[] args) {
  TestDriver driver = new TestDriver();
  try {
   driver.create();
   driver.retrieve();
   driver.update();
   driver.delete();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 public TestDriver() {
  super();
 }

 public void create() throws Exception { 
  Status status = createStatus();
  
  // create a new status in db
  Session session = createStatus(status);

  // retrieve a status from db
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }

 public void retrieve() throws Exception {  
  create();
 }

 public void update() throws Exception { 
  Status status = createStatus();

  // create a new status in db
  Session session = createStatus(status);

  // retrieve a status
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // update a status
  updateStatus(session); 

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }

 public void delete() throws Exception {  
  Status status = createStatus();

  Session session = createStatus(status);

  // retrieve a status
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // update a status
  updateStatus(session);

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }
 
 public void runCRUDTestCases() throws Exception {
 }

 private Status createStatus() {
  Status status = new Status();

  status.setStatusCode("RR");
  status.setCreateTimestamp(new Date());
  status.setCreateUserId("sss");
  status.setSeverity(new Integer(22));
  status.setStatusDescr("testing-ssss");
  status.setUpdTimestamp(new Date());
  status.setUpdUserId("ssss");
  return status;
 }

 private Session createStatus(Status status) {
  Session session = HibernateUtil.getSessionFactory().openSession();
  session.beginTransaction();
  session.save(status);
  session.getTransaction().commit();
  return session;
 }

 private void updateStatus(Session session) {
  Status retrievedStatus;
  retrievedStatus = (Status) session.get(Status.class, "RR");
  retrievedStatus.setStatusDescr("updated description");
  session.beginTransaction();
  session.update(retrievedStatus);
  session.getTransaction().commit();
 }

 private void deleteStatus(Session session, Status retrievedStatus) {
  session.beginTransaction();
  session.delete(retrievedStatus);
  session.getTransaction().commit();
 }

6. HibernateUtil to create/close sessions
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

 private static final SessionFactory sessionFactory = buildSessionFactory();

 private static SessionFactory buildSessionFactory() {
  try {
   // Create the SessionFactory from hibernate.cfg.xml
   return new Configuration().configure().buildSessionFactory();
  } catch (Throwable ex) {
   // Make sure you log the exception, as it might be swallowed
   System.err.println("Initial SessionFactory creation failed." + ex);
   throw new ExceptionInInitializerError(ex);
  }
 }

 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }

 public static void shutdown() {
  // Close caches and connection pools
  getSessionFactory().close();
 }
}

7. Create index.jsp that calls test driver
<?xml version="1.0" encoding="UTF-8" ?>

<%@ page import="com.xyz.persistence.TestDriver"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hibernate + Oracle 11g DB CRUD test page</title>
</head>

<body>
 <%
  try {
   TestDriver driver = new TestDriver();
   driver.runCRUDTestCases();
   driver.create();
   out.println("Create Status succeeded");
   out.println("<br>");
   
   driver.retrieve();
   out.println("Retrieve Status succeeded");
   out.println("<br>");
   
   driver.update();
   out.println("Update Status succeeded");
   out.println("<br>");
   
   driver.delete();
   out.println("Delete Status succeeded");
   out.println("<br>");
   
   out.println("All CRUD operations succeeded");
  } catch (Exception e) {
   out.println("An exception occurred: " + e.getMessage());
  }
 %>
</body>

</html>

8. Copy Oracle DB driver class to application server or package it within war file for this work

9. pom.xml
<artifactId>testWebApp</artifactId>
 <packaging>war</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <name>testWebApp Maven Webapp</name>
 <url>http://maven.apache.org</url>

 <build>
  <finalName>testWebApp</finalName>
  <pluginManagement>
   <plugins>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-compiler-plugin</artifactId>
     <configuration>
      <encoding>UTF-8</encoding>
      <source>1.4</source>
      <target>1.4</target>
     </configuration>
    </plugin>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-resources-plugin</artifactId>
     <version>2.5</version>
     <configuration>
      <encoding>UTF-8</encoding>
     </configuration>
    </plugin>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-eclipse-plugin</artifactId>
     <version>2.8</version>
    </plugin>
   </plugins>
  </pluginManagement>
 </build>

 <!-- Project dependencies -->
 <dependencies>

  <dependency>
   <groupId>jstl</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>
  
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.0</version>
  </dependency>
  
        <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.6.1</version>
  </dependency>
  
     <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-core</artifactId>
       <version>3.3.2.GA</version>
     </dependency>

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

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.0</version>
   <scope>test</scope>
  </dependency>

 </dependencies>

Thursday, March 07, 2013

Spec for small business class management mobile application

I got an idea to build a mobile application that can keep of track of classes, students and their payments for my daughter's music teacher. Here are some major usecases I can think of:

Manage classes:
- add new class for a specific time of day, set its recurring properties. Ex: Every Thursday at 7PM
- change an existing class
- delete an existing class
- set max students in a class
- track progress of the student
- show progress of things student can do vs things need to learn/master

Manage fee payment:
- mark student as paid
- browse a list of unpaid students

Manage enrollment into classes
- add/remove/find a student in a class

Generate reports
- who did not pay this month?

Nice to have:
- automatically adds public holidays
- preference to send reminder to students email if schedule changes
- change schedule for a particular occurrence of a recurrent class
- show picture of the student and his/her contact information

Integration patterns/technologies

I was talking with a friend of mine about different options available for integrating one system with another. Following came up in my mind:
  1. File based - In this type of integration, one system send a file of transactions or records every predefined period of time. The protocol could be FTP/SFTP. The other system picks up the file and processes those records. Optionally it could respond by sending a file of its own that contain error transactions/records. The advantage of this approach is that it is simple and straitforward. However, it is not real time. Also, there is no inherent persistence other than file based.
  2. Database sharing - in this approach both systems read/write from a shared database. The disadvantage is that the database becomes owner of data. It is not real time inherently but could be implemented for real time by polling database
  3. Message based such as JMS/MQ - request/respond pattern can be implemented for real time integration
  4. WebServices/SOAP/Rest - real time.

Monday, March 04, 2013

Simple shell script to invoke a java program with arguments

#!/bin/bash

#arguments, constants etc.
PROVIDER_URL="t3://abc37.abc.com:7002,abc38.abc.com:7002"
CONN_FACTORY="jms/emjoXAJMSConnectionFactory"
QUEUE="jms/ShopListINQueue"
MSG_COUNT=100

WL_HOME="/appl/wl/wlserver_10.3/server/lib"
JAVA_HOME=/usr/lib/jvm/jdk1.6.0_02
CLASSPATH=$WL_HOME/api.jar:$WL_HOME/weblogic.jar:./JmsClient.jar

#invoke java program
$JAVA_HOME/bin/java -cp $CLASSPATH com.abc.test.JmsClient $PROVIDER_URL $CONN_FACTORY $QUEUE $MSG_COUNT

Rewards API - for retail customer loyalty

Below is a spec for Rewards API for customer loyalty programs I came up with. The idea is to keep track of customer purchases by providing them with a store specific card and offer them a financial reward (such as 10$ for every 100$ spent in a month) in return of their spending at the store.

This API can be exposed as a SOAP or other remoting technology and integrated into POS systems.

Key usecases:
1. Customer enrolls in to loyalty program
2. Customer purchases are recorded and points get accumulated
3. Customer redeems rewards points accumulated in his account
4. System clears points accumulated that were not used at the end of every month

Data Model:
Customer_Card
Cardid--firstName--lastName--address--enrollDate

Card_Points
cardId--points--expirationDate
123 80 3/31/2013

Card_Purchases
cardId--purchaseDate--grossAmount
123 3/5/2013 45.0$

Points_Multiplier
pointsMultiplier
0.25

Rewards_Points
points--rewardAmount
100 10$

Application Programming Interface (API) Specification
Integer enrollCustomer(Customer)
void deleteCustomer(int cardId)
void updateCustomer(int cardId, Customer customer)
Customer getCustomer(int cardId)

Double getPointsBalance(int cardId)
Double getPointsMultiplier()

Double addPoints(cardId, purchaseAmount)
Double redeemPoints(cardId)

Business Rules:
- Points expire at the end of every month
- Points_Multiplier specifies how many points there are for 1$
- Rewards_Points specifies how many dollars are rewarded for points

Sunday, March 03, 2013

Install log for Apache/MySQL/PHP/Drupal on 64-bit Windows 7

1. installed httpd-2.2.19-win64 apache in C:\apache
2. installed php-5.4.0-Win32-VC9-x64 php in c:\php
3. Edited httpd.conf
4. Edited php.ini
5. installed mysql in c:\mysql root/admin123
5. installed drupal-7.20 into c:\apache\htdocs
6. Created a schema in mysql
   drupal_schema root/admin123
7. start apache (cmd line httpd.exe)
8. Go to localhost/drupal-7.20 and follow instructions
    site-admin admin/admin123