/** * Return whether the given {@link From} contains a fetch declaration for the attribute with the given name. * * @param from the {@link From} to check for fetches. * @param attribute the attribute name to check. * @return */ private static boolean isAlreadyFetched(From<?, ?> from, String attribute) { for (Fetch<?, ?> fetch : from.getFetches()) { boolean sameName = fetch.getAttribute().getName().equals(attribute); if (sameName && fetch.getJoinType().equals(JoinType.LEFT)) { return true; } } return false; }
@Test public void test_criteria_from_fetch_example() { doInJPA( this::entityManagerFactory, entityManager -> { //tag::criteria-from-fetch-example[] CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Phone> criteria = builder.createQuery( Phone.class ); Root<Phone> root = criteria.from( Phone.class ); // Phone.person is a @ManyToOne Fetch<Phone, Person> personFetch = root.fetch( Phone_.person ); // Person.addresses is an @ElementCollection Fetch<Person, String> addressesJoin = personFetch.fetch( Person_.addresses ); criteria.where( builder.isNotEmpty( root.get( Phone_.calls ) ) ); List<Phone> phones = entityManager.createQuery( criteria ).getResultList(); //end::criteria-from-fetch-example[] assertEquals(2, phones.size()); }); }
@SuppressWarnings({ "unchecked" }) private void renderFetches( StringBuilder jpaqlQuery, RenderingContext renderingContext, Collection<Fetch> fetches) { if ( fetches == null ) { return; } for ( Fetch fetch : fetches ) { ( (FromImplementor) fetch ).prepareAlias( renderingContext ); jpaqlQuery.append( renderJoinType( fetch.getJoinType() ) ) .append( "fetch " ) .append( ( (FromImplementor) fetch ).renderTableExpression( renderingContext ) ); renderFetches( jpaqlQuery, renderingContext, fetch.getFetches() ); } } }
/** * Copy Fetches * * @param from source Fetch * @param to dest Fetch */ public static void copyFetches(Fetch<?, ?> from, Fetch<?, ?> to) { for (Fetch<?, ?> f : from.getFetches()) { Fetch<?, ?> toFetch = to.fetch(f.getAttribute().getName()); // recursively copy fetches copyFetches(f, toFetch); } } }
@Override public Attribute<? super Z, ?> getAttribute() { return getWrapped().getAttribute(); }
private static boolean containsMultiRelationFetch(Set<?> fetches) { for (Object fetchObj : fetches) { Fetch<?, ?> fetch = (Fetch<?, ?>) fetchObj; Attribute<?, ?> attr = fetch.getAttribute(); if (attr.isAssociation() && attr.isCollection()) return true; if (containsMultiRelationFetch(fetch.getFetches())) return true; } return false; }
@Override public JoinType getJoinType() { return getWrapped().getJoinType(); }
@Override public Set<Fetch<X, ?>> getFetches() { return getWrapped().getFetches(); }
private Fetch<?, ?> getFetchedAssoc(final FetchParent<?, ?> parent, final JoinType joinType, final String propertyToFetch) { // Search within current fetches for (final Fetch<?, ?> fetch : parent.getFetches()) { if (fetch.getAttribute().getName().equals(propertyToFetch)) { return fetch; } } // Create a new one return parent.fetch(propertyToFetch, joinType); }
private static boolean containsMultiRelationJoin(Set<?> fetches) { for (Object fetchObj : fetches) { Fetch<?, ?> fetch = (Fetch<?, ?>) fetchObj; Attribute<?, ?> attr = fetch.getAttribute(); if (attr.isAssociation() && attr.isCollection()) return true; if (containsMultiRelationFetch(fetch.getFetches())) return true; } return false; }
@SuppressWarnings("unchecked") protected void fetchToJoin(final From<?, ?> from, final Set<Fetch<?, ?>> fetches) { if (fetches != null && !fetches.isEmpty()) { for (final Fetch<?, ?> fetch : fetches) { @SuppressWarnings("rawtypes") final Join join = (Join) fetch; final Set<Fetch<?, ?>> fs = (Set<Fetch<?, ?>>) ((Set<?>) fetch.getFetches()); if (fs.isEmpty()) { try { from.getJoins().add(join); } catch (UnsupportedOperationException e) { } } else { fetchToJoin(join, fs); } } from.getFetches().clear(); } } }
/** * Return whether the given {@link From} contains a fetch declaration for the attribute with the given name. * * @param from the {@link From} to check for fetches. * @param attribute the attribute name to check. * @return */ private static boolean isAlreadyFetched(From<?, ?> from, String attribute) { for (Fetch<?, ?> fetch : from.getFetches()) { boolean sameName = fetch.getAttribute().getName().equals(attribute); if (sameName && fetch.getJoinType().equals(JoinType.LEFT)) { return true; } } return false; }
@Override @SuppressWarnings("hiding") public <X, Y> Fetch<X, Y> fetch(String attributeName) { return getWrapped().fetch(attributeName); }
private static void collectJoins(Path<?> path, Map<String, Path<?>> joins) { if (path instanceof From) { ((From<?, ?>) path).getJoins().forEach(join -> collectJoins(join, joins)); } if (path instanceof FetchParent) { try { ((FetchParent<?, ?>) path).getFetches().stream().filter(fetch -> fetch instanceof Path).forEach(fetch -> collectJoins((Path<?>) fetch, joins)); } catch (NullPointerException openJPAWillThrowThisOnEmptyFetches) { // Ignore and continue. } } if (path instanceof Join) { joins.put(((Join<?, ?>) path).getAttribute().getName(), path); } else if (path instanceof Fetch) { joins.put(((Fetch<?, ?>) path).getAttribute().getName(), path); } }
@SuppressWarnings({ "unchecked" }) private void renderFetches( StringBuilder jpaqlQuery, CriteriaQueryCompiler.RenderingContext renderingContext, Collection<Fetch> fetches) { if ( fetches == null ) { return; } for ( Fetch fetch : fetches ) { ( (FromImplementor) fetch ).prepareAlias( renderingContext ); jpaqlQuery.append( renderJoinType( fetch.getJoinType() ) ) .append( "fetch " ) .append( ( (FromImplementor) fetch ).renderTableExpression( renderingContext ) ); renderFetches( jpaqlQuery, renderingContext, fetch.getFetches() ); } } }
protected void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) { List<String> iPaths = new ArrayList<String>(); List<String> oPaths = new ArrayList<String>(); Set<Root<?>> roots = q.getRoots(); for (Root root : roots) { Set<Fetch> fetches = root.getFetches(); if (fetches == null) continue; for (Fetch<?,?> fetch : fetches) { String fPath = ((Members.Member<?, ?>)fetch.getAttribute()).fmd.getFullName(false); oPaths.add(fPath); if (fetch.getJoinType() == JoinType.INNER) { iPaths.add(fPath); } } } if (!iPaths.isEmpty()) { exps.fetchInnerPaths = iPaths.toArray(new String[iPaths.size()]); } if (!oPaths.isEmpty()) { exps.fetchPaths = oPaths.toArray(new String[oPaths.size()]); } }
/** Add all the fetches needed for completely loading the object graph */ protected void addFetches(final Root<PortletEntityImpl> definitionRoot) { definitionRoot .fetch(PortletEntityImpl_.portletPreferences, JoinType.LEFT) .fetch(PortletPreferencesImpl_.portletPreferences, JoinType.LEFT) .fetch(PortletPreferenceImpl_.values, JoinType.LEFT); definitionRoot.fetch(PortletEntityImpl_.windowStates, JoinType.LEFT); }
@SuppressWarnings({"unchecked", "rawtypes"}) protected void fetches(SearchParameters sp, Root<E> root) { for (List<Attribute<?, ?>> args : sp.getFetches()) { FetchParent<?, ?> from = root; for (Attribute<?, ?> arg : args) { boolean found = false; for (Fetch<?, ?> fetch : from.getFetches()) { if (arg.equals(fetch.getAttribute())) { from = fetch; found = true; break; } } if (!found) { if (arg instanceof PluralAttribute) { from = from.fetch((PluralAttribute) arg, JoinType.LEFT); } else { from = from.fetch((SingularAttribute) arg, JoinType.LEFT); } } } } } }
protected void evalFetchJoin(QueryExpressions exps, ExpressionFactory factory, CriteriaQueryImpl<?> q) { List<String> iPaths = new ArrayList<String>(); List<String> oPaths = new ArrayList<String>(); Set<Root<?>> roots = q.getRoots(); for (Root root : roots) { Set<Fetch> fetches = root.getFetches(); if (fetches == null) continue; for (Fetch<?,?> fetch : fetches) { String fPath = ((Members.Member<?, ?>)fetch.getAttribute()).fmd.getFullName(false); oPaths.add(fPath); if (fetch.getJoinType() == JoinType.INNER) { iPaths.add(fPath); } } } if (!iPaths.isEmpty()) { exps.fetchInnerPaths = iPaths.toArray(new String[iPaths.size()]); } if (!oPaths.isEmpty()) { exps.fetchPaths = oPaths.toArray(new String[oPaths.size()]); } }
@Override public <Y> Fetch<X, Y> fetch(PluralAttribute<? super X, ?, Y> attribute, JoinType jt) { return getWrapped().fetch(attribute, jt); }