Skip to Main Content

Integration

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Criteria API - Avoiding a crossjoin when using a composite / embeddedId PK

2681373May 27 2014 — edited May 30 2014

Hi, Im using Spring Data's specification framework and have the following toPredicate() method. Its almost working except the "selectedTargetSubquery.from(SelectedTarget)" part of the query is generating a "cross join" which is resulting in too many rows.

Is there a way I can do an inner join (using Join<X,Y> xx = ) ?  it seems to be impossible with composite keys

@Override

    Predicate toPredicate(Root<Target> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

        //we want to query SelectedTarget on  activationUUID to find targets to exclude

        Subquery<SelectedTarget> selectedTargetSubquery = query.subquery(SelectedTarget.class)

        Root<SelectedTarget> selectedTargetRoot = query.from(SelectedTarget.class)

        Path<SelectedTargetPK> selectedTargetPKPath = selectedTargetRoot.get("selectedTargetPK")

        Path<Target> targetPath = selectedTargetPKPath.get("target")

        selectedTargetSubquery.select(targetPath.get("targetId"))

        selectedTargetSubquery.from(SelectedTarget)

        selectedTargetSubquery.where(selectedTargetPKPath.get("activationUUID").in([activationUUID]))

        return root.get("targetId").in(selectedTargetSubquery).not()

    }

Here is where I tried a Join: but get error :  java.lang.ClassCastException: org.hibernate.ejb.metamodel.SingularAttributeImpl$Identifier cannot be cast to javax.persistence.metamodel.ManagedType

    @Override

    Predicate toPredicate(Root<Target> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

        //we want to query SelectedTarget on  activationUUID to find targets to exclude

        Subquery<SelectedTarget> selectedTargetSubquery = query.subquery(SelectedTarget.class)

        Root<SelectedTarget> selectedTargetRoot = query.from(SelectedTarget.class)

        Join<SelectedTargetPK> selectedTargetPKPath = selectedTargetRoot.join("selectedTargetPK")       ///  TRYING JOIN HERE

        Path<Target> targetPath = selectedTargetPKPath.get("target")

        selectedTargetSubquery.select(targetPath.get("id"))

        selectedTargetSubquery.from(SelectedTarget)

        selectedTargetSubquery.where(selectedTargetPKPath.get("activationUUID").in([activationUUID]))

        return root.get("id").in(selectedTargetSubquery).not()

    }

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 27 2014
Added on May 27 2014
1 comment
3,869 views