Thursday, June 9, 2011

Unit Testing Hibernate Data Access Objects using JUnit 4 – Part II

In part I we setup the infrastructure or the framework for unit testing. In this part we will write out domain/entity class, dao interface, dao implementation test and then dao implementation. When we write our test we know it will fail because no such method will exist in the dao implementation. However, we will need to create the implementation class, albeit without any methods. So, let's get straight to it.

@Entity
public class Item {

@Id@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@ManyToOne
private Order order;
private String product;
private double price;
private int quantity;
/**
* @return the id
*/
public Long getId() {
return id;
}

/**
* @return the order
*/
public Order getOrder() {
return order;
}
// --- getters and setters follow.
//--- override the ToString()and HashCode()

public class Order{

//Other instance variables ....
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="ORDER_ID")
private Collection items = new LinkedHashSet();

/**
* @return the items
*/
public Collection getItems() {
return items;
}
/**
* @param items the items to set
*/
public void setItems(Collection items) {
this.items = items;
}
}


Few things to note here if you are using hibernate are ITEM has many to one relationship with ORDER- an order has many items whereas an item belongs to an order. In the database you will have ORDER_ID column in the ITEM table. Cascade.ALL means whenever ORDER is deleted, corresponding ITEM is set to null. We will not update the id of ORDER because it is auto-generated. So update to an ORDER does not have any bearing on ITEM. The ids are auto-generated.

Now that we have our domain objects, we will write ItemDao. You will similarly write OrderDao, but  I will leave that to you.

public interface ItemDao {

/**
* Given an item id
* return the Item object.
* @param id of the
* @return Matching Item object.
*/
public Item findById(Long itemId);

/**
* @return All items
*/
public List<Item> findAllItems();
}


We have two simple methods to find an Item by item id and findAllItems. You would indeally expand on this and write methods to delete, update, findItemByOrderId and so on. For now, let's keep things simple.

Now we will implement this dao, except we will return null from the implemented methods.

public class ItemDaoImpl implements ItemDao {

public Item findById(Long itemId){
return null;
}

public List<Item> findAllItems() {
return null;
}
}


We can now write our unit test! If you've followed part I, we setup application-context to inject dao implementation. Now we will read the application-context in order to inject that. Also I mentioned that the test methods will be annotated with @Transactional. This is to ensure that when the method returns (void), the transactions within will be rolledback. This is to ensure that our test db will remain unchanged and we can test again and again with same test data. Of course, this also means that you will need to populate your test data. So let's do that first.

Run this query in MySQL and you will have 2 rows in the ITEM table.

INSERT INTO `test_hibernate`.`item` (
`ID` ,
`PRODUCT` ,
`PRICE` ,
`QUANTITY` ,
`ORDER_ID`

)
VALUES (
NULL , 'Sony Headphones', '99.99', '3', NULL

), (
NULL , 'Logitech XZ Mouse', '15.99', '2', NULL

);


For now we don't set ORDER_ID. Now that you have two rows, we can write our tests.

