JEE 5, meet Component Model…
Componentization is a well known issue when dealing with Web Dynpro Java Development Components. SAP component model and model view controller pattern (MVC) provide an easy and quick way to re-use your code.
However, code re-use can be a bit tricky when working with pure Java Enterprise 5 projects. Typically, what you might want to achieve is to group logically unrelated pieces of code in different Development Components.
If you are looking for a quick solution you can jump straight to the next section. For those of you interested in taking a look under the hood, the problems you may have found are:
- If you develop all your Enterprise Java Beans and Entities in a single DC you will probably end up with a huge DC, poor code reuse, long build times, low degree of concurrent modifications due to version control system constraints.
- If you place your entities in a single DC and your EJBs in a different DC and then pack them both in a Enterprise Archive (EAR) root, you will note that dependency injection for the EntityManager fails in the EJB DC. This is because of Java Persistence Architecture specifications in the matter of persistence unit visibility.
- JPA specification mandates that a persistence unit be visibile to the EJBs in the EAR root only if the persistence unit itself is contained in the EAR/lib folder. However, SAP component model only allows EAR/lib to contain public parts from Plain Java DCs (option “bundled_lib”) and not from EJB DCs.
- If you create multiple EJB DCs with JPA facet, multiple persistence units are created. Even though this may work great, often developers prefer to have a single persitence unit so as to use a single EntityManager
How can I make my code thin and fit?
The solution described below is based on grouping all your Entities in a single DC, organizing your EJBs in different DCs as you wish and then packing everything in a single EAR.
The component structure goes like this:
1 Java Plain DC: it contains all your Entities. Two public parts: one for assembly (jp_asm: containing all your packages and the META-INF folder), one for compilation (jp_cpl: containing only your packages). JPA facet must be enabled. In case NWDS should prevent you from adding the facet, simply add a dependency from the EAR DC (we’ll talk about it in a while) to jp_asm public part. EJBs are not allowed in this DC. This DC must depend on DC engine.jee5.facade.
1 Data Dictionary DC: your tables will be generated here. Configure you plain java DC to generate tables as you would normally do with an EJB DC.
1..n EJB DCs: These DCs contain all your EJBs, arranged as you wish. Each EJB must depend upon jp_cpl public part for compilation. They can even depend upon each other of course, if you declare dependency on the client public part of a given EJB DC.
1 EAR DC: This DC depends upon jp_asm public part and of course upon the EJB DCs you have created. Dependency must be of type “bundled_lib”. This is fundamental as it is this option that allows the public part jar containing your entities to be packed in the EAR/lib folder, thus providing EAR scope to the entities.
A solution has been presented to componentize pure JEE projects. The advantage is that developers can clearly isolate Business Logic Layer (EJBs) from Persistence Layer (JPA entities).
In addition, when using version control systems, an increase in the degree of concurrent modifications is possible, provided EJB DCs have been logically designed.
Thanks to Rolf Paulsen for providing great insight on the subjects above in JPA/EJB3: DC reuse thread