Powered By Blogger
Showing posts with label java ee. Show all posts
Showing posts with label java ee. Show all posts

Sunday, August 12, 2012

Hibernate Hierarchy Mapping - Table Per Class

This example shows how to map a hierarchy with hibernate using the strategy, table per class. Circle and Square are two classes which extend Shape. The attribute, id of Shape is common to both the subclasses and will be the primary key of the tables created.

===================================================================
// The shape class
package com.shyarmal.hibernate.example.shape;

public class Shape implements IPersistable {

    protected long id;

    public long getId() {
        return id;
    }

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


// Subclass of Shape, Circle
package com.shyarmal.hibernate.example.shape;

public class Circle extends Shape {

    private float radius;
    private float centerX;
    private float centerY;

    public float getRadius() {
        return radius;
    }

    public void setRadius(float radius) {
        this.radius = radius;
    }

    public float getCenterX() {
        return centerX;
    }

    public void setCenterX(float centerX) {
        this.centerX = centerX;
    }

    public float getCenterY() {
        return centerY;
    }

    public void setCenterY(float centerY) {
        this.centerY = centerY;
    }
}


// Subclass of Shape, Square
package com.shyarmal.hibernate.example.shape;

public class Square extends Shape {

    private float length;
    private float topX;
    private float topY;

    public float getTopX() {
        return topX;
    }

    public void setTopX(float topX) {
        this.topX = topX;
    }

    public float getlength() {
        return length;
    }

    public void setlength(float length) {
        this.length = length;
    }

    public float getTopY() {
        return topY;
    }
    public void setTopY(float topY) {
        this.topY = topY;
    }
}

===================================================================
The hibernate xml mapping for the above hierarchy is as follows. All three classes mapping configurations are done in the same hmb file. This configuration will map (and/or create) three tables for the three classes.

===================================================================
<?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.shyarmal.hibernate.example.shape">
    <class name="Shape" table="SHAPE">
        <id name="id" column="ID" type="long">
            <generator class="native" />
        </id>
        <joined-subclass table="CIRCLE" name="Circle">
            <key column="ID" />
            <property name="radius" column="RADIUS" type="float"/>
            <property name="centerX" column="CENTER_X" type="float"/>
            <property name="centerY" column="CENTER_Y" type="float"/>
        </joined-subclass>
        <joined-subclass table="SQUARE" name="Square">
            <key column="ID" />       
            <property name="length" type="float" column="LENGTH"/>
            <property name="topY" column="TOP_Y" type="float" />
            <property name="topX" column="TOP_X" type="float" />
        </joined-subclass>
    </class>
</hibernate-mapping>

===================================================================

As you can notice, the 'class' tag refers to the class, Shape and the primary key is it's id attribute  (mapped with 'generator' tag). Subclasses are mapped with the element, 'joined-subclass', enclosed in 'class' tag. The element, 'key' defines a (foreign key) reference to the 'ID' column of the 'SHAPE' table. Further, the properties specific to each subclass is defined within the 'joined-subclass' element.

thanks,
Shyarmal.

Sunday, June 24, 2012

Web application context (spring load)

Following is an example of how spring beans can be loaded from a servlet. 

The web.xml configuration required is as follows. The spring bean definition xml file path should be given as a context parameter. Spring's ContextLoaderListener has to be defined as a listener in the web.xml. The sub-element 'load-on-startup' should be present in the servlet definition for the servlet to load at the web application is deploy time (If not the servlet will be initialized upon the first request to it).

 ==================================================================
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-beans.xml</param-value>
    </context-param>
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>/WEB-INF/log4j.xml</param-value>
        <description>location of log4j configuration file, used by log4jconfiglistener</description>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>InitServlet</servlet-name>
        <servlet-class>com.shyarmal.servlet.InitServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>InitServlet</servlet-name>
        <url-pattern>/init</url-pattern>
    </servlet-mapping>

</web-app>
 ==================================================================

The servlet code is below. The method, init(ServletConfig) [or init()] is overridden to load the web application context with, "WebApplicationContextUtils .getWebApplicationContext(config.getServletContext());". Servlet's init is called when the same is initialized.

 ==================================================================

package com.shyarmal.servlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;



public class InitServlet extends HttpServlet {

    private static final Logger LOGGER = LoggerFactory.getLogger(InitServlet.class);

    @Override
    public void init(ServletConfig config) throws ServletException {
        try {
            LOGGER.debug("initializing email service.");
            ApplicationContext ac = WebApplicationContextUtils              .getWebApplicationContext(config.getServletContext());
            LOGGER.info("Started email service.");
        } catch (Exception e) {
            LOGGER.error("Failed to load application context.", e);
        }
        super.init(config);
    }
}

