2017-10-14 4 views
1

aufgetreten Wenn ein Befehl ausgeführt wird, wirft EntityManager aus (alle https://pastebin.com/zKYBhsv8)Eclipselink - Abfrage vorzubereiten fehlgeschlagen ist, unerwarteter Fehler

[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) 

Der Code sieht wie folgt aus

Ich schaffe

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

dann erstelle ich Prädikat

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

dies ist die Methode

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()])); 
} 

dann gesetzt Prädikat in countQuery

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

und führen Sie den Befehl

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

und hier habe ich die obigen Fehler bin zu werfen.

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

+1

können Sie näher erläutern, was Sie eigentlich mit diesem 'cb.equal (root.get (MovieEntity_.countries), countries) 'vergleichen möchten? – pirho

+0

Jetzt dachte ich und sah, dass es sinnlos war. Mit diesem Code wollte ich überprüfen, ob das angegebene Land auf der Liste der Filmländer steht. Weißt du, wie man es macht? –

+0

Verwenden Sie "in", um zu prüfen, ob ein Element in der Liste enthalten ist. Sie müssen jedoch genauer sein, da ein Film in zwei Ländern in der Liste aufgrund der Verknüpfung über die OneToMany-Beziehung doppelt angezeigt wird. – Chris

Antwort

0

ich glaube, das Problem tritt auf, wenn Eclipse versucht countries Abgleich mit Sammlung getan zu verarbeiten:

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

Ich denke, Ihre Absicht war für die Gleichstellung mit gestreamten Artikel

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

Leider hat das nicht geholfen. Sie hätten sich den Dienst https://pastebin.com/4tY5djAD und getFindPredicate ansehen können https://pastebin.com/4eQb6yUE –

+0

Können Sie der Frage ORM-Mapping für 'MovieEntity' hinzufügen? –

+0

Ich habe gerade bearbeitet. Das Beste ist, dass der Fehler nur auf den Listen liegt. Es gibt kein Problem mit einzelnen Objekten. –

0

Unter der Annahme, dass Sie alle MovieEntities th überprüfen möchten bei einer oder mehreren der bereitgestellten Countries können Sie versuchen, cb.equal(root.get(MovieEntity_.countries), countries) durch cb.isMember(status, MovieEntity_.countries) zu ersetzen.

Dies ist jedoch möglicherweise nicht der optimale Weg, um dies zu tun, aber zumindest am einfachsten gegen Ihren aktuellen Code zu testen. Vielleicht sollten Sie auch status zu country ändern, um den Code verständlicher zu machen.