2015-04-10 6 views
0

Я разрабатываю веб-приложение Spring, чей уровень persistence состоит из созданных Spring Roo объектов JPA, с Hibernate как провайдер персистентности и MySql в качестве базовой БД.JPA/Hibernate генерирует неправильный SQL в методе поиска Spring Roo

Среди моих образований у меня есть класс Detection с полем TSTAMP java.util.Date генерируемого в Роо следующим образом:

entity jpa --class ~.data.Detection 
... 
field date --fieldName tstamp --type java.util.Date 
... 
finder add findDetectionsByTstampBetween 

(метод искателя был конечно выбран после выполнения finder list)

В моем коде контроллера в точке, я призываю:

List<Detection> detections = Detection.findDetectionsByTstampBetween(from, to).getResultList(); 

Откуда и два допустимых java.util.Date(s). Однако при тестировании выборочных данных (после обеспечения того, что для выбранного выбора из, в возвращаемый список не должно быть пустым), я получил пустой список и исследовал причины.

я нашел в TOMCAT журналы, Hibernate производило следующий SQL:

Hibernate: select detection0_.id as id1_3_, ...etc..., detection0_.tstamp as tstamp4_3_ from detection detection0_ where detection0_.tstamp>=? 

Я бы ожидать, где положение должно содержать заднюю «AND detection0_.tstamp<=?», проверяя другой предел диапазона дат. Я взглянул на сгенерированный метод Detection.findDetectionsByTstampBetween(Date minTstamp, Date maxTstamp) в Detection_Roo_Finder.aj, и фактически «AND» присутствует в вызове createQuery.

public static TypedQuery<Detection> Detection.findDetectionsByTstampBetween(Date minTstamp, Date maxTstamp) { 
     if (minTstamp == null) throw new IllegalArgumentException("The minTstamp argument is required"); 
     if (maxTstamp == null) throw new IllegalArgumentException("The maxTstamp argument is required"); 
     EntityManager em = Detection.entityManager(); 
     TypedQuery<Detection> q = em.createQuery("SELECT o FROM Detection AS o WHERE o.tstamp BETWEEN :minTstamp AND :maxTstamp", Detection.class); 
     q.setParameter("minTstamp", minTstamp); 
     q.setParameter("maxTstamp", maxTstamp); 
     return q; 
} 

Любая идея, что может стать причиной проблемы?

ответ

0

Я наконец нашел решение этой загадки, и, как оказалось, проблема не имела ничего общего с JPA.

Проблема заключалась в том, что вызов в сохранении слоя был вставлен внутри контроллера службы Rest со следующим отображением:

@ResponseBody 
@RequestMapping(value="/detections", method=RequestMethod.GET, params="from, to") 
public Object getDetectionsInRange(
     @RequestParam(required=true) @DateTimeFormat(pattern="yyyy-MM-dd HH:mm") final Date from, 
     @RequestParam(required=true) @DateTimeFormat(pattern="yyyy-MM-dd HH:mm") final Date to 
     ) 
{ 
    ... 
    List<Detection> detections = Detection.findDetectionsByTstampBetween(from, to).getResultList(); 
    ... 
} 

ошибка была в определении params= аргумента в @RequestMapping, правильный формат является следующим образом:

@RequestMapping(value="/detections", method=RequestMethod.GET, params={"from", "to"} ) 

Эта ошибка вызвана другой вариант метода контроллера для /detections. В этой второй версии я назвал другой метод поиска, который, похоже, создал неправильный SQL в Hibernate.

@ResponseBody 
@RequestMapping(value="/detections", method=RequestMethod.GET ) 
public Object getDetections(
     @RequestParam(required=false, defaultValue="0") int days, 
     @RequestParam(required=false, defaultValue="0") int hours, 
     @RequestParam(required=false, defaultValue="0") int minutes 
     ) 
{ 
    ... 
    List<Detection> detections = Detection.findDetectionsByTstampGreaterThanEquals(...).getResultList(); 
    ... 
}