Sample Store Catalog using using Groovy and Grails and the Java Persistence API on Glassfish with MySQL

Sample Store Catalog using using Groovy and Grails and the Java Persistence API on Glassfish with MySQL


I modified this Groovy and Grails  Catalog Sample application to use JPA entity java classes instead of  Groovy domain classes. I followed the steps in this InfoQ article Grails + EJB Domain Models Step-by-Step  and I was really surprised at how easy it was !

download Catalog sample code

Overview of the Technologies and Frameworks in the Sample Application

The Java Persistence API provides a POJO-based persistence model for Java EE and Java SE applications. It handles the details of how relational data is mapped to Java objects, and it standardizes Object/Relational (O/R) mapping.

Grails aims to bring the "coding by convention" paradigm to Groovy. It's an open-source web application framework that leverages the Groovy language and complements Java Web development.

Groovy is an agile and dynamic language for the Java Virtual Machine, it compiles to Java bytecode, and it combines popular features from languages such as Smalltalk, Python, and Ruby.

Grails is a Model-View-Controller based framework that simplifies the development of  web applications by reducing the need for configuration files and by generating a lot of the things needed in a database-backed Web application.

mvc.gif



The Sample Application

The sample application displays an online catalog of pets sold in a pet store. The image below shows the Catalog Listing page, which allows a user to page through a list of items in a store.

listpet.jpg


The Model - JPA Entity Classes

The Model is your application's persistent business domain objects. A JPA Entity instance represents a row in a database table.  Item is an Entity class -- a typical Java Persistence entity object -- which maps to an ITEM table that stores the item instances.

The Item class has a many-to-one relationship with the Address class,  this is specified using the @ManyToOne annotation in the Item class and the @OneToMany(mappedBy = "address") annotation in the Address entity class shown below:


Code Sample from: model\\Item.java
package model;

// import ....

@Entity
@Table(name = "item")
public class Item implements Serializable{
    @Id
    private Long id;
    private String name;
    private String description;
    private String imageurl;
    private String imagethumburl;
    private BigDecimal price;
@ManyToOne(optional = false)
    @JoinColumn(name = "address_id")
    private Address address;

    // getters and setters ...
}



Code Sample from: model\\Address.java
package model;

// import ....

@Entity
@Table(name = "address")

public class Address implements Serializable{
    @Id
    private Long id;
    private String street1;
    private String street2;
    private String city;
    private String state;
    private String zip;
    private BigDecimal latitude;
    private BigDecimal longitude;
    private BigInteger version;
@OneToMany(mappedBy = "address")
    private Collection<Item> items ;

// getters and setters ...

}



classrel.gif

SQL  Sample for items table

CREATE TABLE item (
 id BIGINT NOT NULL,
 product_id BIGINT NOT NULL,
 name VARCHAR(30) NOT NULL,
 description VARCHAR(500) NOT NULL,
 imageurl VARCHAR(55),
 imagethumburl VARCHAR(55),
 price DECIMAL(14,2) NOT NULL,
 address_id BIGINT NOT NULL,
 primary key (id),
 foreign key (address_id) references address(id),
 foreign key (product_id) references product(id)
);



Using the Java Persistence API With Grails and MySQL

Entering the Grails command
> grails create-app catalog
creates a standard directory structure for a grails application named catalog.  After you have your directory structure , to use JPA entities with a grails application:
  1. copy your entity files into the application name\\src\\java directory,  in this case I copied the model.Item and the model.Address  java files into the catalog\\src\\java\\model directory.
  2. copy the MySQL jdbc driver mysql-connector-java-5.1.6-bin.jar into the directory  catalog\\lib .
  3. modify the DataSource.groovy file in the catalog\\grails-app\\conf directory to use MySQL as the data base and  the GrailsAnnotationConfiguration class to use the annotations in the JPA entities as shown below :


    Code Sample from: catalog\\grails-app\\conf\\DataSource.groovy

    import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
    dataSource {
    configClass = GrailsAnnotationConfiguration.class
        pooled = false
    driverClassName = "com.mysql.jdbc.Driver"
        username = "root"
        password = ""
    dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
    }
    hibernate {
        cache.use_second_level_cache=true
        cache.use_query_cache=true
        cache.provider_class='org.hibernate.cache.EhCacheProvider'
    }
    // environment specific settings
    environments {
        development {
            dataSource {
                dbCreate = "update"
    url = "jdbc:mysql://localhost/petcatalog"
            }
        }
        test {
            dataSource {
                dbCreate = "update"
                url = "jdbc:mysql://localhost/petcatalog"
            }
        }
        production {
            dataSource {
                dbCreate = "update"
                url = "jdbc:mysql://localhost/petcatalog"
            }
        }
    }                       


  4. In order for Grails to recognize the JPA Entity classes as domain classes,  add the hibernate.cfg.xml file shown below to the catalog\\grails-app\\conf\\hibernate directory:


    Code Sample from: catalog\\grails-app\\conf\\hibernate\\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>
            <mapping package="model" />
            <mapping class="model.Item" />
            <mapping class="model.Address" />
        </session-factory>
    </hibernate-configuration>

