Kotlin泛型在Criteria API中

huangapple go评论64阅读模式
英文:

Kotlin generics in Criteria Api

问题

I'm trying to add dynamic predicate translating some domain objects into javax.persistence.criteria.Predicate, however I have problems with correctly specifying types in generic methods. Below is a simplified piece of code presenting more or less the method contract I have to uphold. By that I mean that both path and value are calculated somehow.

enum class Operator { EQUAL, NOT_EQUAL, GREATER_THAN_OR_EQUAL, LESS_THAN_OR_EQUAL, GREATER_THAN, LESS_THAN, }

inline fun <T> buildPredicate(
            root: Root<*>,
            builder: CriteriaBuilder,
            operator: Operator,
            pathSupplier: () -> Path<T>,
            valueSupplier: () -> T
        ) {
            val path = pathSupplier()
            val value = valueSupplier()
            when (operator) {
                EQUAL -> builder.equal(path, value)              // ok
                GREATER_THAN -> builder.greaterThan(path, value) // this wont compile though
                else -> throw IllegalArgumentException()
            }
        }

On the marked line it shows

None of the following functions can be called with the arguments supplied.

there is a definition I'm targeting though

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

Is this even doable?

As a side note I may add that in runtime T from the example above will resolve to either some enum, String or LocalDateTime.

英文:

I'm trying to add dynamic predicate translating some domain objects into javax.persistence.criteria.Predicate, however I have problems with correctly specifying types in generic methods. Below is a simplified piece of code presenting more or less the method contract I have to uphold. By that I mean that both path and value are calculated somehow.

enum class Operator { EQUAL, NOT_EQUAL, GREATER_THAN_OR_EQUAL, LESS_THAN_OR_EQUAL, GREATER_THAN, LESS_THAN, }

inline fun &lt;T&gt; buildPredicate(
            root: Root&lt;*&gt;,
            builder: CriteriaBuilder,
            operator: Operator,
            pathSupplier: () -&gt; Path&lt;T&gt;,
            valueSupplier: () -&gt; T
        ) {
            val path = pathSupplier()
            val value = valueSupplier()
            when (operator) {
                EQUAL -&gt; builder.equal(path, value)              // ok
                GREATER_THAN -&gt; builder.greaterThan(path, value) // this wont compile though
                else -&gt; throw IllegalArgumentException()
            }
        }

On the marked line it shows

None of the following functions can be called with the arguments supplied.

there is a definition I'm targeting though

&lt;Y extends Comparable&lt;? super Y&gt;&gt; Predicate greaterThan(Expression&lt;? extends Y&gt; x, Y y);

Is this even doable?

As a side note I may add that in runtime T from the example above will resolve to either some enum, String or LocalDateTime.

答案1

得分: 1

提供使用where T: Comparable<T>子句的方法边界(请参见下面修改后的方法)-更多信息-https://kotlinlang.org/docs/generics.html#type-erasure;

inline fun <T> buildPredicate(
    root: Root<*>,
    builder: CriteriaBuilder,
    operator: Operator,
    pathSupplier: () -> Path<T>,
    valueSupplier: () -> T
) where T: Comparable<T>{
    val path = pathSupplier()
    val value = valueSupplier()
    when (operator) {
        Operator.EQUAL -> builder.equal(path, value)              // ok
        Operator.GREATER_THAN -> builder.greaterThan(path, value) // this compiles
        else -> throw IllegalArgumentException()
    }
}
英文:

Supply the bounds for the method using the where T: Comparable&lt;T&gt; clause (see amended method below) - further info - https://kotlinlang.org/docs/generics.html#type-erasure;

inline fun &lt;T&gt; buildPredicate(
    root: Root&lt;*&gt;,
    builder: CriteriaBuilder,
    operator: Operator,
    pathSupplier: () -&gt; Path&lt;T&gt;,
    valueSupplier: () -&gt; T
) where T: Comparable&lt;T&gt;{
    val path = pathSupplier()
    val value = valueSupplier()
    when (operator) {
        Operator.EQUAL -&gt; builder.equal(path, value)              // ok
        Operator.GREATER_THAN -&gt; builder.greaterThan(path, value) // this compiles
        else -&gt; throw IllegalArgumentException()
    }
}

huangapple
  • 本文由 发表于 2023年5月22日 17:44:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76304889.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定