Aspects of using Hibernate with CaptainCasa Enterprise Client

Similar documents
Arjun V. Bala Page 20

Managing Data on the World Wide-Web

Hibernate Reference Documentation. Version: 3.2 cr1

Ch-03 Web Applications

Configure a SOAScheduler for a composite in SOA Suite 11g. By Robert Baumgartner, Senior Solution Architect ORACLE

No no-argument constructor. No default constructor found

Developing an EJB3 Application. on WebSphere 6.1. using RAD 7.5

Visa Checkout September 2015

Hibernate Reference Documentation

PA165 - Lab session - Web Presentation Layer

Enterprise Application Development In Java with AJAX and ORM

Clustering a Grails Application for Scalability and Availability

Java EE Introduction, Content. Component Architecture: Why and How Java EE: Enterprise Java

Supporting Multi-tenancy Applications with Java EE

Web Container Components Servlet JSP Tag Libraries

CS506 Web Design and Development Solved Online Quiz No. 01

Object Relational Mapping for Database Integration

Liferay Enterprise ecommerce. Adding ecommerce functionality to Liferay Reading Time: 10 minutes

Determine the process of extracting monitoring information in Sun ONE Application Server

Spring Security SAML module

Servlet and JSP Filters

Web Service Caching Using Command Cache

Service Integration course. Cassandra

Performance Monitoring API for Java Enterprise Applications

JBoss Portlet Container. User Guide. Release 2.0

By Wick Gankanda Updated: August 8, 2012

Building Web Applications, Servlets, JSP and JDBC

Documentum Developer Program

CHAPTER 9: SERVLET AND JSP FILTERS

Controlling Web Application Behavior

Ehcache Web Cache User Guide. Version 2.9

PicketLink Federation User Guide 1.0.0

Creating Java EE Applications and Servlets with IntelliJ IDEA

Web Applications. For live Java training, please see training courses at

Building Web Services with Apache Axis2

Web Application Architecture (based J2EE 1.4 Tutorial)

Chapter 1. JOnAS and JMX, registering and manipulating MBeans

Java EE 6 New features in practice Part 3

Core Java+ J2EE+Struts+Hibernate+Spring

MyOra 3.0. User Guide. SQL Tool for Oracle. Jayam Systems, LLC

OTN Developer Day Enterprise Java. Hands on Lab Manual JPA 2.0 and Object Relational Mapping Basics

ULC Application Development Guide. Canoo RIA-Suite 2014 Update 2

Web Development in Java

Drupal CMS for marketing sites

Getting Started with Telerik Data Access. Contents

Java 7 Recipes. Freddy Guime. vk» (,\['«** g!p#« Carl Dea. Josh Juneau. John O'Conner

Connecting Custom Services to the YAWL Engine. Beta 7 Release

Tomcat 5 New Features

Keycloak SAML Client Adapter Reference Guide

White Paper: 1) Architecture Objectives: The primary objective of this architecture is to meet the. 2) Architecture Explanation

The Google Web Toolkit (GWT): The Model-View-Presenter (MVP) Architecture Official MVP Framework

JSP. Common patterns

MS Enterprise Library 5.0 (Logging Application Block)

How To Write A Web Framework In Java

SpagoBI exo Tomcat Installation Manual

Spring Security 3. rpafktl Pen source. intruders with this easy to follow practical guide. Secure your web applications against malicious

JWIG Yet Another Framework for Maintainable and Secure Web Applications

Rapid Application Development. and Application Generation Tools. Walter Knesel

Specialized Programme on Web Application Development using Open Source Tools

Web Development in Java Live Demonstrations (Live demonstrations done using Eclipse for Java EE 4.3 and WildFly 8)

Effective logging practices ease enterprise

Tutorial for Spring DAO with JDBC

Developing Web Views for VMware vcenter Orchestrator

MyOra 3.5. User Guide. SQL Tool for Oracle. Kris Murthy

Workshop for WebLogic introduces new tools in support of Java EE 5.0 standards. The support for Java EE5 includes the following technologies:

