【发布时间】:2010-07-19 18:32:57
【问题描述】:
我正在使用 Scala 来执行类型安全的 JPA2 标准查询。 因此我有一个 Java MetaModel 类(我的代码中唯一的 Java,其余的是 Scala -> 纯 Scala 问题),它包含我的模型属性:
@StaticMetamodel(User.class)
public class User_ {
public static volatile SingularAttribute<User, Long> id;
public static volatile SingularAttribute<User, String> name;
}
要查询一个属性,我有这个功能:
def findByAttribute[T](
attribute:SingularAttribute[User, T], value:T):ArrayList[User] =
{
...
}
我可以这样称呼:
userEJB.findByAttribute(User_.name, "John")
现在我正在尝试创建一个查询函数,我可以使用它一次查询多个属性,因此我想使用 SingularAttributes 的 Map 作为我的函数的参数:
// Map is of type scala.collection.immutable.Map
def findByAttributes[T](
attributes:Map[SingularAttribute[User, T], T]):ArrayList[User] =
{
...
}
好的,所以该函数应该可以工作...但是我怎么称呼它???比如说我想用这样的地图查询:
User_.name -> "Doe"
User_.id -> 5
所以我在 Scala 中定义此 Map 并将其传递给 findByAttributes 的第一种方法是:
val criteria = Map(User_.name -> "Doe", User_.id -> 5)
// Produces Compiler Error
val users = userEJB.findByAttributes(criteria)
不幸的是,编译器在将 searchFor 传递给 findByAttributes 函数时不满意,产生以下错误:
no type parameters for method findByAttributes: (attributes:
Map[javax.persistence.metamodel.SingularAttribute[net.teachernews.model.User,
T],T])
java.util.ArrayList[net.teachernews.model.User] exist so that it can be applied to
arguments (scala.collection.immutable.Map[javax.persistence.metamodel.
SingularAttribute[
net.teachernews.model.User, _
>: java.lang.Long with java.lang.String
<: java.lang.Comparable[_
>: java.lang.Long with java.lang.String
<: java.lang.Comparable[_ >: java.lang.Long with java.lang.String
<: java.io.Serializable] with java.io.Serializable]
with java.io.Serializable],Any]) --- because ---
argument expression's type is not compatible with formal parameter type;
found :
scala.collection.immutable.Map[javax.persistence.metamodel.SingularAttribute[
net.teachernews.model.User, _
>: java.lang.Long with java.lang.String
<: java.lang.Comparable[_
>: java.lang.Long with java.lang.String
<: java.lang.Comparable[_ >: java.lang.Long with java.lang.String
<: java.io.Serializable] with java.io.Serializable] with java.io.Serializable],
Any]
required: Map[javax.persistence.metamodel.SingularAttribute[
net.teachernews.model.User,?T],?T]
这是我遇到过的最复杂的一般问题。对我的技能来说有点太高了;)任何人都知道我如何构建可以传递给函数的正确地图类型?甚至有可能,还是编译器不能在我的情况下推断类型?还是我使用了错误的数据结构?
【问题讨论】:
-
使用以下划线结尾的标识符是您可能做出的最糟糕的选择之一。
-
在为 JPA2 定义元模型时,使用以下划线字符结尾的标识符是常见的做法,至少对于 Java 来说是这样。请参阅java.sun.com/developer/technicalArticles/JavaEE/…(搜索 Employee_)。
-
如果在调用 findByAttributes 时显式指定类型 Map[SingularAttribute[User, String], String] 和类型参数 [String] 会发生什么?
-
可能是这样,但
Person_<%在 Java 中不是有效标识符,但在 Scala 中是有效的。这意味着像[Person_<%Ordered[Person_]]这样的语句与[Person_ <% Ordered[Person_]]的含义不同。