à l'aide d'un ParameterExpression par rapport à une variable en JPA Critères d'API

Lors de l'utilisation de la JPA API criteria, quel est l'avantage de l'utilisation d'un ParameterExpression sur une variable directement? E. g. quand je veux rechercher un client par son nom dans une variable de type String, je pourrais écrire quelque chose comme

private List<Customer> findCustomer(String name) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Customer> criteriaQuery = cb.createQuery(Customer.class);
    Root<Customer> customer = criteriaQuery.from(Customer.class);
    criteriaQuery.select(customer).where(cb.equal(customer.get("name"), name));
    return em.createQuery(criteriaQuery).getResultList();
}

Avec des paramètres, cela devient:

private List<Customer> findCustomerWithParam(String name) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Customer> criteriaQuery = cb.createQuery(Customer.class);
    Root<Customer> customer = criteriaQuery.from(Customer.class);
    ParameterExpression<String> nameParameter = cb.parameter(String.class, "name");
    criteriaQuery.select(customer).where(cb.equal(customer.get("name"), nameParameter));
    return em.createQuery(criteriaQuery).setParameter("name", name).getResultList();
}

De concision, je préfère la première méthode, en particulier lorsque la requête est plus longue avec des paramètres optionnels. Quels sont les inconvénients de l'utilisation de paramètres comme ceci, comme l'injection SQL?

Je ne peux pas parler pour JPA en général, mais j'ai trouvé que OpenJPA en interne convertit un des Critères de requête JPQL, ce qui peut être imprimé à l'aide de OpenJPA de fonctionnalités spécifiques (voir la section openjpa.apache.org/builds/2.1.1/apache-openjpa/docs/...). La première requête se traduit par "SELECT c from Client c OÙ c.name = "test " Client". Cela signifie qu'il n'utilisez PAS un paramètre donc, si cela devient de plus amples traduit de SQL correspondant de l'instruction préparée à ne PAS utiliser un paramètre. La seconde version se traduit par la JPQL "SELECT c from Client c OÙ c.nom = :nom de", donc je vais utiliser des paramètres.
Après quelques essais, j'ai trouvé que l'écriture de la même requête JPQL et en utilisant le nom de "' OU 'x'='x" injecte JPQL. Lors de l'utilisation de l'API criteria, à la génération de JPQL que OpenJPA journaux semble exactement le même. Mais la réelle SQL qui est connecté par OpenJPA puis utilise une instruction préparée avec un paramètre de valeur "' OU 'x'='x" au lieu de " dans la JPQL cas. Cela signifie que l'injection SQL ne fonctionne pas ici! Malheureusement, je n'ai aucune idée de quelle est la fiabilité de ce qui est. Il semble que cette une fonctionnalité non documentée.
Astuce: j'ai juste donné querydsl.com de l'essayer et c'est la syntaxe est beaucoup plus concis et lisible. Il semble que pour se prémunir contre les injections sql en utilisant les paramètres par défaut.
C'est, si vous n'utilisez pas de paramètres, l'injection SQL est possible?

OriginalL'auteur Henno Vermeulen | 2013-05-08