J'utilise Scala pour faire des requêtes de typesafe JPA2. donc j'ai une classe Java MetaModel (le seul Java dans mon code, le reste est Scala -> pur problème Scala), qui contient les attributs mon modèle:Comment appeler une fonction qui a une carte avec un type générique en tant que paramètre?
@StaticMetamodel(User.class)
public class User_ {
public static volatile SingularAttribute<User, Long> id;
public static volatile SingularAttribute<User, String> name;
}
Pour faire une requête pour un seul attribut, i cette fonction:
def findByAttribute[T](
attribute:SingularAttribute[User, T], value:T):ArrayList[User] =
{
...
}
que je peux appeler comme ceci:
userEJB.findByAttribute(User_.name, "John")
maintenant, je suis en train de créer une fonction de requête, avec laquelle je peux interroger pour plusieurs attributs à une fois, et donc je veux utiliser une carte de SingularAttributes comme paramètre pour ma fonction:
// Map is of type scala.collection.immutable.Map
def findByAttributes[T](
attributes:Map[SingularAttribute[User, T], T]):ArrayList[User] =
{
...
}
Ok, donc la fonction devrait fonctionner ... Mais comment puis-je appeler ??? Disons, par exemple, je veux interroger avec une carte comme ceci:
User_.name -> "Doe"
User_.id -> 5
Donc, ma première approche de la définition de cette carte à Scala et passant à findByAttributes est la suivante:
val criteria = Map(User_.name -> "Doe", User_.id -> 5)
// Produces Compiler Error
val users = userEJB.findByAttributes(criteria)
Malheureusement, le compilateur ISN « t satisfait lors du passage à la SearchFor findByAttributes fonction, produisant l'erreur ci-dessous:
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]
Ce problème est le générique le plus compliqué que j'ai jamais eu. Un peu trop haut pour mes compétences;) Quelqu'un sait comment je peux construire le bon type de carte que je peux passer à la fonction? Est-ce possible, ou est-ce que le compilateur ne peut plus déduire le type dans mon cas? Ou est-ce que j'utilise la mauvaise infrastructure de données?
L'utilisation d'identificateurs se terminant par le caractère de soulignement est l'un des pires choix possibles. –
L'utilisation d'identifiants se terminant par le caractère de soulignement est une pratique courante lors de la définition de MetaModels pour JPA2, au moins pour Java. Voir http://java.sun.com/developer/technicalArticles/JavaEE/JavaEE6Overview_Part3.html (recherche de Employee_). – ifischer
Que se passe-t-il si vous spécifiez explicitement le type Map [SingularAttribute [User, String], String] pour les critères et le paramètre de type [String] lors de l'appel de findByAttributes? – Landei