Java Database Development for web applications

Introduction

In this article I will explain why you should not
develop in java as some people do it with perl or php. I will show you
why it is useful to separate dababase and application logic and
finally what technologies you may use.

In terms: You will find information about Object
Relational Mapping, Multi-Tier development, and persistence
technologies like Enterprise Java Beans and Hibernate.

Table
of Contents

Java Database Development for web
applications 1

Introduction 1

Bad use of db access in web script
development 1

Use classes instead of resultSets
(Object relational mapping) 2

Stop writing create, edit, delete
statements (persistence technologies) 3

Available persistence technologies 4

EJB (Enterprise
Java Beans) ( Sun ) 4

Hibernate (Open
Source) 5

JDO (mostly
professional solutions) 7

Choosing your persistence technology 7


Bad use of db access in web script
development

Some people develop their web applications with
script languages which may directly be included in the source code.
The source for a page, that lists books, looks like

&lt;html&gt;&lt;head&gt;&lt;title&gt;Important title&lt;/title&gt;&lt;/head&gt;<br>&lt;body&gt;<br>&lt;someScript&gt;<br>dbConnection = openDBConnection(someDB)<br>resultSet = dbConnection.executeQuery('select bookName from books')<br>loop over resultSet{<br> print (resultSet.field('bookName') + '&lt;br&gt;')<br>}<br>&lt;/someScript&gt;<br>&lt;/body&gt;&lt;/html&gt;




You can develop the same way using java servlets. But
this way to development is only suitable for tiny projects. Imagine
you have 70 dialogs, lots of queries and you want to add a status
field to your book table indicating if a book is deleted or not. You
will have to look through all your dialogs.


This is where Multi Tier development starts. A first
step is to get the db queries out of the dialogs. Using Servlets for
your dialogs, you can implement this by a central class providing all
queries you need. In our example this class is named
LibraryBusinessLogic.






Example
source code of a java servlet:

