To investigate this further I created an S2 webapp deployed within a JBoss 4.2.0 container using EJB3 stateless session beans and JPA entity beans.

First of all though, if you use JPA in standalone mode you can use the open session in view pattern as discussed in prior emails. This question relates to container managed persistence where you don't have the same luxury of creating your own EntityManagerFactory within the webapp.

My short answer is: though is that Struts2 does not introduce any new limitations. You can use struts2 within an EJB3 container with CMP and lazy loading within the JSP the same way you do with with any other webapp within an EJB3 container. You have to lookup the PersitanceUnit in an interceptor as described at [1].

My long answer:

Test scenario;
I created an S2 action that looks up an a remote session bean to find a list of books. The session been performs a simple EJB-QL query ("select book from Book book") Each Book is an Entity with a @OneToMany relatinoship to a BookAuthorMap which in turn has a @ManyToOne to an Author. ie. effectively a many-to-many relationship directed from book to author to provide a genuine lazy-loading opportunity.
My action has a property List<Book> getBooks()
My JSP result displays the list of books found, with an inner iterator to display the list of authors mapped to each book. Effectively, each inner iteration causes a lazy load of the referenced map and Author if the entity's not already cached by the EntityManager. Simple enough?

Here's my summary:
a. as you'd expected, you can't use EJB3 DI within your S2 actions (@PersistenceContext, @Resource, @EJB) However, you can use JNDI so there's no reason why these can't be supported via an explict S2 plugin or interceptor.
Easy options are:
  - write a custom annotation and interceptor as discussed at [2]
  - use a Guice object factory with a JNDI provider to inject
  - use a Spring object factory to do the same thing
- write a Struts2 EJB3 plugin to recognise @PersistenceContxt, @Resource @EJB in actions and inject them (my action simply created an InitialContext and looked up the EJB session bean0

b. As you would expect, the container determines that the transaction is over when the ejb call ends and the entities become detached from the EntityManager So lazy loading is not available in the action (or JSP), but this was when it occurred to me that this is in no way related to struts2 - it's the same problem that exists in stand-alone JPA, and the same problem exists for plain JSP, or plain servlets, struts1 and pretty much anything else in an EJB container (except perhaps JSF backed by managed beans, which I don't know anything about).

So the question is not whether struts2 has a limitation - it doesn't. The question should be how you can extend the transaction down into the web-tier in an EJB environment.

And the answer is simply to use JDNI to lookup the PersistenceUnit in an interceptor or filter - the same as you do for stand-alone mode except using a lookup. I haven't tried yet, but its described at [1].

Hope that helps,
Jeromy Evans


References:
1. http://weblogs.java.net/blog/ss141213/archive/2005/12/dont_use_persis_1.html 2. http://www.nabble.com/Re:--s2--Struts-Dependency-Injection-and-EJB3---support---or-how-can-i-Do-it--p8512920.html


Caine Lai wrote:
Hi Jeromy,

Thanks for your response.  It sounds like your solution works, but it
doesn't seem like this would integrate with container managed persistence
very well.

It's strange this is so difficult to achieve in the "next generation"
struts. I don't know why JPA/EJB3 is an afterthought. I really don't want
to abandon Struts 2 at this point since it was exactly what I was looking
for except for this one very large issue.

I'd still be very interested in hearing from anyone that has thought about
or solved this problem of using Struts 2 in a managed environment.

Thanks,
Caine


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to