10 Replies Latest reply on Jun 8, 2006 3:40 PM by Dave Whittaker

    Seam managed persistence and object attachment

    Dave Whittaker Novice

      I've switched from using the @PersistenceContext annotation to using seam managed persistence with @In(create = true) and now I'm getting behavior that doesn't make any sense to me. I load a list of objects, outject them as a @DataModel then recieve the selected as a @DataModelSelection and try to delete it. My assumption was that because the same entity manager is used throughout the conversation this wouldn't be a problem, but somehow I'm getting the following error

      org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [model.wine.Wine#36]

      I've looked at the debug output from org.jboss.seam.core.ManagedPersistenceContext which only shows one EM being created and never shows it being closed and I've added some debugging to my own app to prove that items are retrieved and deleted using the same EM, so how is this possible? I'm sure I'm missing something and I'm really hoping someone with more experience than me with extended persistence can point me in the right direction.

        • 1. Re: Seam managed persistence and object attachment
          Gavin King Master

          In principle this would work, but you havn't shown any code, so we can't tell you what you are doing wrong.

          Make sure you are not serializing the entity instance.

          • 2. Re: Seam managed persistence and object attachment
            Dave Whittaker Novice

            I realized that shortly after I sent the post. Turns out serialization is occuring because I had my @DataModel outjected to the page scope. I can see why some type of storage within the component tree would be necessary between requests, but couldn't the value binding be stored instead and then reattached, rather than serializing the objects directly? Or, if the objects do need serialization because the backing list might have changed, maybe the serialized version could be checked against the value binding for equality on the subsequent request to determine which version to use?

            • 3. Re: Seam managed persistence and object attachment
              Gavin King Master

              Storing page-scoped state on the server would be very memory hungry.

              All you need to do is merge() before remove().

              • 4. Re: Seam managed persistence and object attachment
                Dave Whittaker Novice

                I see your point, but this seems to be mostly related to the @DataModel annotation and it's implementation. What worries me more than the fact that my @DataModelSelection is serialized and becomes a detached object is that every object in the List that was outjected using @DataModel becomes detached as well. I just can't see why this would be necessary.

                • 5. Re: Seam managed persistence and object attachment
                  Gavin King Master

                  huh? its necessary since it is going to the client and back.

                  if you want some other behavior use conversation or session scope.

                  • 6. Re: Seam managed persistence and object attachment
                    Dave Whittaker Novice

                    Ok, I'm obviously not being very clear.

                    I have a conversation scoped bean which contains a List. The List is outjected using @DataModel(value="model", scope = ScopeType.PAGE). The DataModel is then used in the normal way:

                    <h:dataTable value="#{model}" var="row">...

                    Now when the response is submitted I understand that a serialized version of the component tree must be sent from the client, but I'd imagine those contents contain an HtmlDataTable that binds to the outjected DataModel, not the List that the DataModel wraps. Now the response is recieved, the component tree is deserialized including the DataModel and it does it's thing, namely, setting the correct @DataModelSelection. That explains why the selection has been serialized/deserialized, but the original List which was wrapped and is a field in the conversation scoped bean is also overwritten with the serialized/deserialized values. I can't see why that is necessary and, on top of it, it seem to me that if the two versions of the List were checked for equality the original list could simply be reused in most situations.

                    • 7. Re: Seam managed persistence and object attachment
                      Gavin King Master

                      This is how page scope works. If you declare that the list if kept in PAGE scope, that means it is serialized to the client.

                      • 8. Re: Seam managed persistence and object attachment
                        Dave Whittaker Novice

                        Right, but as I understand the @DataModel annotation it doesn't outject the actual annotated List into PAGE scope, it outjects a DataModel that wraps the List, so why then when the DataModel is reconstituted is it overwriting the perfectly good version of the wrapped List that is still contained in the conversation scoped bean? As I understood it @DataModel causes an outjection but it seems to be causing an INJECTION when the response occurs.

                        • 9. Re: Seam managed persistence and object attachment
                          Gavin King Master

                          It is designed so that you can have an event-scoped bean that has a page-scoped datamodel.

                          If you have a conversation scoped bean, it does not really make sense to have a page-scoped datamodel. Just use a conversation-scoped datamodel (the default).

                          • 10. Re: Seam managed persistence and object attachment
                            Dave Whittaker Novice

                            That's actually how I had it. The reason I made the change is that I have CRUD type functionality broken up over two SFSB components. One of them handles new object creation and the other handles list/update/delete. When I create a new object however, even if I inject the list/update bean into the create bean and call a method to set its query results to null, a new DataModel is not outjected. I figured by changing the outjection to page scope it would force the List to be pulled from the bean each time. At this point I'm programatically removing the DataModel from the conversation when a new object is created, but I don't like the fact that the create bean has to be aware of an outjected list that has nothing to do with its function. Any advice?