Showing posts with label hibernate. Show all posts
Showing posts with label hibernate. Show all posts

Friday, March 19, 2010

Shopping Cart Web Application - Bean Validation

Introduction
In my previous blog entry I wrote about adding security to the shopping cart web application. Part of the change I made to the application was adding a form to register users and a form to add and update items. It made sense to add validation to the fields so that we could maintain the integrity of our data.

I currently maintain two different versions of the application:
  • ShoppingCartSecurity.zip – A standard web application that runs off Tomcat 6 and is built with Hibernate, Spring, JPA and RichFaces. This is an Eclipse archive file that contains two Eclipse projects. 
  • ShoppingCartGF.zip – A JEE application that runs off GlassFish vs 3 and is built with EJB 3.0, JPA and RichFaces.

There are a number of different approaches one can take when doing validation. A common approach is using client side form validation which uses JavaScript to validate the form fields. There is no round trip to the server so the validation is nice and fast. The jQuery Javascript library has a nice plugin to use if you are interested in this approach. Even though client side validation is nice it isn't essential however server side validation is not an option and should be implemented to ensure data integrity. For the shopping cart application I decided to only use server side validation so that I was using a common validation implementation. In order to get the same user experience as client side validation I chose to use the Ajax JSF RichFaces library.

The validation  framework I have chosen to use is the standard validation framework (JSR 303: Bean Validation) implemented in Java EE 6. As of version 4.x Hibernate Validator is based on a new code base which is the reference implementation for JSR 303.

"JSR 303 defines a metadata model and API for JavaBean validation. The default metadata source is annotations, with the ability to override and extend the meta-data through the use of XML validation descriptors. The API is not tied to a specific application tier or programming model. It is specifically not tied to either the web tier or the persistence tier, and is available for both server-side application programming, as well as rich client Swing application developers."

What we will cover
  • Defining constraints
  • Custom validation
  • Spring injection into custom validators
  • Validating constraints
  • RichFaces Ajax validation for JSF inputs


Constraints
Constraints in Bean Validation are expressed via Java annotations. There are three different types of constraint annotations, namely: field, property, and class-level annotations. An example of property annotations can be seen in the User class:

@Column(name="username", nullable=false, unique=true)
@NotEmpty
@Length(min=4, max=12)
@Pattern(regexp="^[a-zA-Z\\d_]{4,12}$", message="{validator.username.invalid}")
@Username(message="{validator.username}")
public String getUsername() {
 return username;
}

The getter method for the username property specifies the following validation annotations:
  • @NotEmpty – The username cannot be null or empty.
  • @Length(min=4, max=12) – The length of the username must be at least 4 characters long and no more than 12 characters long.
  • @Pattern(regexp="^[a-zA-Z\\d_]{4,12}$", message="{validator.username.invalid}") – Match a regular expression. The username must contain alphanumeric characters. The default message is overridden with a key mapped to a message in the validation resource file. 
  • @Username(message="{validator.username}") – Custom validator to compares the usernames already stored in the database to check for duplicates.

An example of where I have used class-level annotation validation can be found in the Register.java JSF backing bean class:

@FieldMatch.List({
 @FieldMatch(first="password", second="confirmedPassword",
   message="{validator.fieldmatch.password}")
  })
public class Register extends BasePage {
 private Validator validator;
 private String password;
 private String confirmedPassword;

 @NotEmpty
 @Length(min=6, max=12)
 @Pattern(regexp = "(?=.*\\d)(?=.*[a-zA-Z]).{6,12}", message = "{validator.password.insecure}")
 public String getPassword() {
  return password;
 }

 public void validateUsername() {
  Set<ConstraintViolation<User>> constraintViolations = validator.validateProperty(getUser(), "username");
  if (constraintViolations.size() > 0) {
   String msg = constraintViolations.iterator().next().getMessage();
   addError(getUiUsername().getClientId(getFacesContext()), msg);
  }
 }
 
