Thursday, August 9, 2012

Generating an EJB SDO Service Interface for Oracle SOA Suite

In Oracle SOA Suite you can use the EJB adapter as a reference or service in your composite applications. The EJB adapter has a flexible binding integration, there are 3 ways for integrating the remote interface with your composite.

First you have the java interface way which I described here this follows the JAX-WS way. It means you need to use Calendar for your Java date types and leads to one big WSDL when you add a wire to a service component.

Second way is EclipseLink Moxy this solution is great when you can't change your java interfaces. Antony Reynolds made a great blogpost how to use EclipseLink moxy in Oracle Soa Suite.

The last way is generating a Service Data Object (SDO) service interface on your EJB Session Bean, This leads to a WSDL with a operation XSD and entity XSDs which can be used / read by the EJB Adapter ( no one big WSDL ).  Use the java data types you want to use, JDeveloper can re-generate the SDO interface and no need to drag a dummy wire to refresh the EJB WSDL when you change the EJB Session bean.

In 2009 I already described this SDO feature but now with Patch Set 5 this SDO feature is finally working well. Before PS5 it was really hopeless.

So let's explain how this works in PS5. I already made a simple HR JPA Model project with a EJB Session Bean.


Before we start we need to think about lazy and eager object loading. In this Department entity I will eager retrieve the manager and employees of this department.


In the Employee entity I will use the Lazy fetch type on the department attribute.


Just like the java interface mapping way we can't have circular references between department and employees XSD.  We need to break the loop so add @XmlTransient to the getter of the department attribute of the employee entity.  ( now the department element will be skipped in the employee XSD )


Select your EJB Session Bean ( Right Click ) and select Create Service Interface.


When we want to use this SDO interface in Oracle SOA Suite we need to enable the Configure as an ADF-BC Service. This will add the necessary SDO annotations on the Remote Interface.



With this as result


The generated Department entity XSD.


The EJB SDO Session Bean WDSL

JDeveloper adds PortableWebService annotation to the EJB Session bean.


The remote interface with all the web annotations on a SDO method.



Also when you want the same behaviour as a Database adapter you can force to start a new transaction and not take part in the BPEL transaction. This way you can see if the transaction is successful at the end of the invoke instead of the end of BPEL.


JDeveloper also adds code to the EJB Session Bean to marshall and unmarshall the java or xml.


Think about which attributes can be empty else you will get some null pointer exceptions.


Also it will load all the SDO XSDs in the EJB Session Bean. If you don't have circular XSD references  then loading should be successful.


In a java client we can test the SDO interface ( this will not use the remote interface annotations) by first loading the XSDs and invoking a SDO session bean method. Loading of the XSDs is necessary else   you will get some EclipseLink objects instead of the department of employee objects.


Deploy the EJB to the SOA Suite Server and also generate an interface jar which does not contain the meta-inf folder  and the Bean.

Now is the time to configure the EJB adapter in Oracle SOA Suite. Drag the EJB Adapter to the reference side of the composite.

Lookup the jar and the WSDL. The wizard will copy the interface jar and WSDL, XSDs to your project.


Fix the jndiName bug in the reference service, go to source mode of the composite.xml , rename the uri attribute to jndiName.



Finish your composite and deploy it. When you go for a test drive you will see something like this.


Here you can download my example project.
https://github.com/biemond/soa11g_examples/tree/master/SoaEjbSdoReference


14 comments:

  1. Hi The post is nice . I have been working on SDO related stuff for some time, based on the example you have shown I have a query : When we use ADF bc as the basis for generating SDO we can have lot of custom methods at Application Module layer that can be exposed as part of SDO.

    Can we do similar stuff using EJB based entities and SDO ? For example a custom method accepting List and returning Rowset


    Thanks ,
    Sam

    ReplyDelete
    Replies
    1. Hi
      Everything is possible in the ejb session bean, just keep it serialazible.

      Delete
  2. Hi Edwin,

    Nice post :) We are actually considering moving from the ADF-BC SDO implementation towards this one. Now I'm just wondering how I can expose this HrSessionEJB also through SOAP as it is automatically the case when using the ADF-BC alternative. When I now deploy the EjbSdoService, it's only accessible through EJB (even though there are webservice annotations present), so how do I enable it to accept SOAP also?

    Thanks,
    David

    ReplyDelete
    Replies
    1. Hi,

      for a web service you probably should add the webservice annotation ( with all the parameters ) and this creates a war with a servlet define in the web.xml and maybe you need to put the wsdl and the xsd in the web-inf/wsdl folder.

      I will check this out and we can take a look how adf bc does this ( must be almost the same )

      thanks

      Delete
    2. Hi,

      I figured it out with running an serviceimpl of adf bc sdo service on the embedded weblogic service.

      First don't add WebService annotation to the bean or remote interface.

      What Oracle JDeveloper does on deployment is

      makes a war with only a WEB-INF folder.
      in this folder there is a wsdl folder with the all the wsdl, xsd's folder structure of the model project.
      adds off course a web.xml with a servlet to the bean
      it also generates a standard-webservices.xml and oracle-webservices.xml file with all the ws references.

      will try to make a war project example and maybe with ant we can automate this process.

      thanks

      Delete
    3. Thanks Edwin for the explanation, looking forward for the example.

      David

      Delete
    4. Hi Edwin,

      I made a post in which I explain how to expose this EJB/JPA based SDO through SOAP:

      http://dablomatique.wordpress.com/2012/08/30/exposing-an-ejb-sdo-service-interface-as-a-soap-webservice-on-weblogic-11-1-1-6/

      The complete modified ModelSDO project is also available on Github:

      https://github.com/dabla/ejb-sdo-service

      Thanks,
      David

      Delete
    5. Hi,

      great work and thanks for sharing, Curious if adf bc entities and bpel entity variable can work with this sdo web services.

      thanks

      Delete
  3. Hi,

    I hope you can help me on this issue.
    I followed your instructions but there was one step that was not successful.
    When I tried creating Service Interface by right-clicking on the Session Bean and select from the context menu, the SDO files and objects (xml, xsd, wsdl, java) were not created as in your tutorial.

    I managed to overcome this issue several weeks ago by adding an extension called SOA Composite Editor into Weblogic, but currently after even with this extension the SOA objects are not created anymore.

    Thanks in advance.
    Clark,

    ReplyDelete
    Replies
    1. Sorry, forgot to mention that I'm using JDev 11.1.1.6

      Delete
    2. And I mean adding the extension to JDev, not Weblogic

      Delete
    3. Hi,

      Strange, I use indeed the soa extension in jdeveloper ( full edition ) but I did not have this problem. can you test the EJB first and see if this works and then try to generate a service interface.

      thanks

      Delete
    4. Hi Edwin,

      I tried and the EJB worked fine. I have followed your tutorial and created many applications with the same code, but the generation of the SDO objects are very unpredictable, in some applications they are created and in the others they are not.

      I am trying to figure out what are the factors that affect the generation process but so far no success. I am suspecting some info in some configuration xml files is missing, or some library jars are not added.

      Would appreciate if you have any info to share.

      Thanks.

      Delete