Adam Bien's Weblog
Simplest Possible EJB 3.1 / REST (JSR-311) Component
The component realization resides in the package: [...].business.orderprocessor. It is deployed as a WAR. The business is the name of the layer/tier and the orderprocessor the component's realization. Why this packages? It is easier to manage dependencies between them during the continuus integration.
The component "orderprocessor" is organized internally in three, technical layers - also realized as packages:
- boundary: the external visible contract, the actual facade
- control: the actual business logic implementation
- entity: the persistence
Each package represents a responsibility and helps you also to measure the dependencies inside the component. E.g. elements from the entity package should not access the control or boundary.
The boundary is implemented as a no-interface view @Stateless EJB 3.1:
@Path("/orders/") @Interceptors(CallAudit.class) @Stateless public class OrderService { @EJB BillingService billing; @EJB DeliveryService delivery; @EJB Warehouse warehouse; @PUT @Produces({"application/xml","application/json"}) @Consumes({"application/xml","application/json"}) public Order order(Order newOrder){ Order order = warehouse.checkout(newOrder); billing.payForOrder(order); delivery.deliver(order); return order; } @GET @Path("{orderid}/") @Produces({"application/xml","application/json"}) public Order status(@PathParam("orderid") long orderId){ return delivery.status(orderId); } }The functionality is directly exposed via REST, so there is no need to introduce dedicated interfaces. The OrderService starts transactions, can be decorated with cross-cutting aspects and represents the single entry point. Its a facade.
An element from the control layer simply relies on the existence of transactions - it is always executed in the boundary context.
@Stateless
public class DeliveryService {
@PersistenceContext
EntityManager em;
public void deliver(Order order){
System.out.println("Delivered: " + order);
order.setDelivered(true);
}
public Order status(long orderId) {
Order found = this.em.find(Order.class, orderId);
if(found == null)
found = new Order();
return found;
}
}
The entity layer consists of JPA-entities, either domain driven, or procedural.
@Entity
@Table(name = "T_ORDER")
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlElement
private long id;
@XmlElement
private int amount;
@XmlElement
private int productId;
@XmlElement
private boolean delivered;
public Order() {
}
public Order(int amount, int productId) {
this.amount = amount;
this.productId = productId;
}
public boolean isDelivered() {
return delivered;
}
public void setDelivered(boolean delivered) {
this.delivered = delivered;
}
}
The Order entity is also annotated with JAXB-annotations - what allows its serialization via XML or JSON without any additional work. In real world you will probably have to introduce a DTO to separate the different aspects of DB and XML serialization.
EJB 3.1 and JSR-311 (REST) fit perfectly together. You can expose EJB 3.1 directly as REST-facades and gain single-threaded programming model, transactionality etc. The dependency to the EJB 3.1 API is very low (two annotations) - you could even go without any annotation.
The JUnit-tests are simple as well:
[...] import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; import static org.mockito.Mockito.*;public class OrderServiceTest { private OrderService orderService; @Before public void initOrderService() { this.orderService = new OrderService(); this.orderService.billing = new BillingService(); this.orderService.delivery = new DeliveryService(); this.orderService.warehouse = mock(Warehouse.class); } @Test public void testOrder() { Order order = new Order(2, 1); when(this.orderService.warehouse.checkout(order)).thenReturn(order); Order ordered = this.orderService.order(order); assertNotNull(ordered); assertTrue(ordered.isDelivered()); } }
The whole sample (LeanServiceECBComponent), tested with Netbeans 6.7.1/6.8m1 and Glassfishv3, was pushed into: http://kenai.com/projects/javaee-patterns/ After opening the LeanServiceECBComponent in Netbeans6.8(m1), right mouse-click on the project and choose "Test RESTFul Web Services".
This component is also described in the current JavaMagazin issue in more detail.
[The whole book "Real World Java EE Patterns - Rethinking Best Practices" describes lean Java EE architectures and patterns. See ServiceFacade, Service, PDO patterns and the chapter 6 "Pragmatic Java EE Architectures", Page 253]
Posted at 09:17AM Aug 11, 2009 by Adam Bien in Real World Java EE Patterns - Rethinking Best Practices | Kommentare[9]
[my tweets]
Rss My book: Real World Java EE - Rethinking Best Practices


Hi Adam,
you could also use @Mock Annotation.
Instead writing:
this.orderService.warehouse = mock(Warehouse.class);
You just add the @Mock Annotation to the OrderService Implementation:
@EJB @Mock Warehouse warehouse;
Then in the @Before Method of your Test you initializes the Mocks as follows:
MockitoAnnotations.initMocks(this.orderService);
This is great!
Regards,
Robert
Gesendet von Robert am August 11, 2009 at 12:47 PM CEST #
on OrderService you have 12 lines of annotations and something like 8 usual code. Fun! I guess it can be explained - it is a service and need some @ to activate. But, anyway, i could only notice that
Gesendet von Gabriel Kastenbaum am August 13, 2009 at 02:38 PM CEST #
How is the EntityManager inside DeliveryService initialized during the test?
Can I use Constructor-Injection to avoid those public fields annotated with EJB?
Gesendet von Sakuraba am August 14, 2009 at 06:55 PM CEST #
@Sakuraba,
you can use either constructors, or setters to set the EntityManager during the test. I just prefer to use the package-visibility - you can keep your code more concise,
adam
Gesendet von Adam Bien am August 14, 2009 at 09:13 PM CEST #
So you basically would add a persistence-unit xml-file for testing, start e.g. a local hsqldb instance before the test, create the EntityManagerFactory /EntityManager for this test-persistence-unit. Afterwards one could do "delivery.em = mytestEM;" inside the Before-methods or use EasyMock for the EntityManager alltogether.
Gesendet von Sakuraba am August 15, 2009 at 03:49 PM CEST #
@Sakuraba,
either that, or use Mockito to mock-out the EM entirely. You can easily factor out the creation of the EntityManager into a super class (2-liner). It works perfectly in real world.
Did you expected something else?
thansk,
adam
Gesendet von Adam Bien am August 15, 2009 at 10:21 PM CEST #
Well... actually yes, I didnt think it would be that easy.
Thanks for your responses ;)
Gesendet von Sakuraba am August 20, 2009 at 07:31 PM CEST #
Hi adam,
" In real world you will probably have to introduce a DTO to separate the different aspects of DB and XML serialization."
Do you know an existing example on how to do this?
Gesendet von JanVerbeke am December 26, 2009 at 05:21 PM CET #
@Jan,
sure - it is trivial plumbing. You will have to read the state of the DB entity in the boundary and copy the interesting contents into a XML- DTO,
This isn't mandatory - such approach often evolves during a project. I wouldn't start with a such separation. Start with a spike / poc then see whether your approach "feels right",
adam
Gesendet von Adam Bien am December 26, 2009 at 10:10 PM CET #