Differences between revisions 4 and 5
Revision 4 as of 2009-04-16 15:10:22
Size: 8925
Editor: ftp
Comment: Removed generic maven javac mumble, replaced with link to more covering article.
Revision 5 as of 2009-09-20 22:12:08
Size: 8945
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 7: Line 7:
 * [http://www.springframework.org Spring framework] 2.5.6
 * [http://www.hibernate.org Hibernate]
 * [[http://www.springframework.org|Spring framework]] 2.5.6
 * [[http://www.hibernate.org|Hibernate]]
Line 46: Line 46:
If you want to use generics in your project you need to configure the java compiler plugin used by maven. One example can be found at near bottom of [http://www.javaworld.com/javaworld/jw-12-2005/jw-1205-maven.html?page=3 page three of JavaWorld's Maven 2 Introduction] article. If you want to use generics in your project you need to configure the java compiler plugin used by maven. One example can be found at near bottom of [[http://www.javaworld.com/javaworld/jw-12-2005/jw-1205-maven.html?page=3|page three of JavaWorld's Maven 2 Introduction]] article.
Line 80: Line 80:
To add (latest) hibernate dependencies you'll need to [http://www.hibernate.org/422.html add JBoss release repository] as well. To add (latest) hibernate dependencies you'll need to [[http://www.hibernate.org/422.html|add JBoss release repository]] as well.
Line 135: Line 135:
Generic DAO implementation will save you a lot of trouble, essentially providing you with CRUD -operations with the cost of one constructor parameter. IBM has a nice article on [http://www.ibm.com/developerworks/java/library/j-genericdao.html not repeating code with DAOs], there are lot of more articles around, to name a few:
 * [http://www.hibernate.org/328.html Generic Data Access Objects] at hibernate.org
 * [http://blog.hibernate.org/Bloggers/GenericDAOPatternWithJDK50 Generic DAO Pattern With JDK 5.0] at inrelation.to
 * [http://code.google.com/p/hibernate-generic-dao/ hibernate-generic-dao] project
Generic DAO implementation will save you a lot of trouble, essentially providing you with CRUD -operations with the cost of one constructor parameter. IBM has a nice article on [[http://www.ibm.com/developerworks/java/library/j-genericdao.html|not repeating code with DAOs]], there are lot of more articles around, to name a few:
 * [[http://www.hibernate.org/328.html|Generic Data Access Objects]] at hibernate.org
 * [[http://blog.hibernate.org/Bloggers/GenericDAOPatternWithJDK50|Generic DAO Pattern With JDK 5.0]] at inrelation.to
 * [[http://code.google.com/p/hibernate-generic-dao/|hibernate-generic-dao]] project
Line 148: Line 148:
 * [http://www.ibm.com/developerworks/java/library/j-ts1.html Understanding Transaction Pitfalls] at ibm.com
 * Spring reference documentation on [http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html transaction management]
 * [[http://www.ibm.com/developerworks/java/library/j-ts1.html|Understanding Transaction Pitfalls]] at ibm.com
 * Spring reference documentation on [[http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html|transaction management]]

Using Derby on Tomcat Webapp built on Spring and Hibernate

Preface

This tutorial covers the steps you need to setup a multitierable web-app project with the following ingredients:

The point of making this tutorial was that the only tutorials I've been able to find usually deal with previous versions of the above and there might or might not be problems with more recent ones.

Note that this tutorial assumes you've got some basics of Java software development and maven already. I've done this all using Eclipse Ganymede r2 on Linux with m2eclipse plugin. It might be doable with others as well.

Other note; I'm no master of maven, there might be public archetypes for this already floating somewhere, linking them here might help people to get started.

Starting up

Project structure

Our example project consists of the following parts:

  • exproject (maven site project, root of our project hierarchy)
    • exproject-core (entities, daos, services)
    • exproject-webapp (webapp which we are deploying on tomcat)

Setting it all up

In eclipse with m2eclipse, you'd start by taking a clean new workspace and go:

  1. File -> New -> Other... -> Maven project

  2. Select the "Create a simple project" checkbox, hit "Next >"

  3. Fill in the artifact identification and hit "Finish" afterwards:
    • Group id: org.example.exproject

    • Artifact id: exproject

    • Packaging: pom

After a while you'll got yourself a new project; quickly add the two modules (exproject-core, exproject-webapp) to it by selecting the "exproject" in Project Explorer, selecting "Maven > New Maven Module Project" from the context menu. Fill the wizard as mentioned above but use packaging jar for exproject-core and packaging war for exproject-webapp.

Post processing

By default the pom -files have explicit versions on each; however I've found it easier to have the modules inherit the version numbers. You can accomplish this by removing version -elements straight under the project -element (not under the parent -element!).

If you want to use generics in your project you need to configure the java compiler plugin used by maven. One example can be found at near bottom of page three of JavaWorld's Maven 2 Introduction article.

Adding dependencies

Hint on maintaining correct versions of your dependencies: Put them under properties like (add under project -element in exproject/pom.xml):

<properties>
  <derby.version>10.4.2.0</derby.version>
</properties>

You can then refer to them as with ${derby.version}.

Derby

To include derby in your core project add the following (add under project -element in exproject/exproject-core/pom.xml):

<dependencies>
  <dependency>
    <groupId>org.apache.derby</groupId>
    <artifactId>derby</artifactId>
    <version>${derby.version}</version>
    <scope>test</scope> <!-- this means derby will only be available for 
                             testing in exproject-core, will not be included 
                             to other projects using exproject-core 
                             as dependency -->
  </dependency>
</dependencies>

If you want to use derby over network, you should add artifact derbyclient instead of derby.

Others

To add (latest) hibernate dependencies you'll need to add JBoss release repository as well.

Spring framework is available as one huge chunk and as many smaller parts, for beginner it might be easier to just use artifact "spring-full" under group "org.springframework".

Actual work (exproject-core)

Entities

(TODO: link to annotations docs)

In this example we have two simple entities, Parent and Child. You can probably guess their relationship.

   1 package org.example.exproject.domain.entities;
   2 
   3 // imports omitted
   4 
   5 @Entity(name="parent")
   6 public class Parent {
   7   @Id
   8   private Long id;
   9   
  10   @OneToMany(cascade=CascadeType.ALL, targetEntity=Child.class)
  11   private Set<Child> children;
  12 
  13   // getters and setters omitted
  14 }

   1 package org.example.exproject.domain.entities;
   2 
   3 // imports omitted
   4 
   5 @Entity(name="child")
   6 public class Child {
   7   @Id
   8   private Long id;
   9   
  10   @ManyToOne(cascade=CascadeType.ALL)
  11   private Parent parent;
  12 
  13   // getters and setters omitted
  14 }

DAO's

(TODO: simple daos, links to documentation)

DAO -layer provides simple CRUD like operations to your database. While we are using Hibernate in this example it's generally a good idea to build your DAO interfaces so that you could later add a JDBC backend if you need or want. Though, there might be a point in encapsulating some logic also to DAO -layer which will open possibilities like implementing the logic in derby itself.

Spring framework provides abstract HibernateDaoSupport -class which will make your Hibernate DAO -code consist mostly of one-liners.

Generic DAO implementation will save you a lot of trouble, essentially providing you with CRUD -operations with the cost of one constructor parameter. IBM has a nice article on not repeating code with DAOs, there are lot of more articles around, to name a few:

Services

(TODO: simple generic crud service)

Service layer adds logic that uses your DAO interfaces to provide your business logic and handles transaction creation and commits. With Spring a @Transactional -annotation and some configuration (in the next section) Spring will arrange creation and committing for you without any boilerplate code.

As with generic dao's you migth find the need to implement yourself a Generic Service as well to provide simplest CRUD functionality by just delegating methods over to your generic dao. This again, will let your ParentService implementation focus on the real business logic.

@Transactional has some pitfalls as well, some recommended reading:

Configuring

(TODO: Spring context:component-scan, context:annotation-config, tx:annotation-driven)

Testing on derby

(TODO: create/upload schema with hbm2ddl.auto, simple crud testing, datasource)

Actual work (exproject-webapp)

Simple controller and view skeleton

(TODO: example)

!ServletContextListener

(TODO: links to documentation, derby.system.home property)

ServletContextListener is interface defines methods for listeners that need to act when ServletContext is getting started and stopped. For embedded derby users this means the following:

  1. The database might need to be created
    • Mostly likely only when developing :)

  2. Derby has to be shut down when the web application is shut down
    • To prevent nasties like data loss, corruption

Creating a database with derby is simple; just open a JDBC connection to jdbc:derby:myDatabaseNameComesHere;create=true. If the database was already created the connection will report an !SQLWarning with !SQLState 01J01 (link to derby manual).

Shutting down a single database is equally simple; just open a JDBC connection to jdbc:derby:myDatabaseNameComesHere;shutdown=true.

However as we'll be using tomcat and your database will be the only one, we'll be more interested in shutting down whole derby embedded RDBMS. This can be accomplished by connecting to jdbc:derby:;shutdown=true.

I'm not sure if there's a simple "DerbyUtil" class already providing static methods such as

  • createDatabase(String name)
  • shutdown(String dbName)
  • shutdown()

... but implementing your own and using it in your servlet context listener class might serve as a good exercise.

Servlet context listeners are hooked up to your web application by adding them by class name to web.xml as explained in the next section.

Configuration

(TODO: context:component-scan, datasource, web.xml)

Launching

(TODO: ...)

DerbyOnTomcatWithSpringHibernate (last edited 2009-09-20 22:12:08 by localhost)