2 Replies Latest reply: Feb 12, 2013 10:46 AM by 984733 RSS

    Getting Field from Collection

      Using the Criteria API, I am querying an entity, and I need to be able to use a field from another entity that is part of a relationship collection in a predicate. I know this is a case of me not quite totally having my head around this concept, so I was hoping someone could set me straight.
      Root<Hardware> hardwareRoot = query.from(Hardware.class);
      Path<HardwarePK> hardwarePkPath = hardwareRoot.get(Hardware_.id);
      Path<String> hardwareTypePath = hardwarePkPath.get(HardwarePK_.type);
      Expression<Collection<OsAssetActive>> osAssetPath = hardwareRoot.get(Hardware_.osAssetsActive);     <<<<<<<   osAssetsActive is a collection in the hardware entity
      Path<String> osAssetTypePath = osAssetPath.get(OsAssetActive_.hwType);     <<<<<<<<<<<     get() not valid method for 'osAssetPath'
      I can't figure out how to get to data in an entity in the collection. It's probably pretty simple, but it's just not sinking in.
        • 1. Re: Getting Field from Collection
          I usually try forming my queries in JPQL where it is more obvious, or there are more examples, of what needs to be done.
          From the JPA specification, section 4.4.4 Path Expressions state

          "It is syntactically illegal to compose a path expression from a path expression that evaluates to a collection.
          For example, if o designates Order, the path expression o.lineItems.product is illegal
          since navigation to lineItems results in a collection. This case should produce an error when the
          query string is verified. To handle such a navigation, an identification variable must be declared in the
          FROM clause to range over the elements of the lineItems collection. Another path expression must
          be used to navigate over each such element in the WHERE clause of the query, as in the following:
          SELECT DISTINCT l.product
          FROM Order AS o JOIN o.lineItems l"

          With Criteria api, the equivalent is:
          CriteriaQuery<Product> q = cb.createQuery(Product.class);
          Root<Order> order = q.from(Order.class);
          Join<Order, Item> item = order.join(Order_.lineItems);
          • 2. Re: Getting Field from Collection
            Thanks a bunch!

            Ironically, I was originally using a join. But then a coworker pointed out that we already had this relationship set up in the entity, so we thought we wouldn't need the join after all - it seemed redundant. WRONG! :-)