3 Replies Latest reply on Nov 24, 2006 9:07 AM by kimbaltrue

    Problem with FetchType.EAGER - multiple instances of an obje

    reubenf

      I have a class named Item that contains a list of objects of type Algorithm. The list is defined with the following property and mapping:

      @ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, targetEntity=Algorithm.class)
      @JoinTable(
      name="item_algorithms",
      joinColumns = { @JoinColumn( name="item_id") },
      inverseJoinColumns = @JoinColumn( name="algorithm_id")
      )
      public List getAlgorithms() {
      return algorithms;
      }

      I have a unit test that creates an Item with three Algorithms and then retrieves the Item with its Identifier

      List itemIDs = new ArrayList(1);
      itemIDs.add("testID");

      Criteria criteria = session.createCriteria(Item.class);
      criteria.add(Restrictions.in("itemIdentifier", idValues));
      List entities = criteria.list();

      System.out.println(entities.size());

      With fetch=FetchType.EAGER - the returned list has 3 items
      With fetch=FetchType.LAZY - the returned list has 1 item

      The retrieved list should return only 1 item. The result should not be different based on the fetch strategy. It looks as if the query in the EAGER case does an outer join yielding 3 records and then creates 3 Items.

      Can anyone please explain what I may be doing wrong?

        • 1. Re: Problem with FetchType.EAGER - multiple instances of an
          kimbaltrue

          I seem to be having the same problem, but with a OneToMany relationship.

          I have a Parent object with a ManyToOne with a "classification" object which contains a list of attribute fields as a OneToMany relationship. Both of these joins are EAGER fetched.

          What's interesting is that the duplication effect happens with a short list, of attributes but doesn't with a long list.

          I'm using 4.0.5.GA, and EJB 3.0 persistence.



          Example: Parent *<- Classification (or Typing object) ->* Attribute
          Actual: Drawer *<- DrawerType ->* DrawerTrays
          All EAGER Fetched

          • 2. Re: Problem with FetchType.EAGER - multiple instances of an
            kimbaltrue

            One interesting note is that I'm getting a multiple of 5 per record. So, if I have twelve (12) records I get back sixty (60) records and duplicates.

            • 3. Re: Problem with FetchType.EAGER - multiple instances of an
              kimbaltrue

              It looks like this behavior isn't a bug (see quote from http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/reference/en/html_single/index.html#d0e1046)

              2.2.5.5. Association fetching
              You have the ability to either eagerly or lazily fetch associated entities. The fetch parameter can be set to FetchType.LAZY or FetchType.EAGER. EAGER will try to use an outer join select to retrieve the associated object, while LAZY is the default and will only trigger a select when the associated object is accessed for the first time. EJBQL also has a fetch keyword that allows you to override laziness when doing a particular query. This is very useful to improve performance and is decided on a use case to use case basis.



              It is very inconvenient though. I suppose there's no work around other than using LAZY Fetching.

              However, should an outer join of a parent table to a sub-table using the parent's primary key result in duplicate records? I'll have to do this manually to see what's going on.