Я нашел сценарий, в котором запрос, созданный при использовании QueryDSL, не работает с mongodb, но работает с jpa. Код является частью проекта на github.
Метод находится в https://github.com/corneil/spring-data-demo/blob/master/src/main/java/org/springframework/data/demo/service/LocationAndDeviceServiceImpl.java
Код:
private List<LocationUpdate> findLocationsFunctions(String deviceId, Date startDate, Date endDate) {
logger.info("findLocations:" + deviceId + "," + startDate + "," + endDate);
DeviceInfo device = deviceInfoRepository.findByDeviceId(deviceId);
if (device == null) {
throw new DataRetrievalFailureException("DeviceInfo:" + deviceId);
}
return locationUpdateRepository.findByDeviceAndLocTimeBetween(device, startDate, endDate);
}
private List<LocationUpdate> findLocationsQsl(String deviceId, Date startDate, Date endDate) {
logger.info("findLocations:" + deviceId + "," + startDate + "," + endDate);
DeviceInfo device = deviceInfoRepository.findByDeviceId(deviceId);
if (device == null) {
throw new DataRetrievalFailureException("DeviceInfo:" + deviceId);
}
List<LocationUpdate> result = new ArrayList<LocationUpdate>();
Iterable<LocationUpdate> resultSet = locationUpdateRepository
.findAll(locationUpdate.device.eq(device).and(locationUpdate.locTime.between(startDate, endDate)));
for (LocationUpdate loc : resultSet) {
result.add(loc);
}
return result;
}
public List<LocationUpdate> findLocations(String deviceId, Date startDate, Date endDate) {
return findLocationsFunctions(deviceId, startDate, endDate);
// return findLocationsQsl(deviceId, startDate, endDate);
}
Комментируя findLocationsFunctions и раскомментировав findLocationsQsl, вы сможете вызвать проблему. Обычные тесты в проекте будут выполнять код JPA с использованием встроенного H2. Вам понадобится доступ к mondodb для выполнения тестов для профиля mongo. Файл database.properties содержит URL-адрес mongodb. Код:
./gradlew test testMongo
Думаю, проблема в том, как предикат QueryDSL конвертируется в Mongo Query. Когда я изначально делал mongoTemplate. Код:
List<LocationUpdate> locations = mongoTemplate .find(
query(where("device").is(device).and("locTime").gte(startDate)
.and("locTime").lte(endTime)), LocationUpdate.class);
было выдано исключение «Из-за ограничений BasicDBObject вы не можете добавить второй $ And» и пришлось изменить на:
Код:
List<LocationUpdate> locations = mongoTemplate .find(
query(where("device").is(device).andOperator(
where("locTime").gte(startDate),
where("locTime").lte(endTime))), LocationUpdate.class);
Я заметил, что при использовании метода поиска отображается следующее:
Код:
"locTime" : {
"$gt" : { "$date" : "2014-04-02T14:06:23.600Z"} ,
"$lt" : { "$date" : "2014-04-02T14:06:23.931Z"}
}
Код в findLocationsQsl не отображает никаких критериев, связанных с locTime.
Тестирование с помощью Spring Data MongoDB 1.5.0 и QueryDSL 3.3.4