 ==================================================================


thanks,
Shyarmal.


Wednesday, December 28, 2011

Open Session In View Filter Usage

Open Session In View Filter of Spring framework takes care of hibernate session management of a web application.  The integration of it is done at the web.xml.

Firstly, the spring beans ought to be loaded to the application context. This is done with a 'context-param' element. Secondly, define a filter with a 'filter' element (here my filter class is com.shyarmal.filter.MyOpenSessionInViewFilter which extends org.springframework.orm.hibernate3.support.OpenSessionInViewFilter).  Thirdly, define a filter mapping to the filter appropriately using 'filter-mapping' element. Notice the init parameter (sessionFactoryBeanName) passed to the filter. It is the id of the session factory defined in spring beans xml configurations.

web.xml elements of interest are as follows.
===================================================================
<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/springmvc-servlet.xml</param-value>
</context-param>

<filter>
   <filter-name>openSessionInViewFilter</filter-name>
   <filter-class>com.shyarmal.filter.MyOpenSessionInViewFilter</filter-class>
   <init-param>
        <param-name>sessionFactoryBeanName</param-name>
        <param-value>sessionFactory</param-value>
   </init-param>
</filter>

<filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>
===================================================================

Following are the spring bean definitions related to session factory used for the integration of open session in view filter.
===================================================================

<bean id="hibernateConfigProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
   <property name="location">
       <value>classpath:hibernate.properties</value>
   </property>
</bean>

<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
   <property name="driverClassName" value="${jdbc.driver.class.name}"/>
   <property name="url" value="${jdbc.url}"/>
   <property name="username" value="${jdbc.username}"/>
   <property name="password" value="${jdbc.password}"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mappingResources">
        <list>
            <value>Accounts.hbm.xml</value>
             .....
            .....
            .....
        </list>
    </property>
    <property name="hibernateProperties" ref="hibernateConfigProperties"/>
</bean>

===================================================================

thanks,
Shyarmal.

Thursday, August 4, 2011

Printing example with Java EE

Following  is an approach to printing a document using a servlet. The example uses a template which is in html to generate a page (an invoice) and then prints it. Place holders of variable fields of the invoice are obtained via the user session and replaced appropriately. Since the clients should be getting a printout of the invoice, the printing has to be done through the browser (using a javascript).

===================================================================
package com.shyarmal.web.services;

import com.shyarmal.web.util.DateTimeUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

public class InvoicePrinter extends HttpServlet {

    private static final String TEMPLATE_NAME = "/invoice.tpl";
    
    private static final Logger LOGGER = Logger.getLogger(InvoicePrinter.class);
    
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        LOGGER.info("printing receipt ....");
        try {
            Map receiptDetails = (Map) req.getSession().getAttribute("recieptParameters");
            receiptDetails.put("date", DateTimeUtil.getDate());
            receiptDetails.put("time", DateTimeUtil.getTime());
            PrintWriter pw = resp.getWriter();
            pw.print(replaceTokens(readTemplate(), receiptDetails));
            pw.flush();
            pw.close();
        } catch (Exception e) {
            LOGGER.error("Printing failed .... ", e);
        } finally {
            LOGGER.info("quit printer task.... ");
        }
    }
    
    private String readTemplate() throws IOException {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(TEMPLATE_NAME)));
            StringBuffer sb = new StringBuffer();
            while(br.ready()) {
                sb.append(br.readLine());
            }
            
            return sb.toString();
        } finally {
            br.close();
        }
    }
    
    private String replaceTokens(String text, Map replacements) {
        Pattern pattern = Pattern.compile("\\[(.+?)\\]");
        Matcher matcher = pattern.matcher(text);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            String replacement = (String)replacements.get(matcher.group(1));
            if(replacement != null) {
                matcher.appendReplacement(sb, "");
                sb.append(replacement);
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

}
===================================================================

I have posted a sample template which will be used to generate the invoice below. The segments to be replaced are enclosed with square brackets. Replacement of tokens is done in the method replaceTokens(String, Map) method. The keys of the map should map the names of the placeholders which are given within square brackets. Actually the printing is done by onLoad='self.print()' call in the body tag of the template. All what the servlet does is creating the specific invoice for the user and displaying it.

===================================================================
<!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> <title>Untitled Document</title> <style type='text/css'> <!-- ----- css codes ------- --> </style> </head> <body style='font: Arial; color:#333333' onLoad='self.print()'> <br /><br /><br /> <table width='100' border='0' align='center' cellpadding='1' cellspacing='0' bgcolor='#A21D18'> <tr> <td bgcolor='#A21D18'>
<table width='455' border='0' align='left' cellpadding='0' cellspacing='0' bgcolor='#FFFFFF'> <tr> <td width='350' height='30' class='style2'> <div align='left' style='padding-left:30px;'>Date : [date] </div> </td> <td width='350' class='style2'> <div align='left' style='padding-left:30px;'>Time : [time] </div> </td> </tr> <tr> <td colspan='2' class='style2'>
<div align='left' style='padding-left:50px; padding-right:50px; padding-top:5px;'> <table width='100%' border='0' cellspacing='0' cellpadding='0'> <tr> <td width='48%'><u>Invoice</u></td> <td width='4%'>&nbsp;</td> <td width='48%'>&nbsp;</td> </tr> <tr> <td>ID/Passport No </td> <td align='center'>:</td> <td>[nic]</td> </tr> <tr> <td>Name</td> <td align='center'>:</td> <td>[first_name] &nbsp; [last_name]</td> </tr> <tr> <td>Billing Address</td> <td align='center'>:</td> <td>[address]</td> </tr> <tr> <td>Billing Country</td> <td align='center'>:</td> <td>Sri Lanka</td> </tr> <tr> <td>Amount </td> <td align='center'>:</td> <td>LKR [amount]</td> </tr> </table> </div></td> </tr> </table></td> </tr> </table> </body> </html>
===================================================================

The javascript code in the jsp will be opening a new window and loading the invoice for the particular customer. The dimensions of the window opened will be 800 x 600 and will be sending a request to the above servlet with the url 'shopping/pringInvoice'. ['shopping/pringInvoice' is mapped to the servlet in the web.xml file.]
===================================================================

<script type="text/javascript">
  function print() {
    window.open('/shopping/printInvoice','receipt','width=600,height=800');
  }
</script>
===================================================================

The servlet should be defined and mapped in the web.xml.
===================================================================
<servlet-mapping>
<servlet-name>printInvoice</servlet-name>
<url-pattern>/printInvoice</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>printInvoice</servlet-name>
<servlet-class>com.shyarmal.web.services.InvoicePrinter</servlet-class>
</servlet>
==================================================================

thanks,
Shyarmal.