CHAPTER 1 EJB Layer Architectural Patterns When first designing Enterprise JavaBean(EJB)systems,choosing a correct architecture,or partitioning of logic,that satisfies project concerns,such as performance,maintainability,and portability,is one of most difficult tasks faced by developers.This chapter covers some fundamental architectural patterns in use in the industry today,specifically: Session Facade.The most widely used of all EJB design patterns,the Ses sion Facade shows how to properly partition the business logic in your system to help minimize dependencies between client and server,while forcing use cases to execute in one network call and in one transaction. Message Facade.The Message Facade pattern discusses when and how to partition logic for use cases that are asynchronous in nature. EJB Command.The antithesis of the Session Facade pattern,the EJB Com- mand Pattern advocates placing business logic in lightweight,plain Java Command beans.The main benefits of the pattern are the complete decoupling of the client from EJB itself and the execution of use cases in one network call and transaction. Data Transfer Object Factory.Debunks the old practice of placing DTO creation/consumption logic on the entity bean itself and prescribes centralizing data transfer object creation and consumption logic into a single layer(implemented as session beans or plain java factories)
3 When first designing Enterprise JavaBean (EJB) systems, choosing a correct architecture, or partitioning of logic, that satisfies project concerns, such as performance, maintainability, and portability, is one of most difficult tasks faced by developers. This chapter covers some fundamental architectural patterns in use in the industry today, specifically: Session Façade. The most widely used of all EJB design patterns, the Session Façade shows how to properly partition the business logic in your system to help minimize dependencies between client and server, while forcing use cases to execute in one network call and in one transaction. Message Façade. The Message Façade pattern discusses when and how to partition logic for use cases that are asynchronous in nature. EJB Command. The antithesis of the Session Façade pattern, the EJB Command Pattern advocates placing business logic in lightweight, plain Java Command beans. The main benefits of the pattern are the complete decoupling of the client from EJB itself and the execution of use cases in one network call and transaction. Data Transfer Object Factory. Debunks the old practice of placing DTO creation/consumption logic on the entity bean itself and prescribes centralizing data transfer object creation and consumption logic into a single layer (implemented as session beans or plain java factories). EJB Layer Architectural Patterns CHAPTER 1
4 Chapter One Generic Attribute Access.This pattern discusses when and how to pro- vide a domain-generic interface to the attributes of an entity bean for maintainability and performance purposes. Business Interface.This pattern shows how to implement an interface implementation scheme that can provide compile-time checking of the method signatures on the Remote/Local interfaces and the EJB bean class
Generic Attribute Access. This pattern discusses when and how to provide a domain-generic interface to the attributes of an entity bean for maintainability and performance purposes. Business Interface. This pattern shows how to implement an interface implementation scheme that can provide compile-time checking of the method signatures on the Remote/Local interfaces and the EJB bean class. 4 Chapter One
EJB Layer Architectural Patterns 5 Session Facade An EJB client needs to execute business logic in order to complete a use case How can an EJB client execute a use case's business logic in one transaction and one bulk network call? To execute the business logic of a typical use case,multiple server-side objects(such as session or entity beans)usually need to be accessed and possi- bly modified.The problem is that multiple fine-grained invocations of ses sion/entity beans add the overhead of multiple network calls(and possibly multiple transactions),as well as contributing to less maintainable code,since data access and workflow/business logic is scattered across clients. Consider an online banking scenario where a servlet receives a request to transfer funds from one account to another,on behalf of a Web client.In this scenario(as depicted in Figure 1.1),a servlet must check to ensure that the user is authorized,withdraw funds from one bank account entity bean,and deposit them to the other bank account entity bean. Servlet UserHome Account1 Account2 ndByPrimaryKey(pk) isAuthorized( findByPrimaryKey(account1PK) findByPrimaryKey(account2PK) withdrawFunds(amount) depositFunds(amount) Figure 1.1 Client transferring funds between entity beans
Session Façade An EJB client needs to execute business logic in order to complete a use case. How can an EJB client execute a use case’s business logic in one transaction and one bulk network call? * * * To execute the business logic of a typical use case, multiple server-side objects (such as session or entity beans) usually need to be accessed and possibly modified. The problem is that multiple fine-grained invocations of session/entity beans add the overhead of multiple network calls (and possibly multiple transactions), as well as contributing to less maintainable code, since data access and workflow/business logic is scattered across clients. Consider an online banking scenario where a servlet receives a request to transfer funds from one account to another, on behalf of a Web client. In this scenario (as depicted in Figure 1.1), a servlet must check to ensure that the user is authorized, withdraw funds from one bank account entity bean, and deposit them to the other bank account entity bean. Figure 1.1 Client transferring funds between entity beans. User findByPrimaryKey(pk) Account Home Servlet UserHome Account 1 Account2 isAuthorized() findByPrimaryKey(account1PK) findByPrimaryKey(account2PK) withdrawFunds(amount) depositFunds(amount) EJB Layer Architectural Patterns 5
6】 Chapter One When executing methods on the entity beans home and remote interface, this approach will not scale under serious loads,because the whole scenario requires at least six network calls:three for finding the appropriate entity beans,and three more for actually transferring the funds.Furthermore,since entity beans are transactional creatures,each method call on an entity will require a separate transaction on the server side,requiring synchronization of the remote entity with its underlying data store and maintenance on behalf of the application server. What's worse is that this approach won't guarantee the safety of the client's money.If something goes wror ng with the de osit,the client's money will have already been withdrawn,and his money will be lost.The user authorization check,the withdrawal,and the deposit all run completely separately,and if the deposit fails,the withdrawal will not be rolled back,resulting in an inconsistent state.The probler m here is that when calling an entity bean's methods directly, each method call is a separate unit of work,and a separate transaction. One solution is to push extra logic into our entity beans to perform many operations on behalf of a single client call.This solution introduces mainte ance problems,because our entity bean layer will likely be used in many different ways over time.If we add application logic to our entity beans each time we need a performance enhancement,our entity beans will quickly become very bloated and difficult to understand,maintain,and reuse.We are effectively erging our application logic (verbs)with our persistence logic (nouns),which is poor application design. Another approach is for our client to demarcate an aggregate,large transac- tion via the Java Transaction API TA).This would make each entity bean method call un nder the ame tran ction an all-or othing fashion If the deposit f ails,then the withdrawal will be rolled back and the users'money will be safe.However,this improved solution also has many drawbacks: High network overhead.We still have six network calls to deal with which slows performance (unless we use local interfaces). Poor concurrency.If the client is located very far from the server(as in the case of an applet or application interacting with a remote EJB sys- tem,perhaps even across the Internet or a firewall),the transaction will last for a long period of time e.This causes excess locking,increasing the chances of collisions or deadlock,and reduces concurrency of other clients accessing the same entity bean instances. High coupling.Our client writes directly to an entity bean API,which tightly couples the client with the entity bean.If the entity bean layer needs changing in the future,then we must also change the client
When executing methods on the entity beans home and remote interface, this approach will not scale under serious loads, because the whole scenario requires at least six network calls: three for finding the appropriate entity beans, and three more for actually transferring the funds. Furthermore, since entity beans are transactional creatures, each method call on an entity will require a separate transaction on the server side, requiring synchronization of the remote entity with its underlying data store and maintenance on behalf of the application server. What’s worse is that this approach won’t guarantee the safety of the client’s money. If something goes wrong with the deposit, the client’s money will have already been withdrawn, and his money will be lost. The user authorization check, the withdrawal, and the deposit all run completely separately, and if the deposit fails, the withdrawal will not be rolled back, resulting in an inconsistent state. The problem here is that when calling an entity bean’s methods directly, each method call is a separate unit of work, and a separate transaction. One solution is to push extra logic into our entity beans to perform many operations on behalf of a single client call. This solution introduces maintenance problems, because our entity bean layer will likely be used in many different ways over time. If we add application logic to our entity beans each time we need a performance enhancement, our entity beans will quickly become very bloated and difficult to understand, maintain, and reuse. We are effectively merging our application logic (verbs) with our persistence logic (nouns), which is poor application design. Another approach is for our client to demarcate an aggregate, large transaction via the Java Transaction API (JTA). This would make each entity bean method call operate under the same transaction, in an all-or-nothing fashion. If the deposit fails, then the withdrawal will be rolled back and the users’ money will be safe. However, this improved solution also has many drawbacks: ■■ High network overhead. We still have six network calls to deal with, which slows performance (unless we use local interfaces). ■■ Poor concurrency. If the client is located very far from the server (as in the case of an applet or application interacting with a remote EJB system, perhaps even across the Internet or a firewall), the transaction will last for a long period of time. This causes excess locking, increasing the chances of collisions or deadlock, and reduces concurrency of other clients accessing the same entity bean instances. ■■ High coupling. Our client writes directly to an entity bean API, which tightly couples the client with the entity bean. If the entity bean layer needs changing in the future, then we must also change the client. 6 Chapter One