@ContextConfiguration(locations={"classpath:/applicationContext.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class ItemDaoImplTest {

@Autowired
private ItemDaoImpl dao;

@Test
@Transactional
public void testFindById()
{
Item newItem =  dao.findById(1L);
assertTrue(newItem.getProduct().equals("Sony Headphones"));
}

@Test
@Transactional
public void testFindAllItems()
{
List<Item> itemList = dao.findAllItems();
assertTrue(String.valueOf(itemList.size()).equals("2"));
}

If you run this now, your tests will fail. This is because you have not implemented the methods correctly.

So now, we implement those methods from daoImpl.

public Item findById(Long itemId){
DetachedCriteria itemCriteria = DetachedCriteria.forClass(Item.class);
itemCriteria.add(Restrictions.eq(ID_FIELD, itemId));
List<Item> itemList = findByCriteria(itemCriteria);
if(null != itemList && itemList.size() > 0)
return itemList.get(0);
return null;
}

public List<Item> findAllItems() {
DetachedCriteria itemCriteria = DetachedCriteria.forClass(Item.class);
List<Item> itemList = findByCriteria(itemCriteria);
if(null != itemList && itemList.size() > 0)
return itemList;
return null;
}

As I mentioned in part I, I will use DetachedCriteria to query our database. One subtle advantage of doing this is constructing queries is easy (to read and write) and the other major advantage would be since we are going to call this from another module most likely, for example web application's controller via service method in this module, we want the session to be started only when the dao method is called and to be cleaned up as soon as the method returns.

Run the test again, and it will pass. This takes care of testing dao. In a near future I will show you how to write tests for service methods by mocking out the db. I will also point out the advantage of doing this.

Monday, June 6, 2011

Unit Testing Hibernate Data Access Objects using JUnit 4 - Part I

In this article, I want to show you how to write unit tests for your DAOs. You would preferably use an in-memory db instance like HsqlDb but using a test db is perfectly fine since you're going to rollback each db transaction. One thing to remember while doing a DAO unit test is that you'd want to test with the db provider that you are going to use in the live, except you will use a test db instance and not the live db instance. The reason for this is that let's say you are using Hibernate just like I am doing here. You would want to test whether or not the sql queries run against the db using the specific version of hibernate works. Hibernate ships with different versions of driver classes for different db vendors, but for some reason, let's say the encoding of the db you're going to use in the live version does not support certain SQL queries generated by Hibernate. If you do an in-memory HSQLDB test and pass you will most likely think that will work with your specific version of db provider. I just don't think this is accurate enough especially if your queries are complex joins. Again, the rollback feature works for you to take advantage of and regardless of whether you are using an in-memory instance or not, you would still need to populate some data before testing. How else would you test find methods? Another advice I would like to give is to try and use accurate data. I don't mean real-values of credit cards, but data not like "AAAA" in place of a person's name. You may run into various issues later when populating your test db with such data. One such problem I can think of is if your entities are annotated with column specifications such as length and type and you have added data that may not be 100% compatible with that. Another problem is relationships between entities.

Moving on we will have these steps:

1. Pre-requisites
2. Setting up the application context
3. Writing Domain and DAO interface
4. Writing DAO unit tests
5. Writing DAO implementations

I will cover 1 and 2 in this part to have the framework in place. In the next part we will write our domain (just one) and dao interface, dao unit test and then dao implementation. This is a logical order because we would want to test first an then see what we need in order for the test to pass. That 'what we need' will go into our implementation. This is called, as you might have guessed it, Test Driven Approach.

Pre-requisites

* Spring Core library for dependency injection. We are also going to use SpringJunit4ClassRunner for unit testing.
* Hibernate 3.x. We will be using Hibernate's Criteria, specifically, Detached Criteria. For more info on using Criteria look here.
* MySQL db.

You can use Maven to configure all of these. Here's what part of the pom.xml looks like. If you need more help on configuring a maven project please look at my "How to setup a Maven Java Enterprise Application". You can find that under the category "Deployment". Here's the list of artifacts you'll need:

<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.2.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.3.1.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.6.0.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jcl</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.framework.version}</version> <!--version 3.0.5.RELEASE -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.framework.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
</dependency>


Setting up the Application Context

When the test is run, it will scan the application context to inject the dao interface. The implementation of the dao interface will use Hibernate's sessionFactory to run our Hibernate queries. We will also add our single Item domain/entity to use sessionFactory. That object will be directly mapped to the ITEM table of our db. I will not create the table since this is simple enough. Lastly, we will need to use Transactions in order to rollback our unit test methods. For this, we will annotate our test methods as @Transactional. Below is the applicationContext.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:tx="http://www.springframework.org/schema/tx"     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<!--  This is where the properties related to datasource are read from -->
<bean id="propertyConfigurer">
<property name="location" value="classpath:hibernate.properties" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
</bean>

<!--  Define dataSource to use -->
<bean id="dataSource">
<property name="driverClassName" value="${hibernate.jdbc.driver}" /> <!-org.gjt.mm.mysql.Driver -->
<property name="url" value="${hibernate.jdbc.url}" />
<property name="username" value="${hibernate.jdbc.user}" />
<property name="password" value="${hibernate.jdbc.password}" />
</bean>

<!--  The sessionFactory will scan the domain objects and their annotated relationships. -->
<bean id="sessionFactory">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.company.application.core.domain.Item</value>
..............
</list>
</property>
<property name="schemaUpdate" value="true" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.connection.isolation">2</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<prop key="hibernate.max_fetch_depth">2</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>

<!--  Define Transaction Manager. We will use Hibernate Transaction Manager. -->

<bean id="transactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!--  We will set transactional properties with annotation -->
<tx:annotation-driven />
<bean id="itemDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>


One thing you might have noticed is that I could easily annotated my Dao as @Resource, have it scanned and not defined in the xml above. That is perfectly legal. Now we're set to write our domain, dao interface, dao test and dao implementation.

Friday, June 3, 2011

Spring Batch: the object oriented way

Recently, I was working on a project where we had to re-write a vb application in java. The application would read from database invoice numbers based on an xml config logic (like range of invoices or invoices for a date range and so on), and for each invoice it would create and write in separate xml and excel files based with filenames being the same as invoice numbers. That sounds simple enough right? So why am I talking about sprng batch? Here's the interesting part of the app - for every invoice there is a BillingOrder (one to one relationship), for every BillingOrder there is 1 to N relationship with Shipping, for every Shipping there is another 1 to N relationship with Products and believe me for every Product there is a UserDetail.  Now what was so special (or lack there of) about this vb application was that it for each invoice it read, it created a new xml and worte the invoice, closed it, did that for n number of invoices. For BillingOrder it opened (not created) the matching invoice, appended data to it, closed it, did that for exactly n number of BillingOrder. You see where I am going with this?

Now immediately you would acknowledge that Spring Batch is the way to go. Problem solved? I wish. The problem was even more compounded by the fact the we had to turn this module in, in a very short period and while they would appreciate if we used Spring Batch, it really was just a re-write. But the heroes that we were (and still are ;)) we just had to use Spring Batch . So here's our little story below.