The Controller

Entering the Grails command  (in the directory catalog)
> grails generate-controller model.Item
will generate the ItemController.groovy   class for the model.Item entity class.

Controllers handle incoming http requests, interact with the model to get data and to process requests,  invoke the correct view, and direct domain data to the view for display.  In Grails, http requests are handled by Controller classes which are made up of one or more action methods that are executed on request and then either render a Groovy Server Page or redirect to another action. Grails routes requests to the controller action which corresponds to the URL mapping for the request. In Grails the default mapping from URL to action method follows this convention: http://host/app/controller/action/id .  For example the URL http://host/catalog/item/list calls the list action method in the item controller class shown below.     Grails Scaffolding provides a series of standardized Controller action methods for listing, showing, creating, updating, and deleting objects of a class.  These standardized actions come with both controller logic and default view Groovy Server Pages. The ItemController list action renders a view with a paginated list of item objects.

Code Sample from: grails-app\\controllers\\ItemController.groovy

class ItemController {

def index = { redirect(action:list,params:params) }

  def list = {
    if(!params.max) params.max = 10
    [ itemList: Item.list( params ) ]
  }
. . .


When a URL has a controller but no action (e.g. http://localhost:8080/catalog/item/  ), Grails defaults to the index action. In the ItemController code the  index action method redirects to the list action.  The ItemController list action method calls the Item.list() method which returns an ArrayList of item objects retrieved from the item database table . If there are more than params.max objects in the table, Grails creates next and previous pagination links automatically. The itemList variable  is automatically made available to the view by the framework.

After executing code, actions usually render a GSP in the views directory corresponding to the name of the controller and action, for example the list action will render the grails-app\\views\\item\\list.gsp .

The View

Entering the Grails command  (in the directory catalog)
> grails generate-views model.Item
will generate the create.gsp , edit.gsp, list.gsp, show.gsp  groovy server pages for the model.Item entity class.
The view layer generates a web page, using data from domain objects provided by the controller. In Grails, the view is rendered using Groovy Server Pages. Below is part of the list.gsp for the Catalog application (note I modified the html table format from the default generated).


Code Sample from: grails-app\\views\\item\\list.gsp

<table>
   <thead>
     <tr>
<g:sortableColumn property="name" title="Name" />
        <g:sortableColumn property="imagethumburl" title="Photo" />
        <g:sortableColumn property="price" title="Price" />
     </tr>
   </thead>
   <tbody>
<g:each in="${itemList}" status="i" var="item">
        <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
           <td>
<g:link action="show" id="${item.id}">
                ${item.name?.encodeAsHTML()}</g:link>
           </td>
           <td>
             <img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
           </td>
           <td>${item.price?.encodeAsHTML()}</td>
        </tr>
     </g:each>
  </tbody>
 </table>

<div class="paginateButtons">
<g:paginate total="${Item.count()}" />
</div>


The view uses instance variables set by the controller to access the data it needs to render the GSP.

GSP has a GroovyTagLib similar to the  JSP tag library. <g: are GroovyTags.

<g:sortableColumn
       The sortableColumn tag renders a sortable column to support sorting in tables.

<g:each in="${itemList}" status="i" var="item">
loops through each object in the itemList variable, which is an ordered ArrayList of Item model objects,  and assigns each Item model object to the item variable.

<g:link action="show" id="${item.id}">${item.name?.encodeAsHTML()}</g:link>
the <g:link> GroovyTag creates an html anchor tag href based on the action, id, controller parameters specified. In this example it generates a link to the item/show/id action which when clicked will display the corresponding item details. For example this line will generate the following HTML for the variable item:
<a href="/catalog/item/show/2">Friendly Cat</a>
<img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
The createLinkTo tag generates an HTML link for the item's imagethumburl attribute. 

${item.price?.encodeAsHTML()}
displays the value of the  item 's price attribute as escaped HTML text.

<g:paginate total="${Item.count()}" />
The paginate tag creates next/previous buttons and a breadcrumb trail to allow pagination of results using the Item.count() domain method.

The Show Action Method

In Grails the mapping for the URL http://host/item/show/1  ( http://host/controller/action/id )  will route to the show action in the ItemController passing 1 to the method as the id of the params parameter hash. The show action of the ItemController class is shown below. The ItemController show action renders a view showing the details of the item object corresponding to the id parameter.

Code Sample from: grails-app\\controllers\\ItemController.groovy

 def show = {
   def item = Item.get( params.id )

   if(!item) {
      flash.message = "Item not found with id ${params.id}"
      redirect(action:list)
   }
   else { return [ item : item ] }
 }



The show action method  calls the Item.get() method which queries the items table returning the item instance variable corresponding to the item with the attribute id (primary key) equal to the  id parameter. This is the equivalent of the following sql : select \* from items where id='1' . The item variable is automatically made available to the Show view by the framework.

The Show View GSP

After executing code in the action, the show action renders the app/views/item/show.gsp . Below is the GSP for the item show view :


Code Sample from: grails-app\\views\\item\\show.gsp

<h2> Detail of item</h2>

<table>
<tbody>
    <tr class="prop">
      <td valign="top" class="name">Name:</td>                          
      <td valign="top" class="value">${item.name}</td>                          
    </tr>                   
    <tr class="prop">
        <td valign="top" class="name">
           Description:
        </td>                           
        <td valign="top" class="value">
           ${item.description}
        </td>                          
    </tr>                       
    <tr class="prop">
        <td valign="top" class="name">Imageurl:</td>                          
        <td valign="top" class="value">
            <img src="${createLinkTo(dir:'images',file:item.imageurl)}" />
        </td>                           
    </tr>                                           
    <tr class="prop">
        <td valign="top" class="name">Price:</td>                           
        <td valign="top" class="value">$ ${item.price}</td>                           
    </tr>
    <tr class="prop">
        <td valign="top" class="name">Address:</td>                           
        <td valign="top" class="value">
          ${item?.address?.street1}, ${item?.address?.city},    
          ${item?.address?.state}
        </td>                          
    </tr>                       
</tbody>
</table>  



${item.description}
displays the value of the  item 's description attribute.
<img src="${createLinkTo(dir:'images',file:item.imageurl)}" />
generates an HTML image tag for the item's imageurl attribute.
${item?.address?.city}
displays the value of the  item's address city attribute.

The image below shows the resulting page for the url http://host/catalog/item/show/105, which displays the item 105's details:

showpet.jpg

Layouts

Grails layouts  let you put common html on multiple views (for example page headers,  footers, sidebars).  Default layout templates are in the views layouts directory with a file name corresponding to the controller, or you can associate a view with a layout using the "layout" meta tag to your page:
<meta name="layout" content="main">
To add a title and parrot image to the top of the Pet Catalog pages, I put this table in the app\\views\\layouts\\main.gsp  layout:

Code Sample from: app/views/layouts/main.gsp

<table>
  <tr>
   <td>Pet Catalog</td>
   <td>
     <img src="${createLinkTo(dir:'images',file:'pet_logo.jpg')}"/>
   </td>
 </tr>
</table>




Conclusion
This concludes the sample application which demonstrates how to work with Groovy and Grails  to page through a list of  Item JPA Entities which are retrieved using Item Controller action methods, and displayed using Item View GSPs.

Setting Things Up and Running the Sample code on MySQL and Jetty:

  1. If MySQL is already installed, then download GlassFish v2 UR1. Otherwise you can also Download GlassFish v2 UR1 and MySQL co-bundle from the usual Download Page (instructions).

  2. Download and install Grails.

  3. Download the sample code and extract its contents. You should now see the newly extracted directory as <sample_install_dir>/Catalog, where <sample_install_dir> is the directory where you unzipped the sample package. For example, if you extracted the contents to C:\\ on a Windows machine, then your newly created directory should be at C:\\Catalog
    The file  "/Catalog/grails-app/conf/DataSource.groovy" is configured for a MySQL configuration.

  4. Start the MySQL database as follows:

    • > mysqld_safe --user root --console

  5. Create the pet-catalog database:

    • > mysqladmin create petcatalog --user root

  6. Create the tables in the MySQL pet-catalog database as follows:

    • shell> mysql pet-catalog < catalog.sql
    • using the file catalog.sql file from the /Catalog directory.

  7. Run the project as follows:
    in a command window in the /Catalog directory enter the command
  8. > grails run-app
    This will run the Application using the built-in Jetty Servlet engine.
When you run the project, your browser should display the Catalog home page at http://localhost:8080/catalog/ .


Run the Sample code on Glassfish:
  1. Use the  WAR file in <sample_install_dir>/Catalog/Catalog.war or Create a WAR file:
    • > grails war
  2. Copy the WAR file (catalog-0.1.war) to  your Glassfish installation "domains/domain/autodeploy" directory. (Start Glassfish and MySQL if you haven't already)

  3. Enter the URL  http://localhost:8080/catalog-0.1/  in your browser, you should see the home page of the Sample Application.

For more information:

Comments:

Post a Comment:
Comments are closed for this entry.
About

caroljmcdonald

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today