2017-10-14 11 views
1

Lors de l'exécution d'une commande, EntityManager jette (tous https://pastebin.com/zKYBhsv8)EclipseLink - requête a échoué à préparer, erreur inattendue est survenue

[EL Warning]: 2017-10-14 20:07:55.332--UnitOfWork(402037615)--Exception [EclipseLink-6168] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.QueryException 
Exception Description: Query failed to prepare, unexpected error occurred: [java.lang.NullPointerException]. 
Internal Exception: java.lang.NullPointerException 
Query: ReportQuery(referenceClass=MovieEntity) 

Le code ressemble à ceci

Je crée

final CriteriaBuilder cb = this.entityManager.getCriteriaBuilder(); 
final CriteriaQuery<Long> countQuery = cb.createQuery(Long.class); 
final Root<MovieEntity> root = countQuery.from(MovieEntity.class); 

alors je crée un prédicat

final Predicate whereClause = MovieSpecs 
      .getFindPredicate(root, cb, countries); 

c'est la méthode

public static Predicate getFindPredicate(
     final Root<MovieEntity> root, 
     final CriteriaBuilder cb 
     final List<CountryType> countries 
) { 
    final List<Predicate> predicates = new ArrayList<>(); 
    if(countries != null && !countries.isEmpty()) { 
     final List<Predicate> orPredicates = 
       countries 
         .stream() 
         .map(status -> cb.equal(root.get(MovieEntity_.countries), countries)) 
         .collect(Collectors.toList()); 
     predicates.add(cb.or(orPredicates.toArray(new Predicate[orPredicates.size()]))); 
    } 
    return cb.and(predicates.toArray(new Predicate[predicates.size()])); 
} 

puis définissez prédicat dans countQuery

countQuery.select(cb.count(root)).where(whereClause); 

et exécutez la commande

final Long count = this.entityManager.createQuery(countQuery).getSingleResult(); 

et ici je jette les erreurs ci-dessus.

MovieEntity: https://pastebin.com/CvhEQFZD MovieEntity_: http s: //pastebin.com/ZyJL0nmM ​​

+1

pouvez-vous élaborer ce que vous voulez réellement comparer avec ce 'cb.equal (root.get (MovieEntity_.countries), pays)'? – pirho

+0

Maintenant, j'ai pensé et j'ai vu que c'était inutile. Avec ce code, je voulais vérifier si le pays est sur la liste des pays du cinéma. Savez-vous comment le faire? –

+0

Utilisez 'in' pour vérifier si un élément est dans la liste, mais vous devrez être plus précis, car un film diffusé dans deux pays de la liste apparaîtra deux fois dans vos résultats en raison de la jointure sur la relation OneToMany. – Chris

Répondre

0

Je pense que le problème se produit lorsque EclipseLink tente de traiter countries correspondant fait contre la collecte:

.map(status -> cb.equal(root.get(MovieEntity_.countries), *countries*)) 

Je pense que votre l'intention était de vérifier l'égalité avec l'article en flux continu

.map(status -> cb.equal(root.get(MovieEntity_.countries), status)) 
+0

Malheureusement, cela n'a pas aidé. Vous pourriez avoir jeté un coup d'oeil au service https://pastebin.com/4tY5djAD et getFindPredicate https://pastebin.com/4eQb6yUE –

+0

Pouvez-vous ajouter le mappage ORM pour 'MovieEntity' à la question? –

+0

J'étais en train d'éditer. La meilleure chose est que l'erreur est seulement sur les listes. Il n'y a pas de problème avec des objets individuels. –

0

en supposant que vous voulez tous MovieEntities e à un ou plusieurs des Countries fournis, vous pouvez essayer de remplacer cb.equal(root.get(MovieEntity_.countries), countries) par cb.isMember(status, MovieEntity_.countries). Cependant, cela peut ne pas être la façon la plus optimale de le faire, mais au moins la plus facile à tester par rapport à votre code actuel. Peut-être que vous devriez également changer status à country pour rendre le code plus compréhensible.