13 Replies Latest reply on Dec 11, 2006 5:12 PM by Pete Muir

    How many EntityManagers and SFSBs in a web app?

    None None Master

      Every object that is managed by Seam is associated with an EntityManager. A SFSB gets its EntityManager by doing an injection of a @PersistenceContext. Normally that PersistenceContext must be of an Extended type, so that lazy-fetched objects can be rendered without the dreaded LazyInitializationException.

      Now here is the problem. If I have multiple SFSBs in the same scope (Session), they will each end up with their own EntityManager. Big problems happen when one SFSB tries to deal with an injected bean while that bean is currently being managed by some other EntityManager.

      What do I do? It is looking to me like I should only have ONE EntityManager for each Scope. That means one SFSB per scope. That seems a bit limiting, or is this really the way to do things?

        • 1. Re: How many EntityManagers and SFSBs in a web app?
          Pete Muir Master

          Seam Managed Persistence Context solves thing for Conversation scope. For SESSION and APPLICATION scopes either eager fetch what you need or create a manager that reloads entities when they become detached (this is somewhere in the forum archive).

          • 2. Re: How many EntityManagers and SFSBs in a web app?
            None None Master

            Thanks for the info on that. I didn't realize. Hmm. I guess I could take away all these collections that I'm using, and instead use beans to do queries. Eager fetching is out of the question because there might be thousands of entities in certain collections, each with its own entities.

            This is frustrating. I would really like to just have an EntityManager that I can use and not worry about this stuff. I'll look for that thread.

            • 3. Re: How many EntityManagers and SFSBs in a web app?
              None None Master

              To put it another way, when the View needs to render something, it is very likely that the objects in the View will need access to an EntityManager. Hibernate had no solution for this; the best you could do would be to use a Filter to handle the EntityManager, but that is really not ideal because it's ugly and in some cases the Filter doesn't get to complete its task. So that's bad. I switched to Seam because I thought that Seam finally solved the "EntityManager in the View phase" problem, but apparently it does not.

              Why is this so hard? Come on, even PHP has a solution to this. In PHP at the beginning of your request, you get a DB connection, and then everywhere else in the request you just do mysql_query(...), and it all works, and at the end of the request, the DB connection is freed. Why is Java having such a hard time doing that? I notice that I can access the FacesMessages from any object and the FacesMessages is retrieved from the Thread itself. Why can't an EntityManager run the same way?

              Am I the only one who can see that this is a fundamental oversight in the entire Java ORM Web landscape?

              • 4. Re: How many EntityManagers and SFSBs in a web app?
                Gavin King Master

                What the hell are you ranting on about?

                • 5. Re: How many EntityManagers and SFSBs in a web app?
                  None None Master

                  I'm not ranting. I'm just trying to figure out how to handle EntityManagers in my application.

                  Put it another way:

                  This is a typical web application. Users log in and then do stuff. This being a Java application, all the stuff they work on are objects.

                  JSF and Seam give me excellent ways to display and edit those objects. EJB3 gives me an excellent way to store those objects without having to write any SQL. That's great.

                  The problem is, how do I avoid LazyInitializationExceptions when my objects have collections in them? Obvious answer: use eager fetching. But for situations where that is not practical, the thing to do is to have an EntityManager available while the page is being rendered.

                  What I have done is used Session-scoped SFSBs with extended persistence context. That sort of works but seems like a bad thing. What's the right way to handle this? It seems like such an obvious thing, so there must be some clean way to handle it, right?

                  • 6. Re: How many EntityManagers and SFSBs in a web app?
                    Pete Muir Master

                    You really seem to have missed the point.

                    If you use a Seam Managed Persistence Context (RTM) then it solves the LIE situation for conversations (which can be used 99% of the time you used to use the session scope).

                    I suspect the problem is that you are using session scoping when you needn't. I think it is fair to say that you should, in most normal apps, only need to store one entity in the session scope - the logged in user - and I've never had to place any in the application context.

                    The problem is, how do I avoid LazyInitializationExceptions when my objects have collections in them? Obvious answer: use eager fetching. But for situations where that is not practical, the thing to do is to have an EntityManager available while the page is being rendered.


                    No. The obvious answer is to use a conversation and a conversation scope entity manager (which Seam does for you) (and certainly provides the same entity manager whilst the page is rendered.


                    I can access the FacesMessages from any object and the FacesMessages is retrieved from the Thread itself.


                    Thats because FacesMessages is conversation scoped. An EXTENDED persistence context isn't, an SMPC is.

                    petemuir wrote:
                    For SESSION and APPLICATION scopes either eager fetch what you need or create a manager that reloads entities when they become detached (this is somewhere in the forum archive).


                    I forgot I wrote this up:

                    http://wiki.jboss.org/wiki/Wiki.jsp?page=SeamEntityHomeForLongRunningContexts

                    • 7. Re: How many EntityManagers and SFSBs in a web app?
                      Gavin King Master

                      As Pete says, this is solved once you start using conversations and Seam-managed persistence contexts.

                      It actually *is* possible to have a session-scoped Seam-managed persistence context, but we don't recommend it because it can be a memory leak unless you *really* know what you are doing, and you have a *really* good usecase for it. Your usecase (ie. "I'm not using conversations, because Tomahawk is broken", according to the other thread) definitely does not count as "good".

                      As for PHP solving the problem, that's just absurd. There is no such thing as lazy fetching or a persistence context in PHP. If you are looking for help in the forum, yelling totally stupid things like this is not the right way to go about it. OK?

                      • 8. Re: How many EntityManagers and SFSBs in a web app?
                        None None Master

                        Gavin, I'm not trying to yell stupid things. PHP is clearly a stupid thing. It doesn't suffer LIEs because it's so primitive it doesn't have any abstraction for access to the DB at all. No (real) objects to initialize means no initialization errors, and applications which are messes of procedural code and no separation of view and logic. It does have a very simple and effective way of managing DB connections, but it's incapable of going to the next generation of web services, which is what Seam is for.

                        Not using conversation scope is obvoiusly where I'm messing myself up. I didn't understand this. I need to either figure out if Tomahawk can work with Seam and maintain conversation, or just ditch Tomahawk, as cool as some of the Tomahawk stuff is.

                        . I think it is fair to say that you should, in most normal apps, only need to store one entity in the session scope - the logged in user - and I've never had to place any in the application context.


                        Ok, that's a useful bit of info.

                        As for SMPC in Conversation scope: So I should change my SFSBs to be conversation-scoped (as you're saying). I should also remove the EXTENDED PersistenceContext parameter? If my SFSB is Conversation scope, I just don't have to worry about it?

                        As a corollary, if I do all that, and test it with a Tomahawk component, and it breaks, well, I just take out the Tomahawk stuff until they come out with a version that works with Seam.

                        Is this the right track?


                        • 9. Re: How many EntityManagers and SFSBs in a web app?
                          Pete Muir Master

                          So, Tomahawk works with Seam conversations (try using an up-to-date version i.e. 1.1.3, also n.b. Tomahawk 1.1.0 would have to have been Myfaces 1.1.0 as old versions had to have exactly the same version no, perhaps thats where you were going wrong?). It's just that Tomahawk is written in a strange way in places which means that some of the components don't work. You would be far better off using a Gavin-recommended component set (e.g. Trinidad or Icefaces), not least because you'll get more help here.

                          @Stateful Seam components are SESSION scoped by default. You shouldn't just remove the EXTENDED parameter, you should use an SMPC - http://docs.jboss.com/seam/1.1CR2/reference/en/html/configuration.html#d0e6294

                          You would definitely be better off changing your component set to work with Seam, not the other way around.

                          I think it is worth pointing out that you could of course do PHP style DB access in Java using plain JDBC - but that would obviously mean no ORM etc.

                          • 10. Re: How many EntityManagers and SFSBs in a web app?
                            None None Master

                             

                            "petemuir" wrote:
                            So, Tomahawk works with Seam conversations (try using an up-to-date version i.e. 1.1.3, also n.b. Tomahawk 1.1.0 would have to have been Myfaces 1.1.0 as old versions had to have exactly the same version no, perhaps thats where you were going wrong?). It's just that Tomahawk is written in a strange way in places which means that some of the components don't work. You would be far better off using a Gavin-recommended component set (e.g. Trinidad or Icefaces), not least because you'll get more help here.


                            I'm tripping out all the Tomahawk; there are only a dozen pages so far so that's not a big deal. Gavin has made it pretty clear, Tomahawk and Seam are like oil and water. I'm not going to try to fight that. Icefaces looks so cool I would rather use that. But I'm going to be sane and just get my plain old application working correctly first, and THEN I will try adding some Icefaces stuff.

                            "petemuir" wrote:
                            @Stateful Seam components are SESSION scoped by default. You shouldn't just remove the EXTENDED parameter, you should use an SMPC - http://docs.jboss.com/seam/1.1CR2/reference/en/html/configuration.html#d0e6294


                            Ok, now THAT was the other thing I was missing. I didn't know about configuring the SMPC and that resulted in everything else going to hell. I'm configuring that now. I notice in that doc that it clearly explains why SMPC should make LIEs be a thing of the past, which is why I started with Seam from the beginning.

                            You would definitely be better off changing your component set to work with Seam, not the other way around.


                            Yes, definitely, especially because at this stage it's not much trouble for me to do that.

                            I think it is worth pointing out that you could of course do PHP style DB access in Java using plain JDBC - but that would obviously mean no ORM etc.


                            Oh certainly, there are plenty of web apps out there that use JSP pages with code and direct JDBC calls all throughout the page, just like with PHP, and it's equally as horrible as PHP. My goal is to get to a real object-oriented application approach. That could mean several different things, including ugly anti-patterns like using DTOs. What I really want is to bind my object all the way through to web forms using minimal glue and DTO-type code. It looks like Seam is supposed to do that if I can figure it out... SMPC and getting rid of Tomahawk and using conversations are the first steps.


                            • 11. Re: How many EntityManagers and SFSBs in a web app?
                              None None Master

                              Ok, more info:

                              From: http://docs.jboss.com/seam/latest/reference/en/html/configuration.html section 9.4:

                              Hibernate users developed the open session in view pattern to work around this problem (managing DB connections). This pattern is usually implemented as a transaction which spans the entire request.


                              That's exactly the PHP solution.

                              There are several problems with this idea, the most serious being that we can't be sure that a transaction has been successful until we commit it, but by the time we commit the transaction, we have already rendered the view.


                              Which is a serious problem and makes web apps look like crap because it will display "your credit card has been charged" on the top of the page and then a "database transaction failed" message below that, leaving the user thinking, "this site is a joke."

                              Furthermore, this is at best a partial solution to the problem, because we can still meet the dreaded LazyInitializationException if we try to re-use the entity object in the next request.


                              Which is the most serious problem. PHP solves it by not having any objects which survive beyond a single request, meaning that their apps will never scale without hacks to solve that problem. PHP hacks are either clusters with object caching hacks, or cumbersome database clusters to take out the problem of database scalability. Java wins by having real objects able to stay in memory on the server between requests, but that creates the problem of detached objects, which it sounds like Seam solves with its conversation context and SMPC, which is what I need to get working.


                              • 12. Re: How many EntityManagers and SFSBs in a web app?
                                None None Master

                                And now I'm getting it to work.

                                I followed all the instructions in Chap. 9 and switched from using the @PersistenceContext annotation to just using @In and injecting the SMPC. At the same time I'm ripping out all the Tomahawk stuff, to be replaced with Icefaces at some future date.

                                It seems to be working. I'll see if I get any dreaded LIEs, but it seems like I shouldn't. I'm also getting a better hang of how components are managed in the various scopes, so I'm able to @In and @Out and get expected results.

                                One more question: If I specify a bean as @Stateful but I don't specify a scope, is the natural scope the conversation, or the session?

                                • 13. Re: How many EntityManagers and SFSBs in a web app?
                                  Pete Muir Master

                                  Conversation for stateful & javabean, event for stateless.