@SuppressWarnings("unchecked")
  static <T> Expression<T> toExpressionRecursively(From<?, ?> from, PropertyPath property) {

    Bindable<?> propertyPathModel = null;
    Bindable<?> model = from.getModel();
    String segment = property.getSegment();

    if (model instanceof ManagedType) {

      /*
       *  Required to keep support for EclipseLink 2.4.x. TODO: Remove once we drop that (probably Dijkstra M1)
       *  See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=413892
       */
      propertyPathModel = (Bindable<?>) ((ManagedType<?>) model).getAttribute(segment);
    } else {
      propertyPathModel = from.get(segment).getModel();
    }

    if (requiresJoin(propertyPathModel, model instanceof PluralAttribute)
        && !isAlreadyFetched(from, segment)) {
      Join<?, ?> join = getOrCreateJoin(from, segment);
      return (Expression<T>)
          (property.hasNext() ? toExpressionRecursively(join, property.next()) : join);
    } else {
      Path<Object> path = from.get(segment);
      return (Expression<T>)
          (property.hasNext() ? toExpressionRecursively(path, property.next()) : path);
    }
  }
Exemple #2
0
  @SuppressWarnings("unchecked")
  static <T> Expression<T> toExpressionRecursively(From<?, ?> from, PropertyPath property) {

    Bindable<?> propertyPathModel = null;
    if (from.getModel() instanceof ManagedType) {
      /*
       *  Avoid calling from.get(...) because this triggers the generation of an inner-join instead
       *  of and outer-join in eclipse-link.
       *  See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=413892
       */
      propertyPathModel =
          (Bindable<?>) ((ManagedType<?>) from.getModel()).getAttribute(property.getSegment());
    } else {
      propertyPathModel = from.get(property.getSegment()).getModel();
    }

    if (property.isCollection() || requiresJoin(propertyPathModel)) {
      Join<?, ?> join = getOrCreateJoin(from, property.getSegment());
      return (Expression<T>)
          (property.hasNext() ? toExpressionRecursively(join, property.next()) : join);
    } else {
      Path<Object> path = from.get(property.getSegment());
      return (Expression<T>)
          (property.hasNext() ? toExpressionRecursively(path, property.next()) : path);
    }
  }
	/**
	 * @see DATAJPA-403
	 */
	@Test
	public void reusesExistingJoinForExpression() {

		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<User> query = builder.createQuery(User.class);
		Root<User> from = query.from(User.class);

		PropertyPath managerFirstname = PropertyPath.from("manager.firstname", User.class);
		PropertyPath managerLastname = PropertyPath.from("manager.lastname", User.class);

		QueryUtils.toExpressionRecursively(from, managerLastname);
		QueryUtils.toExpressionRecursively(from, managerFirstname);

		assertThat(from.getJoins(), hasSize(1));
	}
	/**
	 * @see DATAJPA-401
	 */
	@Test
	public void doesNotCreateAJoinForNonOptionalAssociation() {

		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<Order> query = builder.createQuery(Order.class);
		Root<Order> root = query.from(Order.class);

		QueryUtils.toExpressionRecursively(root, PropertyPath.from("customer", Order.class));
	}
	/**
	 * @see DATAJPA-454
	 */
	@Test
	public void createsJoingToTraverseCollectionPath() {

		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<User> query = builder.createQuery(User.class);
		Root<User> root = query.from(User.class);

		QueryUtils.toExpressionRecursively(root, PropertyPath.from("colleaguesLastname", User.class));

		assertThat(root.getJoins(), hasSize(1));
	}
	/**
	 * @see DATAJPA-401
	 */
	@Test
	public void createsJoinForOptionalAssociation() {

		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<User> query = builder.createQuery(User.class);
		Root<User> root = query.from(User.class);

		QueryUtils.toExpressionRecursively(root, PropertyPath.from("manager", User.class));

		assertThat(root.getJoins(), hasSize(1));
	}
Exemple #7
0
  /**
   * Creates a criteria API {@link javax.persistence.criteria.Order} from the given {@link Order}.
   *
   * @param order the order to transform into a JPA {@link javax.persistence.criteria.Order}
   * @param root the {@link Root} the {@link Order} expression is based on
   * @param cb the {@link CriteriaBuilder} to build the {@link javax.persistence.criteria.Order}
   *     with
   * @return
   */
  @SuppressWarnings("unchecked")
  private static javax.persistence.criteria.Order toJpaOrder(
      Order order, Root<?> root, CriteriaBuilder cb) {

    PropertyPath property = PropertyPath.from(order.getProperty(), root.getJavaType());
    Expression<?> expression = toExpressionRecursively(root, property);

    if (order.isIgnoreCase() && String.class.equals(expression.getJavaType())) {
      Expression<String> lower = cb.lower((Expression<String>) expression);
      return order.isAscending() ? cb.asc(lower) : cb.desc(lower);
    } else {
      return order.isAscending() ? cb.asc(expression) : cb.desc(expression);
    }
  }
Exemple #8
0
  static Expression<Object> toExpressionRecursively(Path<Object> path, PropertyPath property) {

    Path<Object> result = path.get(property.getSegment());
    return property.hasNext() ? toExpressionRecursively(result, property.next()) : result;
  }