If you read the Spring Batch guide (oh we used the 2.1.8 version), you will find workable examples of Reading and Writing in chunks. For each Reader there is a Writer. I am not saying you have to read once and write once. That would not make sense of using a batch application, now would it? You can read 1..100 or n times from a source (db or text or xml), generally use a domain object to populate it and when your threshold for chunking is reached (1..100 or n times) your writer wrties them out to db or text or xml and most importantly (at least to me) sets those objects (1..100 or n number of them) to null. GC happens when it does. Anyways, for our application we would then have these options:

  • Usung domain objects as DTOs. In our job's first step,Read x number of invoices from the db and send them over (application does that for you) to the writer and have them written out one by one, creating new invoice xmls with invoice numbers as name. Use a stepListener to send invoice number list to the next step. In that next step, read exactly x number of BillingOrders from another table in the db and send them over to another writer (remember I said 1 reader : 1 writer) and open each invoice and append to them the BillingOrder values as childNodes. The next step would then be sending BillingOrder ids using another stepListener so that Shipping details can be written. Perfect? Well it gets tricky here. This is 1 to N relationship. So whether or not you send the Shipping details in a sorted order - meaning <Shipping> lists with BillingOrder 1 first, then with BillingOrder 2... you will still have to open the xml files shippingList.size()number of times. You might tweak the code a little bit to stop this from happening but still.. for x number of invoices you are opening at least  (x times 5) xml files. Good solution? Hardly.

  • Option 2. The object oriented way. The right way. Now instead of using our domains as dumb Data Transfer Objects we are going to implement relationships in them. Invoice now has BillingOrder billing (why not the other way? I will explain below). BillingOrder will have a List<Shipping> shippingList (use Set if you want to make sure they are unique), Shipping has List<Product> productList and Product has UserDetail  userDetail. Now our invoiceReader will also change. First of all we will need only 1 reader because we want only 1 writer instance associated with 1 xml ouput file. So we don't use any StepListeners either. Consequently, only 1 step in this job. What we will do is read out all the invoices from the db into a list of invoice objects. Loop through the invoice object list, populating billingOrder instance variables of each invoice object (this is why I had billingOrder inside invoice object. Invoice has to know about BillingOrder). At the same time create another loop to populate each billingOrder of Invoice with Shipping. You will have multiple loops but at then end, you will be able to send 1 invoice object or 100 or n number of invoice objects with all the relationsips intact to the writer. The writer will only create/open 1 xml for 1 complete invoice.  If this seems like a memory issue you can reduce the chunk threshold.  