 public void validatePassword() {
  Set<ConstraintViolation<Register>> constraintViolations = validator.validateProperty(this, "password");
  if (constraintViolations.size() > 0) {
   String msg = constraintViolations.iterator().next().getMessage();
   addError(getUiPassword().getClientId(getFacesContext()), msg);
  }
 }
 
 public void validateConfirmedPassword() {
  Set<ConstraintViolation<Register>> constraintViolations = validator.validate(this);
  if (constraintViolations.size() > 0) {
   ConstraintViolation<Register> cv = constraintViolations.iterator().next();
   if (cv.getMessageTemplate().equals("{validator.fieldmatch.password}")) {
    addError(getUiConfirmedPassword().getClientId(getFacesContext()), cv.getMessage());    
   }
  }
 }
 
 ...
 
}

  • @FieldMatch – Custom cross field validation class-level annotation used to compare the values of two fields, namely password and confirmed password. 
  • @NotEmpty – The password cannot be null or empty.
  • @Length(min=6, max=12) – The length of the password must be at least 6 characters long and no more than 12 characters long.
  • @Pattern(regexp = "(?=.*\\d)(?=.*[a-zA-Z]).{6,12}", message="{validator.password.insecure}") – Match a regular expression. The password must contain alphanumeric characters. The default message is overridden with a key mapped to a message in the validation resource file. 

Custom Validators
As mentioned above I have two custom validators, namely Username and FieldMatch. Creating a custom validator is actually very simple and requires the following three steps:

  • Create a constraint annotation
  • Implement a validator
  • Define a default error message

I won’t go over this in too much detail as the Hibernate Validator documentation is pretty good and covers this nicely.

Username constraint annotation (Username.java)

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy=UsernameValidator.class)
public @interface Username {
 String message() default "Username already exists";
 Class<?>[] groups() default {};
 Class<? extends Payload>[] payload() default {};
}

Username validator (UsernameValidator.java)

public class UsernameValidator implements ConstraintValidator<Username, Object> {
 @Autowired
 private UserDao userDao;

 public void setUserDao(UserDao userDao) {
  this.userDao = userDao;
 }

 public void initialize(Username parameters) {
 }

