With the new Smooks Persistence cartridge in Smooks 1.2 you can directly use several entity persistence frameworks from within Smooks. In this post I will show you how this works with Hibernate and any other JPA compatible framework.
This post is part of a multi post article. You can find the previous post here: Smooks Persistence part 1: The Introduction
In this post we will look at an example of how to persist Hibernate Entities. This example is based on the example of the previous post.
First, lets take a look at the data we are going to process. In this example we are processing XML data. It should be noted however, that the input data could also be CSV, JSON, EDI, Java or any other structured/hierarchical data format. The same principals apply, no matter what the data format is!
<order>
<ordernumber>1</ordernumber>
<customer>123456</customer>
<order-items>
<order-item>
<product>11</product>
<quantity>2</quantity>
</order-item>
<order-item>
<product>22</product>
<quantity>7</quantity>
</order-item>
</order-items>
</order>
These are the Hibernate entities we are going to use:
@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);
}
// Getters and Setters....
}
@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;
// Getters and Setters....
}
@Entity
@Table(name = "products")
@NamedQuery(name="product.byId", query="from Product p where p.id = :id")
public class Product {
@Id
private Integer id;
@Basic
private String name;
// Getters and Setters....
}
The Smooks configuration looks like this:
<!-- In this example, we don't need to reference the Hibernate Session anywhere in the configuration. Later on, in the Smooks execution code (following snippet), you will see that we have set the Session as the default Session. This means that you don't need to reference it by name. In the configuration of the previous post, we needed to reference every DAO by its name. --> <smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.1.xsd" xmlns:dao="http://www.milyn.org/xsd/smooks/persistence-1.2.xsd"> <!-- This is a normal Javabean binding. It creates the order bean and binds data into it. --> <jb:bindings beanId="order" class="example.entity.Order" createOnElement="order"> <jb:value property="ordernumber" data="ordernumber" /> <jb:value property="customerId" data="customer" /> <jb:wiring setterMethod="addOrderLine" beanIdRef="orderLine" /> </jb:bindings> <!-- This is a normal Javabean binding. Notice that we have a wiring on 'product'. The Product entity will not be created, but looked up by a locator. --> <jb:bindings beanId="orderLine" class="example.entity.OrderLine" createOnElement="order-item"> <jb:value property="quantity" data="quantity" decoder="Integer" /> <jb:wiring property="order" beanIdRef="order" /> <jb:wiring property="product" beanIdRef="product" /> </jb:bindings> <!-- This locator calls (via Scribe) the SessionDaoAdapter#lookupByQuery() method. The result will be added to the bean repository under the bean id 'product'. An exception is thrown when no result is found. --> <dao:locator beanId="product" lookupOnElement="order-item" onNoResult="EXCEPTION" uniqueResult="true"> <dao:query>from Product p where p.id = :id</dao:query> <dao:params> <dao:value name="id" data="product" decoder="Integer" /> </dao:params> </dao:locator> <!-- The inserter calls (via Scribe) the SessionDaoAdapter#insert() method at the visitAfter of the Order element. The SessioDaoAdapter#insert() uses the Hibernate Session#save() method to persist the entity to the database. --> <dao:inserter beanId="order" insertOnElement="order" /> </smooks-resource-list>
If we want to use the named query ‘productById’ instead of the query string then the DAO locator configuration will look like this:
<!--
The lookup parameter is the query name
-->
<dao:locator beanId="product" lookupOnElement="order-item" lookup="product.byId"
onNoResult="EXCEPTION" uniqueResult="true">
<dao:params>
<dao:value name="id" data="product" decoder="Integer"/>
</dao:params>
</dao:locator>
The following code executes Smooks. Note that we use a SessionRegister object so that we can access the Hibernate Session from within Smooks.
// Note: In a real world application you should cache the Smooks instance
// else you will have enormous performance penalties.
Smooks smooks = new Smooks("smooks-config.xml");
ExecutionContext executionContext = smooks.createExecutionContext();
// The SessionRegister provides the bridge between Hibernate and the
// Persistence Cartridge. We provide it with the Hibernate session.
// The Hibernate Session is set as default Session.
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("order.xml"));
smooks.filter(source, null, executionContext);
transaction.commit();
If you want to take a JPA version of this example for a spin, simply check out the examples from subversion (http://svn.codehaus.org/milyn/trunk/smooks-examples/) and you’ll find it in the “dao-router” folder. It also shows you how to use custom DOA’s with the Persistence Cartridge.
With Scribe and the Persistence Cartridge it is very easy to use Hibernate, JPA and most other persistence frameworks within Smooks. Later on in this series I will explain how too write your own DAO Adapters, so that you can add support for other persistence frameworks.
In the next post of the series I will explain how you can use Ibatis with the Persistence Cartridge.

