You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Caine Lai <ca...@gmail.com> on 2007/06/02 05:43:50 UTC

How does one use lazy loading in Struts 2 with container managed persistence?

I'm using EJB3 stateless session beans/JPA/JTA to manage my data access.
But I can't figure out how one would use lazy loading in this scenario since
any transaction opened in the EJB layer will already be committed prior to
rendering the view.

Any tips?

I'm familiar with "Open Session in View" when using hibernate, but it's not
quite the same when I'm using container managed transactions and dependency
injection in EJB3.  Or is it?  Would I still open a hibernate session within
the view and close it after the view is rendered in this scenario?

Thanks for any pointers.

Re: How does one use lazy loading in Struts 2 with container managed persistence?

Posted by Caine Lai <ca...@gmail.com>.
Thanks Jeromy,

This was exactly what I was looking for.  Very helpful.

I was able to create a transaction in the web tier using a JNDI lookup of
the UserTransaction.  The transaction spans the entire request as needed.

It still troubles me that any problems with the transaction commit will not
be catchable since the response will have already been committed by the time
the transaction is committed.  JBoss Seam looks like it is the only
framework that has solved this problem, but I'm not at all interested in
using JSF.

Does anyone know if the same implementation can be built into a Struts
interceptor?

Thanks,
Caine

On 6/4/07, Jeromy Evans <jeromy.evans@blueskyminds.com.au > wrote:
>
> 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: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

Re: How does one use lazy loading in Struts 2 with container managed persistence?

Posted by Jeromy Evans <je...@blueskyminds.com.au>.
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: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: How does one use lazy loading in Struts 2 with container managed persistence?

Posted by Caine Lai <ca...@gmail.com>.
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

On 6/2/07, Jeromy Evans <je...@blueskyminds.com.au> wrote:
>
> Hi Caine,
>
> I use JPA. I place the EntityManagerFactory into the application context
> so it can be accessed by an S2 interceptor.
> The S2 interceptor creates an EntityManager for each request as per the
> open session in view pattern and so lazy loading can be used where
> appropriate.
> This doesn't qualify as CPM though which is what you asked for. I
> haven't tried using S2 with an EJB container yet.
>
> There's no need to use spring.
>
> cheers,
> Jeromy Evans
>
> Caine Lai wrote:
> > No one?  This seems like a major design flaw in Struts 2, if there is
> > no way
> > to use lazy loading in Struts 2 using JPA.
> >
> > I've read something online that describes it may be possible to write a
> > custom interceptor that can scan for annotations and inject the
> > persistence
> > context into a struts action.  But without framework support for JPA
> > (built
> > in), how can Struts 2 ever be taken seriously?  Isn't EJB3 and JPA the
> > current standard spec?
> >
> > I'm not at all interested in using Spring either.  And quite fankly I
> > shouldn't be forced to use Spring purely for the Open Session in View
> > pattern.
> >
> > Thoughts?
> >
> > On 6/1/07, Caine Lai <ca...@gmail.com> wrote:
> >>
> >> I'm using EJB3 stateless session beans/JPA/JTA to manage my data
> access.
> >> But I can't figure out how one would use lazy loading in this
> >> scenario since
> >> any transaction opened in the EJB layer will already be committed
> >> prior to
> >> rendering the view.
> >>
> >> Any tips?
> >>
> >> I'm familiar with "Open Session in View" when using hibernate, but it's
> >> not quite the same when I'm using container managed transactions and
> >> dependency injection in EJB3.  Or is it?  Would I still open a
> hibernate
> >> session within the view and close it after the view is rendered in this
> >> scenario?
> >>
> >> Thanks for any pointers.
> >>
> >
> > ------------------------------------------------------------------------
> >
> > No virus found in this incoming message.
> > Checked by AVG Free Edition.
> > Version: 7.5.472 / Virus Database: 269.8.7 - Release Date: 2/06/2007
> 12:00 AM
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

Re: How does one use lazy loading in Struts 2 with container managed persistence?

Posted by Jeromy Evans <je...@blueskyminds.com.au>.
Hi Caine,

I use JPA. I place the EntityManagerFactory into the application context 
so it can be accessed by an S2 interceptor.
The S2 interceptor creates an EntityManager for each request as per the 
open session in view pattern and so lazy loading can be used where 
appropriate.
This doesn't qualify as CPM though which is what you asked for. I 
haven't tried using S2 with an EJB container yet.

There's no need to use spring.

cheers,
Jeromy Evans

