2016-04-23 13 views
0

Ich habe zwei Entitäten, foo und bar. Ein Foo kann einen 0-n-Balken haben.Spring RestFul jquery jpa-Kriterien - HEAD gibt 1 statt 0 zurück

In foo und bar Ich habe diese Daten:

---- foo-table (2 rows) ---  ---- bar-table (1 row) ---- 
fooID       barID  fk_foo 
1        1   1 
2          

Foo und Bar sind in ruhigen Service und Ich mag die Anzahl der Bar finden 2 die foo mit der ID mit.

Da fooID # 2 keinen referenzierten Balken hat, sollte die Anzahl 0 sein. Hier mein Problem: der Service meldet mir die Anzahl der auf foo # 2 bezogenen Bar ist 1 statt 0!

Mein Controller:

@Autowired(required = false) 
private final BarFilter[] filters = new BarFilter[0]; 

/** 
* Count all bars available. 
*/ 
@RequestMapping(value="/bar", method = RequestMethod.HEAD) 
public void countBar(final HttpServletResponse response, final HttpServletRequest request) { 
    final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); 
    final CriteriaQuery<Long> criteriaQuery = criteriaBuilder.createQuery(Long.class); 
    final Root<Bar> root = criteriaQuery.from(Bar.class); 
    criteriaQuery.select(criteriaBuilder.count(root)); 
    for (final BarFilter filter: filters) { 
     filter.count(request, criteriaQuery, root, criteriaBuilder); 
    } 
    final Query query = entityManager.createQuery(criteriaQuery); 
    final Number count = (Number)query.getSingleResult(); 
    LOG.info("Found " + count + "x Bar."); 
    response.setIntHeader("count", count.intValue()); 
} 

Dies ist der Count-Methode der BarFilter Implementierung ist:

@Override 
public void count(HttpServletRequest request, CriteriaQuery<Long> query, Root<Bar> root, CriteriaBuilder builder) { 
    final Enumeration<String> parameterNames = request.getParameterNames(); 
    while (parameterNames.hasMoreElements()) { 
     final String name = parameterNames.nextElement(); 
     String prop = name; 
     if (!prop.contains("[]")) { 
      prop = prop.replace("]", ""); 
      prop = prop.replace("[", "."); 
      final String[] split = prop.split("\\."); 
      Path<Object> path = null; 
      try { 
       final Root<Bar> r = query.from(Bar.class); 
       for (final String property : split) { 
        if (path == null) { 
         path = r.get(property); 
        } else { 
         path = path.get(property); 
        } 
       } 
       query.where(builder.equal(path, request.getParameter(name))); 
      } catch (final IllegalArgumentException e) { 
       System.out.println(prop + " not found"); 
      } 
     } 
    } 
} 

Und das ist die jQuery-Request:

jQuery.ajax({ 
     url: 'rest/bar', 
     type: 'HEAD', 
     dataType: 'json', 
     data: {foo:{id:2}}, 
     success: function(data, state, xhr){ 
      alert(xhr.getResponseHeader('count')); 
     }, 
     error: function(err) { 
      alert('error:' + err.status); 
     } 
    }); 

Chrome gibt mir Diese Anfrage in der Registerkarte Netzwerk: http://localhost:8080/MyServer/rest/bar?foo%5Bid%5D=2 mit dieser Abfragezeichenfolge:

enter image description here

und diese Antwort-Header:

enter image description here

Frage: Warum werde ich eine Zählung von 1 statt 0?

Antwort

0

Ah, nach Stunden habe ich es.

Ich habe zweimal eine .from(...), in der Restfull countBar -Methode und eine andere in der count -Methode. Dies erstellt einen Kreuz-Join und liest die Daten zweimal, nur die zweite where wird zu einer Where-Klausel.