Выберите строку с самой последней датой для пользователя с 1 условием в JPA
У меня есть этот Entity, и я хочу перечислить для каждого устройства последнее событие с сообщением свойства = 1
@Entity
@Table(name = "t_device_event")
@NamedQueries(value = {
@NamedQuery(name = "DeviceEvent.findWithMessageActive",
query = "from DeviceEvent as de1 where de1.message = 1 and de1.received = "
+ " ( select max(de2.received) from DeviceEvent de2 "
+ " where de2.device.id = de1.device.id ) "), )
public class DeviceEvent {
..
}
Но у меня есть проблема с утверждением в последнем тесте, потому что он рассматривает device3
как последнее событие и не тот случай.
assertTrue ((numDevicesWithActiveMessage+1) == deviceEventService.findWithActiveMessage().size());
DeviceEvent deviceEvent3 = newDeviceEvent();
deviceEvent3.setMessage(1);
deviceEventService.save(deviceEvent3);
DeviceEvent deviceEvent4 = newDeviceEvent();
deviceEventService.save(deviceEvent4);
assertTrue ((numDevicesWithActiveMessage+1) == deviceEventService.findWithActiveMessage().size());
Ответы
Ответ 1
Я предполагаю, что DeviceEvent.received
установлен в методе newDeviceEvent()
и установлен на текущее время.
В таком случае, когда между созданием deviceEvent3
и deviceEvent4
нет задержки, скорее всего, они будут иметь одно и то же время в поле received
. Затем запрос будет выбирать максимум из всех received
, и в соответствии с внешним условием он выберет как deviceEvent3
, так и deviceEvent4
, для которых будет соответствовать только deviceEvent3
, поскольку оно message
равно 1
.
Поэтому я считаю, что , потому что TEST считает device3 как последнее событие действительно правильным (скорее всего, если часы не будут отмечены между созданием двух событий).
Ответ 2
Почему бы не создать столбец идентификатора для каждой вставленной записи. Для экземпляра идентификатор, который автоматически увеличивается при вставке (идентификация). Оттуда он должен иметь возможность вернуть последнее значение этого идентификатора, и мы основываем наши данные на возвращаемом идентификаторе?
Ответ 3
Вы не установили - deviceEvent4.setMessage(1)
. Следовательно, deviceEvent3
будет последним событием устройства, и, следовательно, ваш тест, похоже, рассматривает правильное событие устройства (deviceEvent3) как последнее событие
Ответ 4
Думаю, вы должны добавить
deviceEvent4.setMessage(1);
так как этот код
assertTrue ((numDevicesWithActiveMessage+1) == deviceEventService.findWithActiveMessage().size());
ищет активное сообщение, но device4 его не имеет.
Таким образом, последним является device3.