Caine Lai wrote:
> No one?  This seems like a major design flaw in Struts 2, if there is 
> no way
> to use lazy loading in Struts 2 using JPA.
>
> I've read something online that describes it may be possible to write a
> custom interceptor that can scan for annotations and inject the 
> persistence
> context into a struts action.  But without framework support for JPA 
> (built
> in), how can Struts 2 ever be taken seriously?  Isn't EJB3 and JPA the
> current standard spec?
>
> I'm not at all interested in using Spring either.  And quite fankly I
> shouldn't be forced to use Spring purely for the Open Session in View
> pattern.
>
> Thoughts?
>
> On 6/1/07, Caine Lai <ca...@gmail.com> wrote:
>>
>> I'm using EJB3 stateless session beans/JPA/JTA to manage my data access.
>> But I can't figure out how one would use lazy loading in this 
>> scenario since
>> any transaction opened in the EJB layer will already be committed 
>> prior to
>> rendering the view.
>>
>> Any tips?
>>
>> I'm familiar with "Open Session in View" when using hibernate, but it's
>> not quite the same when I'm using container managed transactions and
>> dependency injection in EJB3.  Or is it?  Would I still open a hibernate
>> session within the view and close it after the view is rendered in this
>> scenario?
>>
>> Thanks for any pointers.
>>
>
> ------------------------------------------------------------------------
>
> No virus found in this incoming message.
> Checked by AVG Free Edition. 
> Version: 7.5.472 / Virus Database: 269.8.7 - Release Date: 2/06/2007 12:00 AM
>   


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: How does one use lazy loading in Struts 2 with container managed persistence?

Posted by Al Sutton <al...@al-and-andrea.org.uk>.
I'd also add that Struts2 can be taken seriously because a large number 
of webapps are deployed to servlet engines that don't support EJBs such 
as Tomcat and Jetty and don't get deployed to full J2EE containers.

Therefore requiring EJB support would most likley make Struts2 less 
likely to be adopted, not more so.

Al.

Dave Newton wrote:
> --- Caine Lai <ca...@gmail.com> wrote:
>   
>> But without framework support for JPA (built in),
>>     
> how
>   
>> can Struts 2 ever be taken seriously? Isn't EJB3 and
>>     
>
>   
>> JPA the current standard spec?
>>     
>
> What would "built-in support" for JPA and EJB3 look
> like? 
>
> Seems to me that Hibernate is the current ad-hoc
> standard, and it's where both JPA and EJB3 got quite a
> bit of their inspiration from. There's no built-in
> support for Hibernate (or iBatis, or...) either, but
> I'd guess a fair number of S2 users are using Spring
> for DI and end up using it for a bunch of persistence
> stuff, too.
>
> Persistence layers are probably one of the most wildly
> variable things from project to project. I'm not sure
> why you are opposed to putting this code in an
> interceptor; that's a pretty versatile solution.
>
> d.
>
>
>
>       ____________________________________________________________________________________
> Park yourself in front of a world of choices in alternative vehicles. Visit the Yahoo! Auto Green Center.
> http://autos.yahoo.com/green_center/ 
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>   

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: How does one use lazy loading in Struts 2 with container managed persistence?

Posted by Dave Newton <ne...@yahoo.com>.
--- Caine Lai <ca...@gmail.com> wrote:
> But without framework support for JPA (built in),
how
> can Struts 2 ever be taken seriously? Isn't EJB3 and

> JPA the current standard spec?

What would "built-in support" for JPA and EJB3 look
like? 

Seems to me that Hibernate is the current ad-hoc
standard, and it's where both JPA and EJB3 got quite a
bit of their inspiration from. There's no built-in
support for Hibernate (or iBatis, or...) either, but
I'd guess a fair number of S2 users are using Spring
for DI and end up using it for a bunch of persistence
stuff, too.

Persistence layers are probably one of the most wildly
variable things from project to project. I'm not sure
why you are opposed to putting this code in an
interceptor; that's a pretty versatile solution.

d.



      ____________________________________________________________________________________
Park yourself in front of a world of choices in alternative vehicles. Visit the Yahoo! Auto Green Center.
http://autos.yahoo.com/green_center/ 

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: How does one use lazy loading in Struts 2 with container managed persistence?

Posted by Caine Lai <ca...@gmail.com>.
No one?  This seems like a major design flaw in Struts 2, if there is no way
to use lazy loading in Struts 2 using JPA.

I've read something online that describes it may be possible to write a
custom interceptor that can scan for annotations and inject the persistence
context into a struts action.  But without framework support for JPA (built
in), how can Struts 2 ever be taken seriously?  Isn't EJB3 and JPA the
current standard spec?

I'm not at all interested in using Spring either.  And quite fankly I
shouldn't be forced to use Spring purely for the Open Session in View
pattern.

Thoughts?

On 6/1/07, Caine Lai <ca...@gmail.com> wrote:
>
> I'm using EJB3 stateless session beans/JPA/JTA to manage my data access.
> But I can't figure out how one would use lazy loading in this scenario since
> any transaction opened in the EJB layer will already be committed prior to
> rendering the view.
>
> Any tips?
>
> I'm familiar with "Open Session in View" when using hibernate, but it's
> not quite the same when I'm using container managed transactions and
> dependency injection in EJB3.  Or is it?  Would I still open a hibernate
> session within the view and close it after the view is rendered in this
> scenario?
>
> Thanks for any pointers.
>