Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Lean service architectures with Java EE 6

Elements and patterns of a lean SOA

  • Print
  • Feedback

Page 2 of 6

And the essential complexity

SOA implies distribution of services, which is not always necessary or desirable in a Java EE application. It would be foolish to access a local service remotely just to satisfy some high-level SOA concepts. Direct local access should always be preferred over remote services. A local call is not only orders of magnitude faster than a remote one; the parameters and return values can also be accessed "per reference" and need not be serialized.

Whether the service is local or remote, the business logic should always be executed consistently. A component needs a dedicated remoting and transaction boundary interface, which acts as a gatekeeper (see Figure 1). The main responsibility of such a facade is to keep the granularity of the methods coarse and the persistent state of the component consistent.

Figure 1. Remoting / transactions boundary

Figure 1. Remoting/transactions boundary

You can achieve the right granularity only by carefully crafting the interface so that consistency can be easily ensured with built-in transactions. Listing 1 shows how to configure declarative transactions and expose a remote business interface.

Listing 1. Declarative transaction and remoting declaration

package ...bookstore.business.ordermgmt.facade;

@Stateless
@Remote(OrderService.class)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class OrderServiceBean implements OrderService {
    @EJB
    private CrudService crudService;    
    @EJB
    private VatCalculator vatCalculator;
    @EJB
    private PriceCalculator pc;
    @EJB
    private OrderProcessor op;
    @EJB
    private ShipmentService shipmentService;
  
    
public Shipment orderBook(int customerId,int isbn){
  BigDecimal priceNoVat = this.pc.computePrice(customerId, isbn);
  BigDecimal price = this.vatCalculator.computeVat(priceNoVat);
  Order o = this.op.processOrder(customerId, customerId, price);
  return this.shipmentService.deliver(o);
}
    
public Shipment findShipment(long shipmentId){
         return this.shipmentService.find(shipmentId);
}
//some methods omitted
}

Applying the @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) annotation to the class causes all methods to inherit this setting automatically. You could, alternatively, rely on the default (which is TransactionAttributeType.REQUIRED) and not specify a transaction setting. However, the OrderService is the transaction and remoting boundary. It is accessed exclusively by the UI, which must not start any transactions. Using the REQUIRES_NEW attribute is more explicit. It always starts a new transaction, which is what you would expect from a boundary. The REQUIRED configuration, if it were invoked without a transaction context, would reuse an existing transaction or start a new one. A boundary, however, will never be invoked in an existing transaction, which makes the default setting more confusing.

The @Remote annotation is applied to the bean class -- not the business interface -- which may look strange at the first glance. The business interface does not follow coding conventions either: its name doesn't contain the Remote suffix. As a result, the service consumer sees only a plain old Java interface and is not directly aware of using an EJB. Only an indirect dependency on unchecked exceptions is present. If you are building a Web application, the OrderServiceBean would be exposed with a local business interface only, whereas a rich client runs in a separate process and requires a remote interface. In either case there is no need to further emphasize the business interface's distributive capabilities. It gets injected or looked up, and the consumer is only interested in the functionality and not its remote visibility.

  • Print
  • Feedback

Resources

More from JavaWorld