Построитель критериев гибернации между предикатом с определением типа абстрактного класса - PullRequest
0 голосов
/ 12 июня 2018

Я хочу использовать CriteriaBuilder в Hibernate между методами, которые определены как:

<Y extends Comparable<? super Y>> Predicate between(Expression<? extends Y> v, Y x, Y y)

У меня есть следующий абстрактный класс, важный метод - toPredicate.

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;

abstract public class RangeObject<T> {
    protected T from;
    protected T to;

    public RangeObject(T from, T to) {
        this.from = from;
        this.to = to;
    }

    public T getFrom() {
        return from;
    }

    public T getTo() {
        return to;
    }

    /**
     * Create a predicate for testing whether the second argument is
     * between the `from` and `to` values
     *
     * @param builder Criteria Builder instance
     * @param path    Attribute path from a bound type
     * @return between predicate
     */
    public Predicate toPredicate(
            CriteriaBuilder builder,
            Path<T> path
    ) {
        if (isSingleValue(from, to)) {
            return builder.equal(path, from);
        } else {
            return builder.between(path, from, to);
        }
    }

    /**
     * @param from From value
     * @param to   To value
     * @return Whether parameters to this method match
     */
    abstract public boolean isSingleValue(T from, T to);
}

У него есть параметр Path<T>.
Интерфейс пути определен как interface Path<X> extends Expression<X>, который, насколько я понимаю, должен быть совместим с Expression<? extends Y>.

Я получаюследующая ошибка:

no suitable method found for between(javax.persistence.criteria.Path<T>,T,T)

Я даже попытался изменить метод toPredicate на:

public Predicate toPredicate(
        CriteriaBuilder builder,
        Expression<? extends T> expression
) {
    if (isSingleValue(from, to)) {
        return builder.equal(expression, from);
    } else {
        return builder.between(expression, from, to);
    }
}

И я все еще получаю ту же ошибку:

no suitable method found for between(javax.persistence.criteria.Expression<capture#1 of ? extends T>,T,T)

Если я жестко закодировал тип, он работает (это пример того, что работает:)

import ...

abstract public class RangeObject {
    protected LocalDateTime from;
    protected LocalDateTime to;

    ...

    public Predicate toPredicate(
            CriteriaBuilder builder,
            Path<LocalDateTime> path
    ) {
        if (isSingleValue(from, to)) {
            return builder.equal(path, from);
        } else {
            return builder.between(path, from, to);
        }
    }

    ...
}

Что я делаю не так?

1 Ответ

0 голосов
/ 12 июня 2018

На основании спецификации метода аргументы в методе between должны расширяться Comparable

<Y extends Comparable<? super Y>> Predicate between(Expression<? extends Y> v, Y x, Y y);

Если вы сделаете T, в спецификации вашего класса будет расширяться Comparable, это будет работать как для Path, так и для Expression.

public abstract class RangeObject<T extends Comparable<T>> {
   protected T from;
   protected T to;
   .......
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...