9 Replies Latest reply on Apr 10, 2006 5:03 AM by ejb3workshop

    Many2Many using ArrayList causing strange muliplication effe

    ejb3workshop

      I have a bidirectional many 2 many relationship between a contact and an address entity. A contact also has a bidirectional one 2 many relationship with contact details.
      The problem manifest itself when I do the following :


      create a contact with 10 contact details
      find the contact
      add 10 new addresses to the contact
      merge the contact
      find the contact again


      After the contact has been merged back the collection of the contact has 100 addresses in it. I have done the same sequence but only added 3 or 5 contact details in the beginning. The results where 30 or 50 addresses being returned.

      The database, funny enough, only has 10 addresses, and is correct. It seems as if the persistence context is getting corrupted ?

      I have changed to use a Set which resolved this problem. I am hoping that anybody else has similar experiences and has another solution.

      Thanks

        • 1. Re: Many2Many using ArrayList causing strange muliplication
          epbernard

          do not eager more than 1 bag semantic collection in a single resultset (through EAGER for example)
          you should not load more than one collection per resultset.

          • 2. Re: Many2Many using ArrayList causing strange muliplication
            ejb3workshop

            Hi Emmanuel,

            I don't understand what you mean by loading only one collection per resultset. Could you please elaborate a little more.

            Thanks
            Alex

            • 3. Re: Many2Many using ArrayList causing strange muliplication
              epbernard

              A bag semantic means potential duplicates in the collection.
              If you look at a resultset containing for example A -> Bs -> Cs you'll see that you cannot determine whether an element is a dupe in Bs or in Cs when you load those 2 collections through the same SQL resultset.

              There is no theorical solution for this issue, but it can happen in several situations:
              - multiple bags loading in a single HQL query with "fetch"
              - multiple bags collections set to EAGER in the static metadata (annotations), that requires it to be loaded in one resultset

              This problem does not happen for set or list semantic collections (note that a java.util.List can have bag semantic, refer to the annotations documentation for more info).

              The other generic issue with loading 2 collections in one resultset is that it returns way too much information and this information has to be deduplicate by hibernate in memory (too much DB work, too much network work, too much Java work). So usually, loading 2 collections in the same query is a bad choice.

              • 4. Re: Many2Many using ArrayList causing strange muliplication
                ejb3workshop

                I understand your point better now in case of using Hibernate directly. Yet with EJB3 this should not present a problem, in particular not the way it currently does. I would much rather incure the overhead on the database and in the persistence layer, then have duplicate objects returned. Also having been given all this new functionality by EJB3 I would hate to base my object graph design on the limitations of the underlying persistence framework.

                Is there a better way to annotate the entities, so that they are not loaded in the same fetch operation ? I think that would really solve my problem. A brief example would even be better.

                Thanks
                Alex

                • 5. Re: Many2Many using ArrayList causing strange muliplication
                  ejb3workshop

                  I have undertaken some more testing and can recreate this problem quite easily. Also from epbernard feedback it seems to be a understood problem.

                  During my testing I also tested the same scenario against glassfish / toplink and was not able to reproduce the problem.

                  • 6. Re: Many2Many using ArrayList causing strange muliplication
                    epbernard

                    I am actually considering adding a @Fetch annotation for the next release
                    And we're planning to workaround user multiple bag loads in Hibernate core for 3.2

                    But once again, having to workaround that is a sign that you're lazy defaults are not good

                    • 7. Re: Many2Many using ArrayList causing strange muliplication
                      ejb3workshop

                      Any new development on this issue. I tried this with RC5 and it still is a problem. I have ObjectA which contains a collection of ObjectBs and ObjectCs. When I configure both as Lazy then there is no problem, but also no Bs or Cs. With either one is LAZY there is also no problem, as with B or C are returned. The problem is when both are EAGER. In this case the product of the two is returned. I understand the problem lies with being unable to query two collections with one query.

                      Any other feedback on this would really help. Maybe a timeframe for a fix.

                      Tx

                      • 8. Re: Many2Many using ArrayList causing strange muliplication
                        bigm25

                        try

                        hibernate.max_fetch_depth=0
                        (i.e. include
                        <property name=" hibernate.max_fetch_depth" value="0" />
                        in <our persistence.xml
                        According to http://www.hibernate.org/hib_docs/reference/en/html/session-configuration.html
                        (and according to my own experiences;_) ) this setting will make these kind of "multiplication" problems go away. However you might miss some performance gains...

                        • 9. Re: Many2Many using ArrayList causing strange muliplication
                          ejb3workshop

                          Thanks. This was exactly what I am looking for.