Pattern based development: Defining SOA Frameworks, part III – enabling JPA

Pattern based development: Defining SOA Frameworks, part III – enabling JPA

This is the last article, dedicated to establishing the optimal service delivery platform. Here we will see what kind of tools can help us with automation JPA developing – setting annotations, creation named queries, adding O-R mapping, and writing persistence Entity Manager for entity containers.

Typical Entity Service architecture

Here we continue on building reusable Entity service for Employee enterprise object. Apparently this is not a first exercise around Employee object. Reasons to do that are - discovered problems with straight-forward (bottom-up) implementation on Oracle adapters and inability of Oracle tools to support top-down “Contract first” design approach, when it comes to JAXB implementation. We halfway there, and to understand where exactly and what it takes to make implementation complete better to look at the service internal architecture (Entity model and the primary building block) a bit closer. On the top the Thomas Erl’s Service Resource Notation is used (http://www.arcitura.com/notation), below JDeveloper UML modelling capacity are demonstrated, linking DB and EJB resources.

The positive thing about JDeveloper modelling capability is that we can combine in one model Java classes and DB objects (as presented above), resided in another project as Offline DB Sources. For creating DB objects, dragging from another offline DB project in this model in dialog “Create As” select “Business Component Entity Objects” from the list, not a “Database Objects” as initially suggested, otherwise you will get a compatibility error. To simplify modelling, the Offline DB Objects should be created in the same EmployeeWS project. 

JPA Essential parts (using Geronimo)

Nevertheless, the figure above indicates that part 1 is done using JAXB annotations, and part 2 is what shall be implemented using persistence technology JPA. Capital J on classic (Erl’s) diagram above removed as vendor neutrality is one of the SOA characteristics. Still, Java persistence architecture (JPA) is the primary means of persevering/extracting object state in DB.

Similar to JAXB, JPA is a programming model, originally based on JSR 220 specification. Concrete API realisation can vary from vendor to vendor (check OpenJPA from Apache Geronimo [3] (http://geronimo.apache.org/GMOxDOC30/developing-bean-managed-persistence-with-jpa.html). 

In mentioned above Geronimo JPA example clear top-down design approach is demonstrated, where EJB modules created for Account and Person entities with necessary references. This is a web application, not a web service, so the Contract first design here starts from Java interface (also form of a Contract, like WSDL).

public interface AccountInterface {
      public void initialize(int accountNumber);
      public String getPersonName();
      public void setPersonName(String personName);
      public String getAddress();
      public void setAddress(String address);
      public double getBalance();
      public void setBalance(double balance);
      public void updateAllValues(String address, String personName, double balance);
      public void withdraw(double amount);
      public void deposit(double amount);
}

The AccountBean uses EntityManagerFactory injection for creating EntityManager object (see the snippet below), mentioned in JPA task list (step 2) in the previous post. 

@Stateful
@TransactionManagement(TransactionManagementType.CONTAINER)
@Local(AccountInterface.class)
public class AccountBean implements AccountInterface{

       @PersistenceUnit(unitName="AccountUnit")
       private EntityManagerFactory emf;

      private EntityManager em;

      Account account;
      Person person;

      @PostConstruct
      public void init(){
            em = emf.createEntityManager();
      }

EntityManager is used in initializer as 

account = em.find(Account.class, accountNumber);
if(account == null)throw new IllegalStateException("Account number
("+accountNumber+") not found");

Step 1 in JPA task list (create DB) is also fulfilled manually using Geronimo server console, after beans creation. DB Pool for Datasource, used in the project is also created via console. Actually this is not what we really need, as DB was created, also manually, from XSD in the first part of this post and used by BPEL adapters.

Implementing JPA using JDeveloper

Naturally, Oracle suggests TopLink persistence for JDeveloper and Eclipse (via Dali project) SDP workbenches. Firstly, TopLink shall be included into projects classpath, as shown below

Technically, the task is clear. To present persistence we should map class attributes to DB fields of corresponding table, starting from unique ID, make sure that class is a serializable Entity and add named query. Our classes already have accessors, so we they will be used for attribute population. Manually it can be done pretty straight forward, starting from adding @Stateless, @Local, @Entity, @Id annotations.

The SDP we strive to establish preferably should provide the automated way for maintaining persistence, right from IDE, employing both supported in EJB 3 ways – XML and annotations. If acceptable automation is not possible we can revert to manual way. Oracle propose some automation within MVC Web Application ADF.

(http://docs.oracle.com/cd/E37547_01/tutorials/tut_jpa_app/tut_jpa_ejb_4.html). The point is that this is truly Front-End oriented MVC framework and even with lots of available automation, lost of annotations and required named queries shall be added manually. Framework created lots of session facades, which are not really required for top-down SOAP WS approach, we need something a bit more lightweight.

Implementing JPA using JBoss Developer Studio

Oracle JDeveloper provides bottom-up wizard for establishing persistence units right from DB and we will not go this way, at least not now. We could return to this option just to have it as reference implementation. Like in previous post we will see how EJB 3.0 annotation automation can be done in JBoss Developer Studio. In our Eclipse WebServiceProject in every package we have *RecordType class, corresponding to individual Employee associated entity. We can use Eclipse JPA Tools for each of them to make it persistent, pls see screenshot below: 

1. *RecordType class has been selected for adding persistence.



2. In the next step we should choose JPA implementation (Annotation or XML mapping, first is more preferable), associate atomic java class with corresponding table (PersonRecordType -> PERSON) and for that we should select relevant DB connection and schema. All important fields are highlighted below, including primary key attribute



Directly associated attributes will be mapped immediately, but some associated objects (like Person- Address) will be presented as “unspecified”. To fix it, select edit and in next window select cardinality (1-to-1 or many-to-1), cascading, fetching type and Join table, as presented below


The final result (for PERSON) will contain practically all required annotations and associations.

@Entity
@Table(name = "PERSON")
public class PersonRecordType {

    @XmlElement(name = "Source_ID", required = true)
    @Column(name = "SOURCE_ID", scale = -127)
      protected String sourceID;
    @XmlElement(name = "Target_ID", required = true)
    @Column(name = "TARGET_ID", scale = -127)
      protected String targetID;
    @XmlElement(name = "Title", required = true)
    protected String title;
    @XmlElement(name = "AddressList", required = true)
    @OneToOne(fetch = LAZY, cascade = ALL)
    @JoinTable(name = "PERSON_ADDRESS")
      protected PersonRecordType.AddressList addressList;

Back to JDeveloper

Still some things are missing here, as it was mentioned above, at least we expected serializable entity. We need a quick and reliable way to check consistency of applied persistence. One way of doing this could be employing again JDeveloper for creating Entities from the Tables - exactly the opposite way, similar to top-down implementation approach, presented by red arrow on the first figure. This approach doesn’t break the “Contract-first” design approach, as we need only proper ORM mapping and incorporate it into already existing WS classes. This mapping is registered in persistence.xml descriptor, which shall define linking Data Source (jtaDataSource) with java classes in our project, in addition to other essential JPA parameters, see figure below.


After completing generation entities from tables it would be interesting to compare JDeveloper (“A”, left side ) entities with persisted in JBoss Dev Studio (“B”, on the right side) side by side and after analysing the JPA implementation discrepancies address them in WS project, see the figure below


First thing can be spotted right away – entities from tables (“A”) constructed too plainly – one entity per table, where JAXB provided more OOP-related result. We got QDO package (“B”), containing all enumerators, reusable complex types and so on. Despite of purity of this approach, it means that persistence to this objects shall be added individually, using JPA Tools -> make persistent, as it is demonstrated for the common object Name on the right side above. When this tedious job is done, we can import results back to the JDeveloper again (we didn’t give up the idea to have Oracle-based SDP), persistence descriptor must be updated accordingly, as we did two steps above. To maintain jtaDataSource one way would be to add off-line DB into our project, see below

After that we will have all essential properties covered in our persistence unit.

Some help from NetBeans

Next issue is related to the implementation of EntityManager, required according to [1] for EJB 3.0 and presented at the beginning of this post. Instantiated EntityManager should implement at list two basic methods – find() and persist(). The first one will require a query, and all CRUD operations will require related queries (in our case we will need findById, declared in WSDL). From our JDeveloper exercise we got findAll (of course, if checkbox was selected in the wizard), as below

@Entity
@NamedQueries({ @NamedQuery(name = "Address.findAll", query = "select o from Address o") })
public class Address implements Serializable {
    private static final long serialVersionUID = 3841719021409177558L;

Here again we can do it manually for every individual field, or use another option – employ another tool, NetBeans to generate array of NamedQueries

The result will be as follow (for Address) 

Entity
@Table(name = "ADDRESS")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Address.findAll", query = "SELECT a FROM Address a"),
    @NamedQuery(name = "Address.findById", query = "SELECT a FROM Address a WHERE a.id = :id"),
    @NamedQuery(name = "Address.findByCity", query = "SELECT a FROM Address a WHERE a.city = :city"),
    @NamedQuery(name = "Address.findByCountry", query = "SELECT a FROM Address a WHERE a.country = :country"),
    @NamedQuery(name = "Address.findByPostcode", query = "SELECT a FROM Address a WHERE a.postcode = :postcode"),
    @NamedQuery(name = "Address.findByStreetname", query = "SELECT a FROM Address a WHERE a.streetname = :streetname"),
    @NamedQuery(name = "Address.findByStreetnumber", query = "SELECT a FROM Address a WHERE a.streetnumber = :streetnumber"),
    @NamedQuery(name = "Address.findByStateorprovince", query = "SELECT a FROM Address a WHERE a.stateorprovince = :stateorprovince"),
    @NamedQuery(name = "Address.findByPoboxnumber", query = "SELECT a FROM Address a WHERE a.poboxnumber = :poboxnumber"),
    @NamedQuery(name = "Address.findByPoboxtype", query = "SELECT a FROM Address a WHERE a.poboxtype = :poboxtype")}) 

public class Address implements Serializable {
    private static final long serialVersionUID = 1L;

Final assembly

From this list we will need findById (but not for Address, for Person first, as it’s in a top of Employee hierarchy). Now we have all necessary JPA elements to assemble them in JDeveloper, Employee class, starting from Person entity.

  

@PersistenceUnit(unitName="Employee")
   private EntityManagerFactory emf;   

     private EntityManager em;
     PersonDataType   Person;
     CompanyDataType  Company;
     ContractDataType Contract;
     PayrollDataType  Payroll;

After successful compilation new WAR deployment profile have been created, WAR file made and deployed on WLS as presented below. After careful WSDL verification new Entity-type web service is ready for testing and further – for replacing adapter-based version of MDMEmployeeService, implemented on BPEL, first part of this post.

Conclusion

We have tried several IDE in our search of optimal SOA SDP – JBoss Eclipse, NetBeans, JDeveloper. Probably the switching was too swift and ward to follow, but we managed to cover practically all essential parts of JPA implementation – annotations (all types), O-R mapping (on persistence.xml), named queries, EntityManager implementation. One important part – transactional control have been omitted for brevity, but it’s also managed through the annotations in EntityManager. At the end we have tried to assemble all bits in JDeveloper, build a .war file deploy it on WLS. Despite that, the Oracle JPA automation capabilities were least impressive, as all annotations and mappings were done in JBoss Developer Studio, naming Queries were constructed in NetBeans, and EntityManager (although mentioned in [2]) was taken from Geronimo example[3].

From this exercise is obvious that a lots of work has to be done manually, and that sparks again the question about the role of microservices in simplification of SOA implementation. By the way, speaking of implementation, we didn’t touch the other essential parts of the discussed solution, and probably it will be beneficial to reveal some aspects of EDN and message ingestion. We could discuss it in the next blogpost.

References

1. Oracle Docs: Developing with EJB and JPA Components
https://docs.oracle.com/cd/E16162_01/user.1112/e17455/dev_ejb_jpa.htm#OJDUG987

2. Java EE 6 Docs: Named Queries in JPA EJB 3.0 EntityManager
https://docs.oracle.com/javaee/6/tutorial/doc/bnbrg.html

3. Geronimo Tutorial: Developing bean managed persistence with JPA
http://geronimo.apache.org/GMOxDOC30/developing-bean-managed-persistence-with-jpa.html

4. Adam Bien’s WEBLOG
http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_for

 

Om bloggeren:
Sergey has a Master of Science degree in Engineering and is a Certified Trainer in SOA Architecture, Governance and Security. He has several publications in this field, including comprehensive practical guide “Applied SOA Patterns on the Oracle Platform”, Packt Publishing, 2014.

comments powered by Disqus