If you've thoroughly read this, you might have one question. Why didn't Jason Kidd shoot this well early in his career? Kidding. You would be asking "Where is the config file read?" What you need to understand about steps is that there is only one instance of reader and exactly one instance of writer for each step execution. For example, there are 500 rows of invoices and you set the chunk threshold to 100. When the step starts, a new instance of reader (InvoiceReader) is created. After 100 have been read and sent for writing, the same invoiceReader instance is used again and next hundred is sent. How else would it know to process the next 100? This happens 5 times and on the sixth occasion, a null is sent (not an exception, you really need to send null) to mark the end of the step. Since only one instance of reader (and writer) exists, you can create an instance level variable in the reader like boolean isFirstRead and set it to true on the first instance read. The code to read the config file will be within this if condition. Then in the recurring cycles, this config file will not be read. And you would not start from the top.

So that as they say is that. I wanted to write pseduo code to explain the loops but I kept on writing and didn't realize that I wasn't.

Wednesday, June 1, 2011

Creating and consuming a EJB 3 Message Driven Bean Part II

In part I we did all the dirty work - setup JMS connection factory and JMS destination in the application server and then created a stateless session bean that sends message to our XYZ Warehouse application. One thing I forgot to mention is that you'd probably be asking "where is the messaging server?". You might have heard of Active MQ or Webshpere MQ. We're using messaging server included within the AS. So then let's get to creating our MDB.

Create our Message Driven Bean
MessageDrivenBean is just like our stateless bean in the sense it does not retain state. For you and I this means, do not write any code like transaction related code. In the event of any exception you will not be able to recover from this. Little bit confused? Simply understand that it is not your shopper who will have started this transaction for the exception to be returned to the client to handle it. Maybe I should have an article on Transactions. :)

The first thing to do is Annotate the Class with @MessageDriven which tells the AS that this bean is an MDB. You will also have to specify that you want to use the destination "jms/InvoiceQueue". Refer to the source below.  You can then implement MessageListener interface and when you do that you implement void onMessage(Message message) method. Basically, this method encapsulates your business logic or what type of and what message to consume. As with any EJB, you will need an associated EntityManager context to do your CRUDing. But that really is not where I want to focus. What you should get from the code below is that we know we are consuming an ObjectMessage that was sent originally from the producer app. And I'd pointed out that we need an object similar to or at least capable of storing the properties of the Object (Item). We have ItemOrder in this client app to do so.

