Monday, March 19, 2012

Smooks Entity Persistence Frameworks - Hibernate


With the new Smooks Persistence cartridge in Smooks 1.2, we can directly use several entity persistence frameworks from within Smooks (Hibernate, JPA etc). So in this blog post let's try out the Hibernate sample specified in here.
Since smooks have given the basic configurations only, this blog post is going to assist the peolple who need full implementation.

What we are going to do is process the following XML message and store the product information to a bean and persist the order information.



input.xml
------------


    1
    123456
    
        
            11
            2
        
        
            22
            7
        
    

First we have to Specify our Entity classes (Order, OrderLine, Product)
//Order class
package example.entity;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.*;

@Entity
@Table(name="orders")
public class Order {
 
    @Id
    private Integer ordernumber;
 
    @Basic
    private String customerId;
 
    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
    private List orderItems = new ArrayList();
 
    public void addOrderLine(OrderLine orderLine) {
        orderItems.add(orderLine);
    }
    
    public Integer getOrdernumber() {
 return ordernumber;
 }

   public void setOrdernumber(Integer ordernumber) {
 this.ordernumber = ordernumber;
 }

   public String getCustomerId() {
 return customerId;
 }

   public void setCustomerId(String customerId) {
 this.customerId = customerId;
 }

   public List getOrderItems() {
 return orderItems;
 }

   public void setOrderItems(List orderItems) {
 this.orderItems = orderItems;
 }

}
//OrderLine class 
package example.entity;

import javax.persistence.*;

@Entity
@Table(name = "orderlines")
public class OrderLine {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Integer id;

 @ManyToOne
 @JoinColumn(name = "orderid")
 private Order order;
 
 @Basic
 private Integer quantity;

 @ManyToOne
 @JoinColumn(name = "productid")
 private Product product;

 public Integer getId() {
  return id;
 }

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

 public Order getOrder() {
  return order;
 }

 public void setOrder(Order order) {
  this.order = order;
 }

 public Integer getQuantity() {
  return quantity;
 }

 public void setQuantity(Integer quantity) {
  this.quantity = quantity;
 }

 public Product getProduct() {
  return product;
 }

 public void setProduct(Product product) {
  this.product = product;
 }

}
//Product Class
package example.entity;

import javax.persistence.*;

@Entity
@Table(name = "products")
public class Product {
 
    @Id
    private Integer id;
   
 @Basic
    private String name;

 public Integer getId() {
  return id;
 }

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

 public String getName() {
  return name;
 }

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

}
Here is the Smooks configuration to bind xml message to java beans and persist the order entity. 
smooks-hbt-config.xml
-----------------------------------



     
    
        
        
        
    
 
     
    
        
        
        
    
 
    
    
        from Product p where p.id = :id
        
            
        
    
 
    
    
     
So now you would wonder where we store the datasource configuration. If we just use Hibernate we can configure datasource information inside hibernate.cfg.xml

  
    jdbc:mysql://localhost:3306/dbname
    uname
    pwd
    com.mysql.jdbc.Driver
    org.hibernate.dialect.MySQLDialect
 
    false
 
    true
    update
 
    
    1
    thread
  
  
  
  
 
The database represented in the connection must have 4 tables.


customers (id int(11), name varchar(30))
products (id int(11), name varchar(30))
orders (ordernumber int(11), customerId varchar(30))
orderlines (id int(11), quantity int(11), orderid int(11), productid int(11))

Insert the following sample data to customers and procucts tables.

insert into customers (id, name) values (123456, 'Devin Snow');
insert into customers (id, name) values (789101, 'Homer Simpson');
insert into customers (id, name) values (999999, 'John Doe');

insert into products  (id, name) values (11, 'Cheese cake');
insert into products  (id, name) values (22, 'Chocolate 300gr');
insert into products  (id, name) values (33, 'Beer');
insert into products  (id, name) values (44, 'Smooks in Action');
insert into products  (id, name) values (55, 'Ultimate guide to Smooks');

Let's execute Smooks now. 

package example.main;

import java.io.File;
import java.io.IOException;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.milyn.Smooks;
import org.milyn.container.ExecutionContext;
import org.milyn.persistence.util.PersistenceUtil;
import org.milyn.scribe.adapter.hibernate.SessionRegister;
import org.milyn.scribe.register.DaoRegister;
import org.xml.sax.SAXException;

public class Main {

 public static void main(String args[]) throws IOException, SAXException {
  Smooks smooks = new Smooks("smooks-hbt-config.xml");

  ExecutionContext executionContext = smooks.createExecutionContext();

  SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
   
  Session session = sessionFactory.openSession();
  DaoRegister register = new SessionRegister(session);
   
  // This sets the DAO Register in the executionContext for Smooks //to access it. 
  PersistenceUtil.setDAORegister(executionContext,register);
   
  Transaction transaction = session.beginTransaction();
  
  Source source = new StreamSource(new File("input.xml"));
   
  smooks.filterSource(executionContext, source);
   
  transaction.commit();

 }