protected void doGet(HttpServletRequest request, HttpServletResponse response)<br>      throws ServletException, IOException {<br>    PrintWriter out = response.getWriter();<br>    out.print("&lt;html&gt;&lt;head&gt;&lt;title&gt;My Servlet&lt;/title&gt;&lt;/head&gt;&lt;body&gt;");<br>    // [laliluna] 09.11.2004 create instance of my business logic class<br>    LibraryBusinessLogic libBL = new LibraryBusinessLogic();<br>    ResultSet books = libBL.getAllBooks();<br>    try {<br>      while (books.next())<br>        out.print(books.getString('name'));<br>    } catch (SQLException e) {<br>      e.printStackTrace();<br>    }<br>  }

Use classes instead of resultSets (Object relational mapping)


The disadvantage from our example above is that we
have to know what the database looks like and how the fields are
spelled. We have no error message from the Development Environment
showing that a call to a resultSet like

books.getString(‘badName’)

is wrong. Only at run time we can see the problem.
There is a easy solution to this problem, it is called object
relational mapping. Instead of working directly with a result set
from a query, you copy each entry of the result set to a java class.







Our class LibraryBusinessLogic is doing something
more now:

Our servlet looks a little different now:

  protected void doPost(HttpServletRequest request, HttpServletResponse response)<br>      throws ServletException, IOException {<br>    PrintWriter out = response.getWriter();<br>    out.print("&lt;html&gt;&lt;head&gt;&lt;title&gt;My Servlet&lt;/title&gt;&lt;/head&gt;&lt;body&gt;");<br>    // [laliluna] 09.11.2004 create instance of my business logic class<br>    LibraryBusinessLogic libBL = new LibraryBusinessLogic();<br>    List books = libBL.getAllBooks();<br>    for (Iterator iter = books.iterator(); iter.hasNext();) {<br>      Book book = (Book) iter.next();<br>      out.print("Bookname: " + book.getName() + "&lt;br&gt;");<br>    }<br>  }

This is nice, isn’t it?


So let’s go on to improve our database development
style.


Stop writing create, edit, delete
statements (persistence technologies)


In an average application: What do you think how much
percent of the queries do only create/update/delete an entry in a
table?


Do you think that it should be your job to write
these tedious statements? Then help is close to you. Persistence
technologies do exactly what you need.

Persistence = write data to somewhere where it can
stay for ever, normally a database

Based on a class and a description file (often in
xml) of the table mapping, the persistence technology knows from
which table it has to read the data.

Loading classes from the database looks like

Query query = session.createQuery("select b from Bug as b");<br>      for (Iterator iter = query.iterate(); iter.hasNext();) {<br>        bugs.add((Bug) iter.next());<br>      }<br>    return bugs;

saving a bug to the database looks like


session.update(bug);





There are as far as I know, three major persistence
technologies available:


They do not only provide persistence but also
functionalities like caching, Business logic on the application
server, clustering, recover strategies, transaction management,
database connection pooling and much more.

They do a lot for you. And in my humble opinion, when
you develop any kind of application with database access, you should
use persistence technology.

Available persistence technologies

EJB (Enterprise Java Beans) (�
Sun )

EJBs are probably the standard technology to persist
(save) classes to databases. Every application server supporting J2EE
provides native functionality for EJBs.

The general structure of a J2EE application is
displayed below.

The Entity EJBs (persistence part) are only one type
of EJBs. There are also Session Beans to provide the business logic.







For an entity bean you need the class, the interfaces
and an xml description file. The interfaces give access to the class
and its corresponding database entry. The xml description file is to
let the application server know to which table he has to map the
class and to which column a field.







When you use create an entry in the database with an
entity EJB you will do the following steps

When you want to read an existing value from the
database you use the home interface again and call the
findByPrimaryKey method. This method will return the interface with
which you can change the values of your data entry.

This is not very complicated in the end.

When you develop an entity EJB you have to

Below you can see an example for a mapping
description:

&lt;entity &gt;<br> &lt;description&gt;&lt;![CDATA[SimpleBean EJB]]&gt;&lt;/description&gt;<br> &lt;display-name&gt;SimpleBean&lt;/display-name&gt;<br><br> &lt;ejb-name&gt;SimpleBean&lt;/ejb-name&gt;<br><br> &lt;home&gt;de.laliluna.tutorial.simpleBean.interfaces.SimpleBeanHome&lt;/home&gt;<br> &lt;remote&gt;de.laliluna.tutorial.simpleBean.interfaces.SimpleBean&lt;/remote&gt;<br> &lt;local-home&gt;de.laliluna.tutorial.simpleBean.interfaces.SimpleBeanLocalHome&lt;/local-home&gt;<br> &lt;local&gt;de.laliluna.tutorial.simpleBean.interfaces.SimpleBeanLocal&lt;/local&gt;<br><br> &lt;ejb-class&gt;de.laliluna.tutorial.simpleBean.ejb.SimpleBeanCMP&lt;/ejb-class&gt;<br> &lt;persistence-type&gt;Container&lt;/persistence-type&gt;<br> &lt;prim-key-class&gt;java.lang.String&lt;/prim-key-class&gt;<br> &lt;reentrant&gt;False&lt;/reentrant&gt;<br> &lt;cmp-version&gt;2.x&lt;/cmp-version&gt;<br> &lt;abstract-schema-name&gt;SimpleBean&lt;/abstract-schema-name&gt;<br> &lt;cmp-field &gt;<br>    &lt;description&gt;&lt;![CDATA[]]&gt;&lt;/description&gt;<br>    &lt;field-name&gt;id&lt;/field-name&gt;<br> &lt;/cmp-field&gt;<br> &lt;cmp-field &gt;<br>    &lt;description&gt;&lt;![CDATA[]]&gt;&lt;/description&gt;<br>    &lt;field-name&gt;name&lt;/field-name&gt;<br> &lt;/cmp-field&gt;<br> &lt;primkey-field&gt;id&lt;/primkey-field&gt;<br>&lt;/entity&gt;




The creation of the interfaces and the description
file is a tedious task. It is a good idea to use MyEclipse because it
generates all this for you. You only have to implement the class.


Hibernate (Open Source)


Hibernate is a object/relational persistence and
query service for Java. Comparing to EJB technology it is the
alternative to Entity EJBs. It this does not provide a business logic
part like the session beans but of course (and this is a good idea)
you can implement the business logic with session beans and use
hibernate in the session beans instead of entity beans.


What is nice and in my opinion an advantage over
entity beans, hibernate starts from simple java classes (Pojo = Plain
Old Java Objects).


To use hibernate you will create a simple java class:


public class Bug
implements Serializable
{
private int hashValue = 0;
private java.lang.Integer id;
private java.lang.String title;

public AbstractBug()
{
}
public AbstractBug(java.lang.Integer fid)
{
this.setId(fid);
}
public java.lang.Integer getId() {
return id;
}
public void setId(java.lang.Integer id) {
this.id = id;
}
public java.lang.String getTitle() {
return title;
}
public void setTitle(java.lang.String title) {
this.title = title;
}
………….





Than you create a mapping file which is the
equivalent to the EJB mapping file.





<hibernate-mapping package=“de.laliluna.fehlerbehebung”>
<class name=“Bug” table=“bug”>
<id name=“id” column=“fid” type=“java.lang.Integer”>
<generator class=“sequence”>
<param name=“sequence”>public.bug_fid_seq</param>
</generator>
</id>
<property name=“title” column=“ftitle” type=“java.lang.String” />
</class>
</hibernate-mapping>





And you start using your hibernate class.


Example to create a new entry in the database:


    try {
Bug bug = new Bug();
bug.setTitle(“Title”);
bug.setTuserFk(tuser);
Transaction tx = session.beginTransaction();
session.save(bug);
tx.commit();
} catch (HibernateException e) {
e.printStackTrace();
}





There is no need for any interfaces like with EJBs.


The creation of the description file can be done with
tools like MyEclipse. MyEclipse provides functionality to create
classes and description files directly from database tables.


Hibernate includes tools to

A development speed is very high using hibernate.

JDO (mostly professional solutions)

I have to apologize myself, but I do not have any
practical experience with JDO and I do not want to copy any
information I cannot approve. It is supposed to be somewhere in the
middle between Hibernate and EJB but closer to Hibernate.;-)

What I saw before about JDO it is really very close
to Hibernate. There is a JDO standard the companies follows. The
most solutions are payable and I question if it is useful to buy
something when you can use well established technologies like Entity
EJBs or Hibernate.

Choosing your persistence technology

EJB is the standard, hibernate is the more flexible
nice guy.





EJB persistence

Hibernate persistence


Standard solution


Natively integrated in all J2EE servers


Optimizations directly available from the
application server


Monitoring Tools and everything you need


Object oriented query language EJB-QL is
limited.

Probably most popular open source persistence
technology

Very sophisticated mapping technology
(polymorphism, composition, …)

Works with all application servers, even with
servlet application servers (Tomcat).

Object oriented query language is more complete
than EJB-QL

No problems using SQL directly

We used EJBs a lot but there are a lot of things why
I prefer Hibernate in most but not in all projects now. One thing is
sure, you can use both technologies for most development projects. It
depends on your focus. When the native support of EJB is important to
you and you want to use the monitoring tools of your application
server, you should go for EJB technology.

When you want to be less limited by the query
language and want to use sophisticated mappings, your choice is
probably Hibernate. When you want something less complex and you are
a beginner, you should also go for hibernate.

As stated before, you may use Session EJBs for
Business Logic and Hibernate to persist data. So these two
technologies are not completely exclusive. Try our little tutorials
to get a impression of both technologies and take your choice later.

I hope I could help you a little bit.


Sebastian

http://www.laliluna.de