Я работаю над устаревшей базой данных, где изменение схемы таблицы невозможно. Большинство записей уникальны, но есть несколько повторяющихся записей. По этой причине я модифицировал интерфейс RecordRepository.java для выполнения @Query с помощью map (). В противном случае JPA вернет те же данные, если сочтет это той же записью.
RecordRepository.java:
@Query("select new map(field1 as field1, field2 as field2) from Record where year = ?1")
List<Record> findByYear(String year);
RecordController.java:
@RestController
public class RecordController {
@Autowired
private RecordRepository recordRepository;
@RequestMapping(value = "/record/{year}", method = RequestMethod.GET)
public List<Record> recordByYear(@PathVariable("year") String year) {
List<Record> l = recordRepository.findByYear(year);
System.out.println(l.getClass());
System.out.println(l.get(1967));
return l;
}
}
Вывод getClass() - class java.util.ArrayList. Элемент печати 1967 из ArrayList - {field1=2018-01-15, field2=201801}.
Но при попытке получить строковое значение field1 с помощью String tmp_r = l.get(1967).getField1() я получаю ошибку java.util.HashMap cannot be cast to Record.
Я пробовал различные предложения от SO. У меня кружится голова, должно быть, я упускаю из виду какое-то простое объяснение этому.
С Уважением Клаус
Ааа, тогда мне нужно переделать карту () в JPA. Спасибо.




Что ж, l.getClass() - это список ArrayList, но это не означает, что все его элементы являются записями (возможно, приведение типов было выполнено где-то еще).
Когда вы вызываете l.get(1967), результирующим элементом является HashMap (верно?), Поэтому, возможно, вы можете сначала проверить фактический тип выражения l.get(1967).
Если карта проиндексирована по строкам, String tmp_r = l.get(1967).get("field1") напечатает ваше поле.
Тип возвращаемого значения в интерфейсе - List <Record>. И завернутый в map () в JPA. Так что, может быть, мне нужно распаковать что-нибудь? Я попробовал получить ("field1"), но это не сработало.
Мне нужно переосмыслить способ получения данных. Спасибо.
Ты ведешь меня в правильном направлении. Я добавлю свой ответ о том, как я ее решил, и награду вас правильным ответом.
Ответ Даниэля и комментарий Штефи привели меня в правильном направлении. Решение оказалось довольно простым. Моя ошибка может быть связана с тем, что я давно с этим работал. Я изменил тип возвращаемого значения в интерфейсе со списка на список.
RecordRepository.java:
List<HashMap<String, Record>> findByYear(String year);
RecordController:
List<HashMap<String, Record>> l = recordRepository.findByYear(year);
System.out.println(l.get(1967).get("field1"));
даст мне значение field1.
"select новая карта (поле1 как поле1, поле2 как поле2) from Record ..." создает
List<HashMap>, а неList<Record>, и ваш метод репозиторияList<Record> findByYear(String year)должен возвращатьList<Record>, поэтому он пытается преобразовать каждыйHashMapв наборе результатов вRecord, что невозможно.