IBM Operational Decision Manager Version 8 Release 5. Getting Started with Business Rules

CONTROLLING WEB APPLICATION BEHAVIOR WITH

ACM Crossroads Student Magazine The ACM's First Electronic Publication

Hello World Portlet Rendered with JSP for WebSphere Portal Version 4.1

ActiveVOS Server Architecture. March 2009

Oracle Hyperion Financial Management Custom Pages Development Guide

ArpViewer Manual Version Datum

How to Enable Quartz Job Execution Log Interception In Applications. J u n e 26,

Rational Application Developer Performance Tips Introduction

Running and Testing Java EE Applications in Embedded Mode with JupEEter Framework

Athena Framework Java Developer's Guide

Quartz.Net Scheduler in Depth

Crystal Reports XI. Overview. Contents. Understanding the CRConfig.xml File

White Paper March 1, Integrating AR System with Single Sign-On (SSO) authentication systems

Oracle Forms Services Secure Web.Show_Document() calls to Oracle Reports Server 6i

WebSphere Server Administration Course

Financial Big Data Loosely coupled, highly structured. Andrew Elmore

WEB APPLICATION DEVELOPMENT. UNIT I J2EE Platform 9

IBM WebSphere Server Administration

CONFIGURATION AND APPLICATIONS DEPLOYMENT IN WEBSPHERE 6.1

JSP Java Server Pages

WebSphere and Message Driven Beans

JAVA r VOLUME II-ADVANCED FEATURES. e^i v it;

JAVA ENTERPRISE IN A NUTSHELL. Jim Farley and William Crawford. O'REILLY 4 Beijing Cambridge Farnham Koln Paris Sebastopol Taipei Tokyo.

CERTIFIED MULESOFT DEVELOPER EXAM. Preparation Guide

CSE 530A Database Management Systems. Introduction. Washington University Fall 2013

Model-View-Controller. and. Struts 2

Crystal Reports Integration Plugin for JIRA

Using Database Metadata and its Semantics to Generate Automatic and Dynamic Web Entry Forms

WebObjects Web Applications Programming Guide. (Legacy)

Configuring ActiveVOS Identity Service Using LDAP

WIRIS quizzes web services Getting started with PHP and Java

Oracle WebLogic Server

Transcription:

Aspects of using Hibernate with CaptainCasa Enterprise Client We all know: there are a lot of frameworks that deal with persistence in the Java environment one of them being Hibernate. And there are a lot of different ways how to work with Hibernate. So this document only does not tell you the one and only way to use Hibernate within a CaptainCasa environment, but it talks about one way of using it. Nevertheless there are some principal thoughts that should always be of interest and, please note: the server side of CaptainCasa is based on JSF. So, what we talk about in this document is nothing, which is specific to CaptainCasa. Adding Hibernate to your Project Libraries Hibernate consist out of quite a lot libraries + dependent libraries. Add all these libraries into the WEB-INF/lib folder of your web content. The following screen shot shows the WEB-INF/lib folder after having added all Hibernate libraries: 1

You also see a hsqldb.jar which is a driver to the database that we are using (a small HSQL database). Configuration Files Add the following configuration files to the source folder of your project: A typical content of the log4j.properties files is: ### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.consoleappender log4j.appender.stdout.target=system.out log4j.appender.stdout.layout=org.apache.log4j.patternlayout log4j.appender.stdout.layout.conversionpattern=%dabsolute %5p %c1:%l - %m%n ### direct messages to file hibernate.log ### #log4j.appender.file=org.apache.log4j.fileappender #log4j.appender.file.file=hibernate.log #log4j.appender.file.layout=org.apache.log4j.patternlayout #log4j.appender.file.layout.conversionpattern=%dabsolute %5p %c1:%l - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootlogger=warn, stdout log4j.logger.org.hibernate=info #log4j.logger.org.hibernate=debug ### log HQL query parser activity #log4j.logger.org.hibernate.hql.ast.ast=debug ### log just the SQL #log4j.logger.org.hibernate.sql=debug ### log JDBC bind parameters ### log4j.logger.org.hibernate.type=info #log4j.logger.org.hibernate.type=debug ### log schema export/update ### log4j.logger.org.hibernate.tool.hbm2ddl=debug ### log HQL parse trees #log4j.logger.org.hibernate.hql=debug ### log cache activity ### #log4j.logger.org.hibernate.cache=debug ### log transaction activity #log4j.logger.org.hibernate.transaction=debug ### log JDBC resource acquisition #log4j.logger.org.hibernate.jdbc=debug ### enable the following line if you want to track down connection ### ### leakages when using DriverManagerConnectionProvider ### #log4j.logger.org.hibernate.connection.drivermanagerconnectionprovider=trace A typical content of the hibernate.cfg.xml file is: <?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> 2

