13 Replies Latest reply on Feb 8, 2008 3:21 PM by Nicklas Karlsson

    When to use @PersistenceContext vrs @In EntityManager (SMPC)

    Reind D Newbie

      I've been experiencing some problems since switching to seam 2 with

      org.hibernate.LazyInitializationException: could not initialize proxy - no Session


      Is my understanding correct:

      One should use a SMPC in Seam components that are *not* session beans.

      @In EntityManager entityManager

      For stateful session beans (that may or may not be seam components) one should use:

      @PersistenceContext(type=EXTENDED)
      EntityManager entityManager

      For stateless session beans (that may or may not be seam components) one should use:

      @PersistenceContext
      EntityManager entityManager

      The problem I'm experiencing is that I have a SFSB using an entityManager annotated with @PersistenceContext(type=EXTENDED). Some operations on entities produce the LazyInitializationException. If I switch to a Conversation Scoped Seam component, and start a long running conversation, then these exceptions go away.

      This class is just meant to be a SFSB (Session Scope) though, not Conversation scoped. Am I wrong in thinking that the PersistenceContext(type=EXTENDED) should stay around as long as the bean is alive, and thus not produce LIEs?

        • 1. Re: When to use @PersistenceContext vrs @In EntityManager (S
          Reind D Newbie

          I've also noticed that if I find an entity using a EJB PersistenceContext EM, then I get LazyInitializationExceptions when trying to fetch a property of that entity in another bean that uses the SMPC EM.

          The only way I've found around this is to re-fetch the entity using the current EM.

          This seams highly non-ideal. What's the proper approach in this case? If I don't want to start a long-running conversation in an SFSB then the only way to keep the em session going across multiple invocations is by using the EJB3 Extended PC, but then these entities are non-transferable to other seam components (where they'll produce LIEs).

          It seems one must use all Extended PC or all SMPC or refetch the entity with the current EM:

          entity = em.find(Foo.class, entity.getId());


          Or am I missing something?

          • 2. Re: When to use @PersistenceContext vrs @In EntityManager (S
            Eric H Novice

            Use SMPC for everything. Is there any reason not to?

            • 3. Re: When to use @PersistenceContext vrs @In EntityManager (S
              Kenneth Christensen Novice

              Use @PersistenceContext if you are using EJB3 and if you need a new transaction (@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) ) - Seam ref:


              If you are using EJB3 and mark your class or method @TransactionAttribute(REQUIRES_NEW) then the trans-
              action and persistence context shouldn't be propagated to method calls on this object. However as the Seam-
              managed persistence context is propagated to any component within the conversation, it will be propagated to
              methods marked REQUIRES_NEW. Therefore, if you mark a method REQUIRES_NEW then you should access the en-
              tity manager using @PersistenceContext.


              otherwise use SMPC.


              • 4. Re: When to use @PersistenceContext vrs @In EntityManager (S
                Kenneth Christensen Novice

                Rephrasing my last answer :-)

                If you need a new transaction and using EJB3 use @PersistenceContext - otherwise use SMPC for everyting else.

                • 5. Re: When to use @PersistenceContext vrs @In EntityManager (S
                  Reind D Newbie

                  I have a SFSB that is invoked in multiple requests without a clear Begin or End. It uses a SLSB to get a reference to an entity.

                  Here's an example from my project (note this worked in 1.2.1):

                  Foo is session scoped, so I expect its instance variables to stay around and managed. When I invoke a() the 'entity' ref is set. When I then invoke b(), entity is not-null and I can even get lazy loaded properties.

                  With Seam 1.2.1 this worked, now with 2.0 it no longer works. I'm not sure what's changed between versions that would cause this.

                  With 2.0. I get a NPE when trying to access 'entity' from a seperate request. I can get around this by creating a @Begin @Create public void init() {} method in Foo, but that's an ugly workaround.

                  The seam SMPC in a Session bean should be session scoped, and any entities that it retrieves should also be managed throughout the session, right?

                  @Name
                  @Scope(STATEFULL)
                  @Stateful
                  public class FooImpl implenents Foo {
                   @In
                   EntityManager entityManager;
                  
                   @In
                   Bar bar;
                  
                   private entity;
                  
                   // several methods that access 'entity' and access lazy loaded
                   // properties of entity
                   public void a() {
                   entity = bar.getEntity();
                   // do something
                   }
                  
                   public void b() {
                   entity.getProperty();
                   entity.getLazyProperty();
                   }
                  }
                  
                  @Name
                  @Stateless
                  public class BarImpl implenents Bar {
                   @In
                   EntityManager entityManager;
                  
                   public Entity getEntity() {
                   entityManager.find(Bar.class, ...);
                   }
                  }
                  


                  • 6. Re: When to use @PersistenceContext vrs @In EntityManager (S
                    Reind D Newbie

                    Sorry, I meant, ScopeType.SESSION instead of STATEFUL

                    @Name
                    @Scope(SESSION)
                    @Stateful
                    public class FooImpl implenents Foo {


                    Also, I understand that the SMPC is conversation scoped, but then what should I use in a Session scoped Session bean where there is no natural conversation Begin and End point? (and why has this behavior changed since 1.2 =-) ?)

                    • 7. Re: When to use @PersistenceContext vrs @In EntityManager (S
                      Joseph Nusairat Newbie

                       

                      "msystems" wrote:
                      Use @PersistenceContext if you are using EJB3 and if you need a new transaction (@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) ) - Seam ref:


                      If you are using EJB3 and mark your class or method @TransactionAttribute(REQUIRES_NEW) then the trans-
                      action and persistence context shouldn't be propagated to method calls on this object. However as the Seam-
                      managed persistence context is propagated to any component within the conversation, it will be propagated to
                      methods marked REQUIRES_NEW. Therefore, if you mark a method REQUIRES_NEW then you should access the en-
                      tity manager using @PersistenceContext.


                      otherwise use SMPC.


                      What you are saying at the top part is true.

                      However i don't believe the doco is saying use SMPC all the time.

                      Take a look at the first paragraph of the section. It basically refers to if you are using the component outside of a Java EE5 environment or if you have many loosly coupled components. Which as long as they are all SB the PersisetnceCOntext should transfer. However the doco is 100% right if you are going to have a mix of SB and POJOS .... then yeah doing the EntityManager injection is the only way to go.

                      So you can stick with the @PersistenceContext in most situations. Its going to be a situation where you are wanting to transact against non-EJB components you will want to use the @IN EntityManger.

                      Of course that being said i am not sure the harm it would cause using the @In EntityManager more often.

                      • 8. Re: When to use @PersistenceContext vrs @In EntityManager (S
                        Kenneth Christensen Novice

                         

                        "kasim" wrote:
                        "msystems" wrote:
                        Use @PersistenceContext if you are using EJB3 and if you need a new transaction (@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) ) - Seam ref:


                        If you are using EJB3 and mark your class or method @TransactionAttribute(REQUIRES_NEW) then the trans-
                        action and persistence context shouldn't be propagated to method calls on this object. However as the Seam-
                        managed persistence context is propagated to any component within the conversation, it will be propagated to
                        methods marked REQUIRES_NEW. Therefore, if you mark a method REQUIRES_NEW then you should access the en-
                        tity manager using @PersistenceContext.


                        otherwise use SMPC.


                        What you are saying at the top part is true.

                        However i don't believe the doco is saying use SMPC all the time.

                        Take a look at the first paragraph of the section. It basically refers to if you are using the component outside of a Java EE5 environment or if you have many loosly coupled components. Which as long as they are all SB the PersisetnceCOntext should transfer. However the doco is 100% right if you are going to have a mix of SB and POJOS .... then yeah doing the EntityManager injection is the only way to go.

                        So you can stick with the @PersistenceContext in most situations. Its going to be a situation where you are wanting to transact against non-EJB components you will want to use the @IN EntityManger.

                        Of course that being said i am not sure the harm it would cause using the @In EntityManager more often.


                        Of course you don't have to use SMPC if you don't want to use it !
                        But there is an advantage in using SMPC if you have a lot of conversations with loosly coupled components.

                        98% of the time I'm using a SMPC and the last 2% of the time I'm using a persistence context (@PersistenceContext) - of course together with Seam-managed transactions.



                        • 9. Re: When to use @PersistenceContext vrs @In EntityManager (S
                          Christian Bauer Master

                          Folks, it's quite simple:

                          - EJB 3.0 defines injection rules for EntityManager with @PersistenceContext

                          - For consistency reasons with the rest of the component model, they decided to make the _propagation_ rules (one component that has @PersistenceContext calling another component that also has @PersistenceContext) bound to transaction OR instantiation order propagation (SLSB vs. SFSB)

                          - These rules are straightforward (although I think our book is the only one that documents them properly) but complex

                          - Seam-managed and injected persistence contexts are an alternative with easier injection and propagation rules, not bound to transaction or instantiation order

                          So, unless you WANT PC propagation rules bound to transaction propagation (that's what the quoted paragraph from the docs is about), using a SMPC is fine in all situations.

                          • 10. Re: When to use @PersistenceContext vrs @In EntityManager (S
                            Joseph Nusairat Newbie


                            Christian ... i tried to find your book on amazon .... so i searched for your name and this showed up instead


                            http://www.amazon.com/Christian-Bauer-Loves-T-Shirt-XL/dp/B0011H0542/ref=sr_1_2?ie=UTF8&s=apparel&qid=1202413814&sr=8-2


                            ... looks around nervously ...

                            • 12. Re: When to use @PersistenceContext vrs @In EntityManager (S
                              Norman Richards Master

                              Christmas shopping is going to be easy this year!

                              • 13. Re: When to use @PersistenceContext vrs @In EntityManager (S
                                Nicklas Karlsson Master

                                What size do you think Rod Johnson is? ;-)