 public boolean isValid(final Object value, ConstraintValidatorContext context) {
  try {
   User user = userDao.findByUsername((String) value);
   if (user == null) {
    return true;
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  return false;
 }
}

Spring injection
You will notice I am injecting the UserDao class into this validator using Springs @Autowired annotation. This is made possible thanks to Spring’s LocalValidatorFactoryBean class.

"By default, the LocalValidatorFactoryBean configures a SpringConstraintValidatorFactory that uses Spring to create ConstraintValidator instances. This allows your custom ConstraintValidators to benefit from dependency injection like any other Spring bean."

I only needed to add the following line of code to the shoppingcart-database.xml Spring bean configuration file in order to use the SpringConstraintValidatorFactory:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

The Register.java JSF backing bean mentioned earlier gets a reference to the Spring created Validator by declaring the managed property in the faces-config.xml:

<managed-bean>
 <managed-bean-name>pc_Register</managed-bean-name>
 <managed-bean-class>com.mydomain.shoppingcart.view.Register</managed-bean-class>
 <managed-bean-scope>request</managed-bean-scope>
 <managed-property>
  <property-name>shoppingViewHelper</property-name>
  <value>#{shoppingViewHelper}</value>
 </managed-property>
 <managed-property>
  <property-name>validator</property-name>
  <value>#{validator}</value>
 </managed-property>
</managed-bean>

ValidationMessages.properties
I created a ValidationMessages.properties file and saved it in my src folder of my project. Hibernate Validator uses this file to retrieve the messages used by the validators.

Tying it together with the user interface
The login-form.jspx page includes a form for registering users. Instead of explaining each input field I am only going to step through one of them (username) and explain the validation process for it:

<h:inputText id="usrnameInTxt" binding="#{pc_Register.uiUsername}" value="#{pc_Register.user.username}" label="usrnameOutTxt" tabindex="1">
 <a4j:support id="usrnameSpt" event="onblur" reRender="usrnameMsg" limitToList="true" action="#{pc_Register.validateUsername}" />
</h:inputText>
<rich:message id="usrnameMsg" for="usrnameInTxt" errorClass="error" />

The a4j:support tag is a RichFaces tag that provides Ajax support to JSF input fields. Here it defines that the validateUsername method in the Register backing bean will be invoked when the onblur event of the input text field is triggered.

public void validateUsername() {
 Set<ConstraintViolation<User>> constraintViolations = validator.validateProperty(getUser(), "username");
 if (constraintViolations.size() > 0) {
  String msg = constraintViolations.iterator().next().getMessage();
  addError(getUiUsername().getClientId(getFacesContext()), msg);
 }
}

As you can see from the above code the validator class in the validateUsername method invokes the validateProperty method. The single property username is validated and if any constraint violations are raised an error message is added to the FacesContext.

The RichFaces rich:message tag behaves the same way as the standard JSF h:message tag except it will auto re-render itself after an Ajax request.

RichFaces Ajax Validator
RichFaces also has an Ajax validator tag that ties nicely into Hibernate Validator. I use this tag in the Items Admin modal panel of the items.jspx page.

<h:inputText id="nameInTxt" 
 value="#{pc_Items.selectedItem.name}"
 label="nameOutTxt" tabindex="1">
 <rich:ajaxValidator event="onblur" />
</h:inputText>
<rich:message id="nameMsg" for="nameInTxt" errorClass="error" />

As you can see there are no a4j:support tags or validation methods that get called. RichFaces will create its own Validator instance and call the validate property methods automatically for you. This works pretty nicely in the above example however for the registration form we are not using this tag because the validator is created for us by the Spring LocalValidatorFactoryBean class.


Registration screen shot



Saturday, January 9, 2010

Shopping Cart Web Application - Part 7 - TopLink and EAR

I recently received a response from someone who was stepping through my Shopping Cart Web Application tutorial and who wanted to deploy the application on GlassFish and use TopLink Essentials (EclipseLink) as the reference implementation for JPA as opposed to Hibernate.

Thankfully there wasn't that much change that needed to be made to the existing ShoppingCartHibJpaPart7 application. This application (ShoppingCartTopLinkJpaPart7.zip) is available to download in case anyone would like to take a look. I chose to use EclipseLink which is the successor to TopLink. In order to get it working with GlassFish 2.0 there are a few simple steps to take. The biggest change I needed to make was in the persistence.xml file:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
 version="1.0">

 <persistence-unit name="shopping-cart"
  transaction-type="RESOURCE_LOCAL">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <non-jta-data-source>jdbc/__shoppingcart</non-jta-data-source>
  <exclude-unlisted-classes>false</exclude-unlisted-classes>
  <properties>
   <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
   <property name="eclipselink.logging.level" value="FINE" />
  </properties>
 </persistence-unit>
</persistence>
The real difference here is the use of EclipseLink properties as opposed to Hibernate properties. I also had to define the non-jta-data-source attribute. Another one of the requirements was to have GlassFish manage the database connections so my application needed to be configured to lookup the resource via the datasource JNDI name.

Java Transaction API  (JTA) inside a web application
After doing this I was asked if I could change the transaction type from RESOURCE_LOCAL to JTA. In order to do this I made the following changes:

I changed the value of the transaction-type in the persistence.xml file from RESOURCE_LOCAL to JTA and changed the non-jta-data-source attribute to jta-data-source.

Secondly I needed to do a JNDI lookup for the EntityManager managed by the container, one way is to do it by annotation on the Dao class:

@PersistenceContext(name="persistence/ShoppingCart", unitName="shopping-cart")
public class BasketDaoImpl implements BasketDao {

and then the lookup:

Context ctx = new InitialContext();
em =  (EntityManager) ctx.lookup("java:comp/env/persistence/ShoppingCart");

Our application is managing the transaction however in a JTA entity manager entityManager.getTransaction() calls are not permitted so instead I needed to get a UserTransaction by doing a JNDI lookup for the UserTransaction:

Context ctx = new InitialContext();
(UserTransaction)ctx.lookup("java:comp/UserTransaction");

If you are interested in seeing how I implemented this you can download the ShoppingCartJtaTopLinkJpaPart7.zip file and view the DAO classes in the shopping-cart-core-jta-toplink-jpa-part7 project.

BasketDaoImpl.java
@PersistenceContext(name="persistence/ShoppingCart", unitName="shopping-cart")
public class BasketDaoImpl implements BasketDao {

  public Basket updateBasket(Basket basket) throws Exception {
    EntityManager em = null;
    UserTransaction utx = null;
    try {
      em = JPAUtil.getEntityManager();
      utx = JPAUtil.getUserTransaction();
      utx.begin();
      basket = em.merge(basket);
      utx.commit();
      return basket;
    } catch (RuntimeException e) {
      if (utx != null) {
        utx.rollback();
      }
      throw e;
    }
  }

Java Transaction API  (JTA) inside a JEE application
In this example our application is going to make use of an EJB session bean. Unlike in the previous example where our application was controlling the transaction via the UserTransaction class here the container will manage and control the transaction for us. Once again you can download the full source of the ShoppingCartEJBTopLinkJpaPart7.zip file and take a look at what I did.

Using JEE annotations it was very simple to turn the ShoppingManager class into a session bean. The @PersistenceContext annotation was used to obtain an EntityManager instance and you will also notice I got rid of the DAO classes as there really was no need for them anymore as the container manages the transaction.

ShoppingManager.java
@Stateless(name="ShoppingManager")
public class ShoppingManager implements ShoppingService {

  @PersistenceContext(unitName="shopping-cart")
  private EntityManager em;

  public Basket updateBasket(Basket basket) throws ShoppingException {
    try {
      return em.merge(basket);
    } catch (Exception e) {
      logger.error("There was an error updating the basket, exception: " + e);
      throw new ShoppingException("There was an error updating the basket", e);
    }
  }

All these applications were written in Eclipse and tested in a GlassFish 2.0 application server.

Sunday, July 5, 2009

Shopping Cart Web Application - Part 7 - Hibernate


Introduction
Hibernate is an object-relational mapping (ORM) library for the Java language, providing a framework for mapping an object-oriented domain model to a traditional relational database.
If you are new to Hibernate I would suggest reading the documentation on the Hibernate website as well as this tutorial.

What you need before we get started


What we will cover

  • Hibernate Overview
  • Java Persistence API
  • Shopping cart web application changes


Level
  • Beginner

Overview
Hibernate's primary feature is mapping from Java classes to database tables (and from Java data types to SQL data types). Hibernate also provides data query and retrieval facilities. Hibernate generates the SQL calls and relieves the developer from manual result set handling and object conversion, keeping the application portable to all supported SQL databases, with database portability delivered at very little performance overhead.

Java Persistence API
The Java Persistence API (JPA) provides an object/relational mapping facility to Java developers for managing relational data in Java applications. Java Persistence consists of three areas:
  • The Java Persistence API
  • The query language
  • Object/relational mapping metadata

JPA was introduced in JEE 5 and forms part of the JSR 220 EJB3.0 specification. The Java Persistence API draws upon the best ideas from persistence technologies such as Hibernate, TopLink, and JDO. Customers now no longer face the choice between incompatible non-standard persistence models for object/relational mapping.

Both sample applications use JPA annotations in the Entity classes, the difference between the two is in the data access objects. The Hibernate sample application makes use of Hibernate's session factory to read and write to the database whereas the JPA sample application makes use of JPA's EntityManager to read and write to the database.  

For further reading and information on JPA I recommend these links:

Shopping Cart Web Application


Database Schema
Below is a schema of the database I want my application to use:



The SQL statements for the creation of these tables for this database will look like:
create table basket (id bigint not null unique, primary key (id)) ENGINE=InnoDB;
create table basket_item (id bigint not null unique, price double precision not null, quantity integer not null, items_id bigint not null, basket_id bigint not null, primary key (id)) ENGINE=InnoDB;
create table item (id bigint not null unique, description varchar(255), name varchar(255) not null, price double precision not null, primary key (id)) ENGINE=InnoDB;
alter table basket_item add index FK3F6FA5ECF59CCC6 (basket_id), add constraint FK3F6FA5ECF59CCC6 foreign key (basket_id) references basket (id);
alter table basket_item add index FK3F6FA5EC98F3A8D9 (items_id), add constraint FK3F6FA5EC98F3A8D9 foreign key (items_id) references item (id);

The above basket table is pretty useless but I wanted an example which had a many-to-one association with items. The basket table could also include more columns such as username.

HSQLDB
HSQLDB (Hyperthreaded Structured Query Language Database) is a relational database management system written in Java. The reason I have chosen this database over MySQL or any other database is because I wanted an in-memory database so that it would be easier for readers who are unfamiliar with configuring databases to get my sample application up and running without much hassle. Using HSQLDB’s in-memory database all I had to do was include the HSQLDB library in my applications classpath. Hibernate will create the database for me and prepopulate our database with necessary data.

Hibernate configuration file vs Persistence configuration file
The Hibernate sample application requires a Hibernate configuration file whereas the JPA sample application requires a persistence configuration file. Both are very similar:

1. Hibernate configuration file
Hibernate uses a file (hibernate.cfg.xml) to configure hibernate properties such as connection details to the database, location of the entity classes used to create tables in the database and a whole range of other settings. This is a copy of the hibernate.cfg.xml we used in the Shopping Cart application:
<?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>
        <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
        <property name="hibernate.connection.url">jdbc:hsqldb:shoppingcart</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="current_session_context_class">thread</property>
        
        <mapping class="com.mydomain.shoppingcart.bo.Item" />
        <mapping class="com.mydomain.shoppingcart.bo.Basket" />
        <mapping class="com.mydomain.shoppingcart.bo.BasketItem" />
    </session-factory>
</hibernate-configuration>

2. Persistence configuration file
Much like the Hibernate configuration file the persistence configuration file is used to configure the JPA context.
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
 version="1.0">
 <persistence-unit name="shopping-cart" transaction-type="RESOURCE_LOCAL">
  <properties>
   <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
   <property name="hibernate.connection.url" value="jdbc:hsqldb:shoppingcart" />
   <property name="hibernate.connection.username" value="sa" />
   <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
   <property name="hibernate.archive.autodetection" value="class" />
   <property name="hibernate.show_sql" value="true" />
   <property name="hibernate.format_sql" value="true" />
  </properties>
 </persistence-unit>
</persistence>


Annotations
Many APIs require a fair amount of boilerplate code (any code that is or can be reused in new contexts or applications without being changed much from the original). For example, in order to write a JAX-RPC web service, you must provide a paired interface and implementation. This boilerplate could be generated automatically by a tool if the program were “decorated” with annotations indicating which methods were remotely accessible.

Annotations are like meta-tags that you can add to your code and apply them to package declarations, type declarations, constructors, methods, fields, parameters, and variables. As a result, you will have helpful ways to indicate whether your methods are dependent on other methods, whether they are incomplete, whether your classes have references to other classes, and so on.

Annotation-based development relieves Java developers from the pain of cumbersome configuration. Annotation-based development lets us avoid writing boilerplate code under many circumstances by enabling tools to generate it from annotations in the source code. This leads to a declarative programming style where the programmer says what should be done and tools emit the code to do it.

Mapping with EJB3/JPA Annotations
Every bound persistent POJO class is an entity bean and is declared using the @Entity annotation (at the class level). Below is an extract of the code of what our Item class now looks like having annotations added to it:

Item.java
@Entity
@Table(name="item")
public class Item implements Serializable  {
 private static final long serialVersionUID = 1135428828106917172L;
 private String description;
 private Long id;
 private String name;
 private Double price;
 private List<BasketItem> basketItems = new ArrayList<BasketItem>(0);
 
 public Item() {
 }

 public Item(Long id, String name, double price) {
  this.id = id;
  this.name = name;
  this.price = price;
 }

 public Item(Long id, String description, String name, double price) {
  this.id = id;
  this.description = description;
  this.name = name;
  this.price = price;
 }
 
 @Column(name="description")
 public String getDescription() {
  return description;
 }

 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
 public Long getId() {
  return id;
 }

 @Column(name="name", nullable=false)
 public String getName() {
  return name;
 }

 @Column(name="price", nullable=false, precision=22, scale=0)
 public Double getPrice() {
  return price;
 }

 public void setDescription(String description) {
  this.description = description;
 }

 public void setId(Long id) {
  this.id = id;
 }

 public void setName(String name) {
  this.name = name;
 }

 public void setPrice(Double price) {
  this.price = price;
 }
 
 @OneToMany(mappedBy="item", cascade=CascadeType.ALL)
 public List<BasketItem> getBasketItems() {
  return this.basketItems;
 }

 public void setBasketItems(List<BasketItem> basketItems) {
  this.basketItems = basketItems;
 }
}


  • @Entity declares the class as an entity bean (i.e. a persistent POJO class). @Id declares the identifier property of this entity bean. The other mapping declarations are implicit.
  • @Table is set at the class level; it allows you to define the table, catalog, and schema names for your entity bean mapping. If no @Table is defined the default values are used: the unqualified class name of the entity.


Hibernate Annotation Extensions
Hibernate 3.1 offers a variety of additional annotations that you can mix/match with your EJB 3 (JPA) entities. They have been designed as a natural extension of JPA annotations. I am using a Hibernate annotation in the Basket class to handle the removal of orphans as the current version of JPA doesn't have an annotation that handles this.

Basket.java
@OneToMany(mappedBy="basket", cascade=CascadeType.ALL)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
public List<BasketItem> getBasketItems() {
 return basketItems;
}

To empower the EJB3 capabilities, hibernate provides specific annotations that match hibernate features. The org.hibernate.annotations package contains all these annotations extensions. Please refer to the hibernate documentation for more information.

Serializable
One of the other important things to note was that our entity classes implement the interface Serializable. Strictly speaking, this is not a requirement. However, in practice you will normally want your Hibernate objects to be serializable so that they can be (potentially) migrated around a multiprocessor cluster or saved and restored across a web server reboot etc.

Session Factory vs EntityManager
The Session factory is used by the Hibernate sample application to transact with the database whereas the EntityManager is used by the JPA sample application.

1. SessionFactory
The session factory creates Sessions. Usually an application has a single SessionFactory. Threads servicing client requests obtain Sessions from the factory. The Session interface is the main runtime interface between a Java application and Hibernate. The main function of the Session is to offer create, read and delete operations for instances of mapped entity classes.

2. EntityManager
An EntityManager instance is associated with a persistence context. The EntityManager is used to create and remove persistent entity instances, to find entities by their primary key, and to query over entities.


Hibernate utility class vs JPA utility class
I created a utility class that will be used by any class within the Shopping Cart application that requires a hibernate session / EntityManager.

1. Hibernate utility
The class is called HibernateUtil.java and can be found in the com.mydomain.shoppingcart.util package.

2. JPA utility
The class is called JPAUtil.java and can be found in the com.mydomain.shoppingcart.util package.


Data Access Object (DAO's)
A Data Access Object (DAO) is an object that provides an abstract interface to some type of database or persistence mechanism, providing some specific operations without exposing details of the database. The DAO pattern allows data access mechanisms to change independently of the code that uses the data. Compare the DAO's in the Hibernate sample application to the JPA sample application. You will see where the Hibernate session is being used and where JPA's EntityManager is being used. I created two DAO's, one for each of our Entities:
  • ItemDaoImpl – implements ItemDao interface
  • BasketDaoImpl – implements BasketDao interface

Lastly I tied the rest of the pieces together so that our application was using our DAO's now and not just getting back stubbed data.

Tuesday, April 28, 2009

Scalaffinity - Scala, Spring, Hibernate, Maven project

I was looking around to see how to build a JUnit test case using Scala with Spring. I came across this project (currently still in development) called Scalaffinity. You can connect to the SVN repository and download the project. That’s what I did and it has everything I was looking for and more. Thanks to Álvaro Martínez Hernández who put this project together.