<session-factory> <!-- Database connection settings --> <property name="connection.driver_class">org.hsqldb.jdbcdriver</property> <property name="connection.url">jdbc:hsqldb:hsql://localhost/isa</property> <property name="connection.username">sa</property> <property name="connection.password"></property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.hsqldialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.nocacheprovider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">update</property> <mapping resource="entities/database.hbm.xml"/> </session-factory> </hibernate-configuration> The hibernate configuration points to locally running hypersonic database (HSQL). There is a pointing to a mapping file contained in the source directory entities/database.hbm.xml - so all this is normal Hibernate The typical HibernateUtil class Add the typical HibernateUtil class to the project for having a singleton-access to the Hibernate SessionFactory: package hibernate; import org.hibernate.sessionfactory; import org.hibernate.cfg.configuration; public class HibernateUtil private static final SessionFactory s_sessionfactory; static try // Create the SessionFactory from hibernate.cfg.xml s_sessionfactory = 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 s_sessionfactory; 3

First test your Environment After having done the copying, it's not too bad to do some testing, if you can access the database Write an entity bean (in example below PersonEntity ) Set up the mapping (or use Hibernate annotations) Write a mini test page with an action listener doing some Hibernate operations Deploy this by reloading the application in the Layout Editor The entity bean might look like: package entities; public class PersonEntity String m_id; String m_firstname; String m_lastname; Boolean m_sex; String m_geburtsland; public String getgeburtsland() return m_geburtsland; public void setgeburtsland(string geburtsland) m_geburtsland = geburtsland; public Boolean getsex() return m_sex; public void setsex(boolean sex) m_sex = sex; public String getid() return m_id; public void setid(string id) m_id = id; public String getfirstname() return m_firstname; public void setfirstname(string firstname) m_firstname = firstname; public String getlastname() return m_lastname; public void setlastname(string lastname) m_lastname = lastname; The mapping file (in the example: entities/database.hbm.xml) might look like: <?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> <class name="entities.personentity" table="person"> <id name="id" length="25" column="p_id" type="string" /> <property name="firstname" length="100" column="p_firstname"/> <property name="lastname" length="100" column="p_lastname"/> <property name="sex" column="p_sex"/> </class> </hibernate-mapping> And the simple bean that is bound to user interface ( managed bean ) might have the following action listener: public class TestUI public void ontest(actionevent event) try Session s = HibernateContext.getCurrentSession(); // query List<PersonEntity> pes = (List<PersonEntity>)s.createQuery 4