import com.factory.entities.ItemOrder;
import java.util.ArrayList;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@MessageDriven(mappedName = "jms/InvoiceQueue", activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class InvoiceMessageBean implements MessageListener {

    @PersistenceContext
    EntityManager em;

    public InvoiceMessageBean() {
    }

    public void onMessage(Message message) {
        try {            
            ObjectMessage objectMessage = (ObjectMessage) message;
            ArrayList list = (ArrayList)objectMessage.getObject();
            ItemOrder itemOrder = new ItemOrder();
            itemOrder.setBarcode(Integer.parseInt(list.get(0).toString()));
            itemOrder.setTotalItemsToOrder(Integer.parseInt(list.get(1).toString()));
            itemOrder.setCompanyID(19284);
            em.persist(itemOrder);
        } catch (JMSException jmse) {
            jmse.printStackTrace();
        }
    }
}


So that's it. You're now ready to create and consume your EJB 3 MDB. You should be able to appreciate all the asynchronous nature of MDB! Enterprise JAVA rules!

Creating and consuming a EJB 3 Message Driven Bean Part I

"Finally, The Rock has come back to...." More like finally, I am going to write an article (albeit two parts article) about programming, if you don't regard SQL as programming. In the first part I am going to write about how to send message to a messaging server including creating a new JMS resource. I used glassfish v2.1 for this. You can use do the same on your preferred application server. In the next part I will write about consuming the message via the MDB. So let's begin. I have created a checklist of functions we need to perform in order deploy our MDB and consume it.

Checklist:


  1. Create a new JMS connection factory to allow creation of JMS objects in the application server. (Messaging server)

  2. Create a new JMS Destination that will be repository for messages sent. (Messaging server)

  3. Use/Create a  session bean to send the message. (Producer Application)

  4. Create our MessageDrivenBean to consume it. (Consumer Application)


Create a new JMS connection factory to allow creation of JMS objects in the application server.
Before we start with creating our MDB and consumer, the first thing I suggest doing is to create a new JMS connection factory in your application server. Think of JMS connection factory as JDBC connection pool. Your JDBC connection pool creates a pool of connection and whenever your application makes a call to get a new connection object, the pool serves it. When you're done the connection object is returned to the pool and if in active and not invalid state, it can serve another connection request. Using pool is just a lot faster and the application server is responsible for managing it. Of course you are responsible for closing the connection so that it can be returned to the pool. We have the option of using javax.jms.TopicConnectionFactory, javax.jms.QueueConnectionFactory or simply javax.jms.ConnectionFactory. Even though we're going to be consuming queues (why? I will explain the difference between a topic an queue) staying true to Abstract Factory Pattern, we will use the inteface ConnectionFactory. Have a look at the image below. I've created a new JMS Connection Factory with JNDI name jms/InvoiceQueueFactory. I've left the Pool Settings to default AS settings.

[caption id="attachment_64" align="alignnone" width="300" caption="JMS Connection Factory"]JMS Connection Factory[/caption]

Create a new JMS Destination that will be repository for messages sent
Now that you've created the Connection Factory we are ready to create a JMS Destination. JMS Destination is where the messages that are sent from the MDB are stored. There are two types of destinations

  • Queue - For point-to-point communication.

  • Topic - For publish-subscribe communication.


What messaging paradigm you want to use is dependent on what your business model is. In the sample MDB, whenever the inventory level of an item in an ABC store reaches below a certain threshold we are going to send an order request  to an XYZ warehouse for the item.

Let's say an instance of ItemOrder class/entity in the Warehouse client app has the following properties

  • int barcode;

  • int totalItemsToOrder;

  • String companyID;


And an instance of Item class/entity in the ABC producer app has the following fields

  • int barcode;

  • String name;

  • double price;

  • int minQuantity;

  • int totalItemsInStock;


Now what happens is when a shopper buys an item with barcode 3884994 from the shop, the totalItemsInStock drops below the minQuantity. What we want to do now is to send a message to the messaging server so that at a later time (may be 5 secs from now or 2 days from now) the Warehouse Application consumes this and sends an packaging and shipping order to its distribution vendor. What is important here is that one and only one message needs to be sent to warehouse. Otherwise, they'd end up sending more than what you need for your store. We would also like to make the message as durable. But this is a configuration in the MDB itself. Later I will discuss this. Anyways, the point is, we need to send a point-to-point message with specific  item barcode and our company ID (their system requirement, apparently) and make sure that message stays there until it is consumed (Hopefully the message does not expire).

You'd use Publish-subscribe when this is not a requirement. Generally, there is a one to many relationship between publisher and subscriber. This won't make sense in our scenario here. So Queue it is!

Creating this is easy. Just use another jndi name like I've done below and specify the type as Queue.

[caption id="attachment_65" align="alignnone" width="300" caption="JMS_Destination_Resource"]JMS_Destination_Resource[/caption]

Use/Create a  session bean to send the message. (Producer Application)
As discussed above, whenever the inventory level drops to below the threshold for that Item, we need to send a message to the Warehouse system via our messaging server to request new orders. What we want to send is our ItemOrder object. I think the valid types are TextMessage, BytesMessage, StreamMessage, ObjectMessage, MapMessage. Please check the API for more info on this. As you may have guessed it, we're going to use ObjectMessage. The caveat here is that you need to have a similar object in the Warehouse system, or at least one with the properties in ItemOrder object. You get the point.

So without further ado, below is a stateless bean that sends a request to the messaging server when the invoice is saved (saveInvoice), if the inventory level drops below the min threshold.

import com.store.entities.Customer;
import com.store.entities.Invoice;
import com.store.entities.Item;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.jms.JMSException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ejb.Remove;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;

@Stateless
public class InvoiceBean implements InvoiceRemote {

    private Invoice invoice = new Invoice();
    @EJB
    private ItemRemote itemService;
    @EJB
    private CustomerRemote customerService;
    @PersistenceContext
    EntityManager em;
    @Resource(name = "jms/InvoiceQueueFactory")
    private ConnectionFactory connectionFactory;
    @Resource(name = "jms/InvoiceQueue")
    private Destination destination;
    private int cartTotal;

    public void addItem(int barcode) {
        Item it = new Item();
        it = (Item) itemService.findItem(barcode);
        if (it.getQuantity() < 1) {
            System.out.println("No item available..........");
        } else {
            it.setQuantity(it.getQuantity() - 1);
            it = (Item) itemService.updateItem(it.getId(), it.getName(), it.getQuantity(), it.getPrice(), it.getBarcode(),
                    it.getMinQuantity(), it.getImage(), it.getItemsToOrder(), it.getShippingCost());
            if(getInvoice().getItems()==null){
                List<Item> items = new ArrayList<Item>();
                items.add(it);
                getInvoice().setItems(items);
                this.setCartTotal(1);
            }else{
                getInvoice().getItems().add(it);
                this.setCartTotal(this.getCartTotal()+1);
            }
            getInvoice().setTotalCost(it.getPrice()+getInvoice().getTotalCost());
        }

    }

    public void removeItem(int barcode) {
        Item it = itemService.findItem(barcode);
        it.setQuantity(it.getQuantity() + 1);
        itemService.updateItem(it.getId(), it.getName(), it.getQuantity(), it.getPrice(), it.getBarcode(),
                it.getMinQuantity(), it.getImage(), it.getItemsToOrder(), it.getShippingCost());
        getInvoice().getItems().remove(it);
        getInvoice().setTotalCost(getInvoice().getTotalCost()- it.getPrice());
        this.setCartTotal(this.getCartTotal()-1);
    }

    @Remove
    public void saveInvoice() {
        em.persist(getInvoice());
        for (Item i : getInvoice().getItems()) {
            Item it = new Item();
            it = itemService.findItem(i.getBarcode());
            if (it.getQuantity() <= it.getMinQuantity()) {

                try {
                    Connection connection = connectionFactory.createConnection();
                    Session session = connection.createSession(true,
                            Session.AUTO_ACKNOWLEDGE);
                    MessageProducer producer = session.createProducer(destination);
                    ObjectMessage message = session.createObjectMessage();
                    ArrayList list = new ArrayList();
                    list.add(it.getBarcode());
                    list.add(it.getItemsToOrder());
                    message.setObject(list);
                    producer.send(message);
                    session.close();
                    connection.close();
                } catch (JMSException ex) {
                    Logger.getLogger(InvoiceBean.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    @Remove
    public void cancelInvoice() {
        this.setCartTotal(0);
        for (Item i : getInvoice().getItems()) {
            Item it = itemService.findItem(i.getBarcode());
            it.setQuantity(it.getQuantity() + 1);
            itemService.updateItem(it.getId(), it.getName(), it.getQuantity(), it.getPrice(),
                    it.getBarcode(), it.getMinQuantity(), it.getImage(), it.getItemsToOrder(), it.getShippingCost());
        }
        setInvoice(new Invoice());
        setCartTotal(0);
    }

    public void addCustomer(int customerID) {

        Customer cust = new Customer();
        cust = (Customer) customerService.findCustomer(customerID);
        System.out.println(cust.getEmail());
        getInvoice().setCustomer(cust);
    }

    /**
     * @return the invoice
     */
    public Invoice getInvoice() {
        return invoice;
    }

    /**
     * @param invoice the invoice to set
     */
    public void setInvoice(Invoice invoice) {
        this.invoice = invoice;
    }

    /**
     * @return the cartTotal
     */
    public int getCartTotal() {
        return cartTotal;
    }

    /**
     * @param cartTotal the cartTotal to set
     */
    public void setCartTotal(int cartTotal) {
        this.cartTotal = cartTotal;
    }
}


As you can see the stateless bean performs its other business methods and when it finally (@Remove to remove its instance and return it to the pool of stateless beans)  savesInvoice, it sends a message to the messaging server, only if the inventory level drops below the minQuantity.

So this takes care of part I. In Part II I will write the Warehouse's MDB.