cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with Web Dynpro EJB Models

Former Member
0 Kudos

Hi Experts,

I am having problems with Web Dynpro EJB Models when created from CAF Application Services. I have created a CAF entity service, called 'Customer', and a CAF application service, called 'CustomerApp'. When creating the EJB model in my Web Dynpro DC, on the screen where I am supposed to select the 'Enterprise Beans and interfaces', I have duplicates of both the Customer bean and CustomerApp bean. Another problem is that the Customer bean has two methods named 'lock' and two methods named 'unlock' (which I did not create). I can only create the model if I go and manually unselect one 'lock' and one 'unlock' method.

Also, I'm unable to get my model to work in my Web Dynpro application. I followed the tutorial on <a href="http://help.sap.com/saphelp_nwce10/helpdata/en/45/f7f744aea471fae10000000a1553f6/frameset.htm">EJB3 Web Dynpro Integration</a>, however, I'm unsure of how to access individual elements when your service returns a collection instead of a single entity? Also, what if your service requires input parameters? Whenever I try and add them directly to the modelObject I receive a nullpointer exception.

In 7.0 we could call and assign Application Services to Model objects directly in the code. Is this still possible or do all service calls need to occur through a model node in the web dynpro context?

Accepted Solutions (0)

Answers (1)

Answers (1)

0 Kudos

Hi there,

Having each bean listed twise is a known issue which will be fixed in the next version. However, you can select any of them and then it works fine.

Each business object (BO) in CAF comes with some methods directly from CAF. Such are lock() and unlock(). It makes sense not to select them if you do no plan to use them.

Regarding the collections support - there are no major limitations there, so I would expect that it works fine. Accessing the elements coming from a collection is pure Web Dynpro specific (means does not differ for different CMI models). The most typical example would be to bound the Response model class to a Table WD component.

You do not need to add any elements manually. Two steps are needed in order to have your Request model objects (which are bound to the WD context) automatically created:

- register a model instance in WD Runtime during wdDoInit() method

- make all the Request model classes mandatory for the context (i.e. set Collection Cardinality 1..1).

Both steps are well described in the documentation.


com.sap.tc.cm.ejb.example.model.MyStudsModel myModel = 
    new com.sap.tc.cm.ejb.example.model.MyStudsModel();
wdComponentAPI.getModelInstanceMap().putDefaultInstance
    ("com.sap.tc.cm.ejb.example.model.MyStudsModel", myModel); 

Consuming CAF services (or pure EJBs) through the EJB CMI Model is much easier and intuitive. Besides it really reduces the manual coding. So keep on digging, I'm sure you'll be pleased with the final result.

What is the version of the engine you use?

EJB CMI Model in the version uploaded on SDN does not have CAF support officially. It was intended for consuming EJBs in Web Dynpro applications. Since CAF services are actually EJBs, it is possible to import them via EJB CMI Model. There are some limitations though - at least modifiedAt and createdAt BO properties are not supported as well as some other CAF-specific types. In the next version planned to be released in few months, full CAF support will be provided.

In order to continue investigations, please post the signatures of the EJB methods you want to consume in Web Dynpro.

Hope this helps.

Best regards,

Vesselin

Former Member
0 Kudos

Hi Vesselin,

Thanks for the thorough answer, however, there is still one or two things I'm unsure of. Let me rephrase parts of my question.

I managed to get the collections node to work when binding it to a Table component, so the nullpointer exception is no more. However, I'm still unsure how to interact with application services without going through the context. Is this possible? For example, let's say I have a getAll method on Customers that takes no parameters but returns a collection of Customers. Instead of binding this to a Table, I'd like to loop over all Customers and append their names to a String which I'll display in a TextView. Is this possible inside Web Dynpro on the model?

I know that I can (and should rather) do this inside the Application Service itself, but I'm sure I'll run into a similiar situation in the future where I need to do some "display" processing inside the Web Dynpro application, and I'd like to know how to do it? If I could perhaps give an example of more or less how it would have worked in 7.0, then perhaps you can give me the equivalent 7.1 code (excuse the syntax errors, I'm doing this from memory):


String names = new String();
java.util.List customerList = CustomerAppServiceProxy.getAll();
java.util.Iterator customerIterator = customerList.iterator();
while (customerIterator.hasNext())
{
  names += ((ACustomer)customerIterator.next()).getName();
}

Regarding your question of what engine version I'm using - I'm not sure? How can I check? I'm working on 7.1 SP3 if that is of any help?

Thanks for your time and answer,

JP

0 Kudos

Hi JP,

Yes, that was what I needed to know - 7.1 SP3 is the latest release.

Here is how you can append the names of the returned customers.

Let's say you have the method getAll() in the application service. The generated model classes are:

Request_beanName_getAll

Response_beanName_getAll

and of course Customer

I guess you can go without binding to the context, but this would be the harder approach. If you bind the Request model class to the context (with Collection Cardinality 1..1), then when you need to concat the names, do the following (e.g. in wdDoInit method):

// invoke application service's getAll() method

wdContext.currentRequest_beanName_getAll.modelObject().execute();

Then all the names are in the WD context under:

|-- Request_beanName_getAll

 |-- Response_beanName_getAll

  |-- return (of type Customer, Cardinality MANY)

   |--

name (String)

you just need to iterate all the customers from the context and concat their names.

This approach is almost the same as before but you do not need to lookup the EJB and manually invoke its method. Request.execute() does all the work and also updates the corresponding Response.

You can directly access the Response via

wdContext.currentResponse_beanName_getAll()

.

Then

response.modelObject().getReturn()

will return all Customers.

Let me know what the result is.

Btw, you have obviosuly some previous experience with consuming EJBs in Web Dynpro and probably that's why starting with quite a different approach is a bit overhead for you. I guess the difficulties should be only at the beginning - once you get familiar with it, its usage is much easier and intuitive.

Cheers,

Vesselin

Former Member
0 Kudos

Hi Vesselin,

Thanks for the quick reply.

Things are starting to make sense, and like you said, I guess a lot of my confusion stems from the differences from straight-forward EJB programming. I managed to get the code working like in the way you suggested and also independently of the context by instantiating the <i>Request_beanName_getAll

</i> class myself.

Just to make sure that I understand correctly: let's say I want to use the generated lock and unlock methods of the services. That would mean that I first have to generate models for them and then either use them through the context or by instantiating them myself, correct?

Thanks a lot,

JP

0 Kudos

Hi JP,

Yes exactly. You can either create a new ejb model or just re-import an existing one. Re-import means that the model is updated based on a new method selection. Please note that you should also select all the previous methods plus lock() and unlock().

Great it finally works! Let us know in case of any further concerns.

Cheers,

Vesselin

Former Member
0 Kudos

Thanks a lot, will do