( "from PersonEntity" ).list(); for (PersonEntity pe: pes) System.out.println(pe); // update Transaction t = HibernateContext.beginTransaction(); PersonEntity pe = new PersonEntity(); pe.setid(""+system.currenttimemillis()); pe.setfirstname("first"); pe.setlastname("last"); s.save(pe); HibernateContext.commit(); catch (Throwable t) t.printstacktrace(); When executing the action listener from the UI several times, you should see an increasing number of persons that are output to the console Typical Usage Patterns In principal you now can work with Hibernate in any way you like. You have the UI-classes (managed beans) that are bound to the UI processing, within these classes you can invoke any Java function that internally operated with the Hibernate objects, such as SessionFactory, Session, Transaction, Query etc. But: of course there are some usage patterns that you should be aware of: Typically there is one (and exactly one) SessionFactory for the database that you access. This is ensured due the HibernateUtil class that was mentioned in a previous chapter. Typically the life cycle of a Session-object should be very short. The Session-object should be valid during one request only, so it should be closed when the request that comes from the user interface client is finished and the response to the client is sent. - It is an absolute anti-pattern to have Session-objects that span multiple requests. Don't do this by accident! Typically all the code that is executed during a request should access the same Sessionobject. Same with transactions: everyone typically should used a shared transaction for one request, so that all updates that are done are in the same transaction. Now adding some typical Hibernate Usage Patterns Bind Hibernate Context Info to Thread In order to achieve the goals listed in the text above, it is a common pattern that these objects that are be shared during request processing are bound to the request thread. The concrete objects that we take about are: Session Transaction The binding to the thread is done by a class HibernateContext: 5

package hibernate; import java.util.hashtable; import java.util.map; import org.hibernate.session; import org.hibernate.transaction; public class HibernateContext static Map<Thread,HibernateContext> s_contextperthread = new Hashtable<Thread, HibernateContext>(); Session m_currentsession; Transaction m_currenttransaction; public static Session getcurrentsession() HibernateContext hc = getcurrentcontext(true); if (hc.m_currentsession == null) hc.m_currentsession = HibernateUtil.getSessionFactory().openSession(); return hc.m_currentsession; public static Transaction begintransaction() HibernateContext hc = getcurrentcontext(true); if (hc.m_currentsession == null) getcurrentsession(); if (hc.m_currenttransaction == null) hc.m_currenttransaction = hc.m_currentsession.begintransaction(); return hc.m_currenttransaction; public static void commit() HibernateContext hc = getcurrentcontext(false); if (hc == null) return; if (hc.m_currenttransaction!= null) hc.m_currenttransaction.commit(); hc.m_currenttransaction = null; public static void rollback() HibernateContext hc = getcurrentcontext(false); if (hc == null) return; if (hc.m_currenttransaction!= null) hc.m_currenttransaction.rollback(); hc.m_currenttransaction = null; public static void close() HibernateContext hc = getcurrentcontext(false); if (hc == null) return; if (hc.m_currenttransaction!= null) hc.m_currenttransaction.rollback(); if (hc.m_currentsession!= null) hc.m_currentsession.close(); s_contextperthread.remove(thread.currentthread()); System.out.println("HibernateContext - closed"); private static HibernateContext getcurrentcontext(boolean createnewifnotexists) HibernateContext hc = s_contextperthread.get(thread.currentthread()); if (createnewifnotexists == true && hc == null) hc = new HibernateContext(); s_contextperthread.put(thread.currentthread(),hc); return hc; 6

