Sample Store Catalog using using Groovy and Grails and the Java Persistence API on Glassfish with MySQL
http-equiv="content-type">
Sample Store Catalog using using Groovy and Grails and the Java
Persistence API on Glassfish with MySQL
I modified this
href="http://weblogs.java.net/blog/caroljmcdonald/archive/2008/04/sample_store_ca.html">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
href="http://www.infoq.com/articles/grails-ejb-tutorial">Grails + EJB
Domain Models Step-by-Step and I was really surprised at how
easy it was !
href="https://techdayscode.dev.java.net/servlets/ProjectDocumentList?folderID=9118&expandFolder=9118&folderID=9118">
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.
src="http://weblogs.java.net/blog/caroljmcdonald/archive/mvc.gif"
style="width: 304px; height: 334px;">
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.
height="532" width="353">
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
style="color: rgb(153, 0, 0);">@ManyToOne annotation inthe
Itemclass and the
style="font-weight: bold; color: rgb(153, 0, 0);">@OneToMany style="color: rgb(153, 0, 0);">(mappedBy = "address") annotationin the
Addressentity class shown below:
|
|
| Code Sample from:
style="font-weight: bold;">model\Item.java |
|
package model;
// import ....
@Entity
@Table(name = "address")public class style="color: rgb(0, 0, 153); font-weight: bold;">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;
style="font-weight: bold; color: rgb(153, 0, 0);">@OneToMany style="color: rgb(153, 0, 0);">(mappedBy = "address")
private Collection< style="color: rgb(0, 0, 153); font-weight: bold;">Item> style="color: rgb(0, 0, 153); font-weight: bold;">items ;
// getters and setters ... style="color: rgb(0, 0, 153); font-weight: bold;">
}
src="http://weblogs.java.net/blog/caroljmcdonald/archive/classrel.gif"
height="134" width="274">
| SQL Sample for items table
style="font-family: monospace;"> |
|
Using the Java Persistence API With Grails and MySQL
Entering the Grails command
[prettify]> grails create-app catalog[/prettify]
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:
- copy your entity files into the application name
style="font-weight: bold;">\src\java
directory, in this case I copied the model.Item and the
model.Address java files into the catalog\src\java\model
directory. - copy the MySQL jdbc driver mysql-connector-java-5.1.6-bin.jar
into the directory catalog\lib
. - modify the DataSource.groovy
file in the catalog\grails-app\conf
directory to use MySQL as the data base and theGrailsAnnotationConfiguration
class to use the annotations in the JPA entities as shown below :
cellspacing="0">
Code Sample from: catalog\grails-app\conf style="font-weight: bold;">\DataSource.groovy
import
org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
dataSource {
style="font-weight: bold; color: rgb(153, 0, 0);">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"
style="font-weight: bold;">url = "jdbc:mysql://localhost/petcatalog"
}
}
test {
dataSource {
dbCreate =
"update"
url =
"jdbc:mysql://localhost/petcatalog"
}
}
production {
dataSource {
dbCreate =
"update"
url =
"jdbc:mysql://localhost/petcatalog"
}
}
}
- 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:
cellspacing="0">
Code Sample from: catalog\grails-app\conf\hibernate style="font-weight: bold;">\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)generate-controller class="userinput">> grailsmodel.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/
style="font-weight: bold;">app/controller/action/id . For
example the URL http://host/catalog/item/list
calls the
list
style="font-family: monospace; font-weight: bold;">
style="color: rgb(0, 0, 153);">
style="font-weight: bold;">action method in the
style="font-weight: bold;"> item controller
style="font-family: monospace;">
style="color: rgb(0, 0, 153); font-weight: bold;">class
shown below.
href="http://grails.codehaus.org/Scaffolding">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
style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
style="color: rgb(0, 0, 153); font-weight: bold;">list
action renders a view with a paginated list of item objects.
| Code Sample from: grails-app\ style="font-weight: bold;">controllers\ItemController.groovy |
class ItemController { def index = { redirect(action:list,params:params) } style="font-family: monospace;"> 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
style="font-weight: bold;">
style="font-family: monospace;">
style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
code the
style="color: rgb(0, 0, 153); font-weight: bold;">
style="font-family: monospace;">
style="color: rgb(0, 0, 153); font-weight: bold;">index
action method redirects to the
style="color: rgb(0, 0, 153); font-weight: bold;">list
action. The
style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
style="color: rgb(0, 0, 153); font-weight: bold;">list action
method calls the
style="color: rgb(0, 0, 153); font-weight: bold;">Item.list() method
which returns an ArrayList of item objects retrieved from the item
database table . If there are more than
style="font-family: monospace;">params.max objects in the
table, Grails creates next and previous pagination links automatically.
The itemList
style="font-family: monospace;"> 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)
[prettify]> grails generate-views model.Item[/prettify]
will generate the create.gsp ,
edit.gsp, list.gsp, show.gsp groovy server pages for the
style="font-weight: bold;">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
href="http://docs.codehaus.org/display/GRAILS/Developer+-+Groovy+Server+Pages">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\
style="font-weight: bold;">views\item\list.gsp |
|
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:sortableColumnThe href="http://grails.codehaus.org/GSP+Tag+-+sortableColumn">sortableColumn
tag renders a sortable column to support sorting in tables.
<g:each
in="${itemList}" status="i"
var="item">itemList
style="font-family: monospace;"> variable,which is an ordered style="font-weight: bold;">ArrayList of
style="color: rgb(0, 0, 153); font-weight: bold;">Item modelobjects, and assigns each
style="color: rgb(0, 0, 153); font-weight: bold;">Itemmodel object to the
style="color: rgb(0, 0, 153); font-weight: bold;">item variable.<g:link
action="show"
id="${item.id}">${item.name?.encodeAsHTML()}</g:link>
href="http://grails.org/doc/1.0.x/ref/Tags/link.html">the
<g:link> GroovyTag creates an html anchor tag hrefbased on the
action, id, controllerparameters 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 class="attribute-name"> href="/catalog/item/show/2">Friendly Cat</ class="end-tag">a>
<img
src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
style="color: rgb(0, 0, 153); font-weight: bold;">
tag generates an HTML link for the
item's
imagethumburl style="color: rgb(0, 0, 153); font-weight: bold;">attribute.
${item.price?.encodeAsHTML()}
style="color: rgb(0, 0, 153); font-weight: bold;">item 's price attributeas
escaped HTML text.
<g:paginate
total="${Item.count()}" />
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
class="attribute-value">/item/show/1 (
http://host/controller/action/id
) will
route to the
style="color: rgb(0, 0, 153); font-weight: bold;">show
action in the
style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
passing 1 to the method as the
style="color: rgb(0, 0, 153); font-weight: bold;">id of
the
style="color: rgb(0, 0, 153); font-weight: bold;">params parameter
hash. The
style="color: rgb(0, 0, 153); font-weight: bold;">show
action of the
style="color: rgb(0, 0, 153); font-weight: bold;">ItemController class
is shown below. The
style="color: rgb(0, 0, 153); font-weight: bold;">ItemController
style="color: rgb(0, 0, 153); font-weight: bold;">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 = style="color: rgb(0, 0, 153); font-weight: bold;">Item.get( style="color: rgb(0, 0, 153); font-weight: bold;">params.id ) if(!item) { flash.message = "Item not found with id ${params.id}" redirect(action:list) } else { return [ item : item ] } } |
The
style="color: rgb(0, 0, 153); font-weight: bold;">show
action method calls the
style="color: rgb(0, 0, 153); font-weight: bold;">Item.get()
style="color: rgb(0, 0, 153); font-weight: bold;">
style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">method
which queries the items table returning the style="font-family: monospace;"> style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">item instance
variable corresponding to the item with the attribute style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">id
(primary key)
equal to the style="color: rgb(0, 0, 153); font-weight: bold;">id
parameter. This is the equivalent of the following sql : style="font-family: monospace;">select * from items where id=' style="font-family: monospace;"> style="color: rgb(0, 0, 153); font-weight: bold;">1' .
The style="color: rgb(0, 0, 153); font-weight: bold;">item variable
is automatically made available to the Show view by the framework. style="font-weight: bold;">The Show View GSP
After executing
code in the action, the style="color: rgb(0, 0, 153); font-weight: bold;">show action
renders the app/views/item/show.gsp . Below is the GSP for
the item show view :
| Code Sample from: grails-app\ style="font-weight: bold;">views\item\show.gsp |
|
${item.description}
style="color: rgb(0, 0, 153); font-weight: bold;">item 's description style="color: rgb(0, 0, 153); font-weight: bold;"> attribute.<img
src="${createLinkTo(dir:'images',file:item.imageurl)}" /> style="color: rgb(0, 0, 153); font-weight: bold;">
image tag for the
style="color: rgb(0, 0, 153); font-weight: bold;">item's imageurlattribute.${item?.address?.city}
style="color: rgb(0, 0, 153); font-weight: bold;">item's style="font-family: mon;">address city style="color: rgb(0, 0, 153); font-weight: bold;"> attribute.The image below shows the resulting page for the url
http://host/catalog/item/show/105, which displays the item 105's
details:
height="728" width="677">
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= class="code-quote">"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 | ||
|
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 style="font-weight: bold;">MySQL and Jetty:
- If MySQL
is already installed, then download href="https://glassfish.dev.java.net/downloads/v2ur1-b09d.html">GlassFish
v2 UR1. Otherwise you can also Download href="http://glassfish.java.net/">GlassFish v2 UR1
and MySQL co-bundle
from the usual Download
Page ( href="http://docs.sun.com/app/docs/doc/820-3797/ggkei?l=en&q=mysql&a=view">instructions).
- Download and
install Grails.
- Download the href="http://techdayscode.dev.java.net/servlets/ProjectDocumentList?folderID=8159">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 whereyou unzipped the sample package. For example, if you extracted the
contents to
C:\ on a Windows machine, then your newlycreated directory should be at
C:\Catalog. The
file
"
/Catalog/grails-app/conf/DataSource.groovy"is configured
for a MySQL
configuration.
> mysqld_safe --user root
--console
the tables in the MySQL pet-catalog database as follows:
-
[prettify]shell> mysql<em class="replaceable"><code>pet-catalog<em class="replaceable"><code><</code></em>catalog.sql[/prettify] - using the file
catalog.sqlfile from the/Catalog
directory.
in a command window in the /Catalog directory enter the command
> 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:
- Use the WAR file in
or Create a WAR file:<sample_install_dir>/Catalog/Catalog.war
-
[prettify]> grails war[/prettify]
-
- 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)
- 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:
- Grails
+ EJB Domain Models Step-by-Step
- To learn how to build a Grails CRUD app see:
href="http://blogs.sun.com/arungupta/entry/totd_30_crud_application_using">TOTD
#30: CRUD Application using Grails - Hosted on Jetty and HSQLDB
- To learn how to run a Grails app on Glassfish and mySQL
see: href="http://weblogs.java.net/blog/arungupta/archive/2008/04/totd_31_crud_ap.html">TOTD
#31: CRUD Application using Grails - Hosted on GlassFish and MySQL - Grails framework
- Groovy
-
href="http://dev.mysql.com/doc/refman/5.0/en/mysql-commands.html">MySQL
commands
- Login or register to post comments
- Printer-friendly version
- caroljmcdonald's blog
- 9780 reads