The typical lifecycle within the request processing is: HibernateContext.getCurrentSession() <== the session for querying etc. HibernateContext.beginTransaction() <== start update HiberanateContext.commit() / rollback() HibernateContext.close() <== remove the thread binding and clean up Session Because the methods are static they can be accessed everywhere within the call stack that is processed during a request processing. Of course there should be only limited functions that really are responsible for committing a transaction typically the most outside function that triggers an update. Enforced closing of Session at End of Request Now that during the request processing we made sure that we have a shared Session and a shared Transaction instance due to thread binding, we have to make sure as next step that these shared objects are reliably closed when a request processing is finished. An easy way to do so, is the usage of a servlet filter: package hibernate; import java.io.ioexception; import javax.servlet.filter; import javax.servlet.filterchain; import javax.servlet.filterconfig; import javax.servlet.servletexception; import javax.servlet.servletrequest; import javax.servlet.servletresponse; public class HibernateContextFilter implements Filter public void init(filterconfig config) throws ServletException public void dofilter(servletrequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException try chain.dofilter(request,response); catch(throwable t) finally HibernateContext.close(); public void destroy() Please note: you need to embed servlet-api.jar (typically in tomcat/lib-directory) into your project libraries. The filter just makes sure that at the end of request processing the Hibernate instances 7

are closed. You have to register the filter in your web.xml file: <?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>jsf1</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>hibernate.hibernatecontextfilter</filter-name> <filter-class>hibernate.hibernatecontextfilter</filter-class> </filter> <filter> <filter-name>org.eclnt.jsfserver.util.compressionfilter</filter-name> <filter-class>org.eclnt.jsfserver.util.compressionfilter</filter-class> </filter> <filter-mapping> <filter-name>hibernate.hibernatecontextfilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> Passing Hibernate POJOs into your Screens Now that you can access Hibernate in some structured way, you might look for the best option to directly bind the POJO instances coming from Hibernate into your screen. Example: you may want to render a list of Persons, each person being an instance of calls PersonEntity. 8

The logic for accessing the database is: public static List<PersonEntity> readallpersons(string firstname, String lastname) if (firstname == null) firstname = "%"; else firstname = "%" + firstname + "%"; if (lastname == null) lastname = "%"; else lastname = "%" + lastname + "%"; Session s = HibernateContext.getCurrentSession(); List<PersonEntity> pes = (List<PersonEntity>)s.createQuery ( "from PersonEntity where " + "firstname LIKE '"+firstname+"' and " + "lastname LIKE '"+lastname+"'" ).list(); return pes; The grid of the page is defined / filled in the following way: <t:row id="g_12"> <t:fixgrid id="g_13" height="100%" objectbinding="#d.personenlisteui.grid" sbvisibleamount="25" width="100%"> <t:gridcol id="g_14" text="column" width="100"> <t:label id="g_15" text=".pe.id" /> </t:gridcol> <t:gridcol id="g_16" text="column" width="50%"> <t:label id="g_17" text=".pe.firstname" /> </t:gridcol> <t:gridcol id="g_18" text="column" width="50%"> <t:label id="g_19" text=".pe.lastname" /> </t:gridcol> </t:fixgrid> </t:row> package managedbeans; import hibernate.hibernatecontext; 9

import java.io.serializable; import java.util.list; import javax.faces.event.actionevent; import logic.commitable; import logic.logic; import org.eclnt.editor.annotations.ccgenclass; import org.eclnt.jsfserver.elements.impl.fixgriditem; import org.eclnt.jsfserver.elements.impl.fixgridlistbinding; import org.eclnt.jsfserver.pagebean.pagebean; import org.hibernate.session; import org.hibernate.transaction; import entities.personentity; @CCGenClass (expressionbase="#d.personenlisteui") public class PersonenListeUI extends PageBean implements Serializable public class GridItem extends FIXGRIDItem implements java.io.serializable PersonEntity i_pe; public GridItem(PersonEntity pe) i_pe = pe; public PersonEntity getpe() return i_pe; FIXGRIDListBinding<GridItem> m_grid = new FIXGRIDListBinding<GridItem>(); String m_searchlastname; String m_searchfirstname; // ------------------------------------------------------------------------ // constructors & initialization // ------------------------------------------------------------------------ public PersonenListeUI() public String getpagename() return "/isa/personenliste.jsp"; public String getrootexpressionusedinpage() return "#d.personenlisteui"; public String getsearchlastname() return m_searchlastname; public void setsearchlastname(string value) this.m_searchlastname = value; public String getsearchfirstname() return m_searchfirstname; public void setsearchfirstname(string value) this.m_searchfirstname = value; public FIXGRIDListBinding<GridItem> getgrid() return m_grid; public PersonEntity getnewperson() return m_newperson; public void onsearchaction(actionevent event) fillgrid(); private void fillgrid() m_grid.getitems().clear(); List<PersonEntity> pes = Logic.readAllPersons(m_searchFirstName,m_searchLastName); for (PersonEntity pe: pes) m_grid.getitems().add(new GridItem(pe)); 10

You see: The grid item class refers to the POJO instance (member i_pe ). In the grid column cell definition the properties of the POJO instance are referenced via.pe.<propertyname>. By using the POJO object directly you do not have to repeat all set/get-method definitions on item level, but directly bind the user interface controls to the POJO instance coming from the database. 11