В примерах Spring Data JDBC, как мне написать простой запрос в аннотации @Query?
например Как мне добавить простой запрос findByName в Репозиторий LegoSet?
Когда я попробовал
@Query("select * from lego_set where name = :name")
List<LegoSet> findByName(@Param("name") String name);
он выдает следующую ошибку:
org.springframework.data.mapping.MappingException: Could not read property @org.springframework.data.annotation.Id() @org.springframework.data.relational.core.mapping.Column(value=handbuch_id, keyColumn=)private java.lang.Long example.springdata.jdbc.basics.aggregate.Manual.id from result set!
...
> Caused by: org.hsqldb.HsqlException: Column not found: manual_handbuch_idat org.hsqldb.error.Error.error(Unknown Source) at org.hsqldb.error.Error.error(Unknown Source) `
Кроме того, справочный документ, похоже, скопирован из некоторого общего документа с данными Spring, поскольку в нем упоминается производный запрос, который еще не существует в jdbc данных Spring.
@ user1211 нет атрибута nativeQuery в аннотации Spring Data JDBCs @Query, поскольку все запросы должны предоставляться на собственном диалекте SQL используемой базы данных.




Объект LegoSet имеет отношение 1: 1 к Manual.
Spring Data JDBC выбирает такую конструкцию с помощью соединения и ожидает репрезентативные столбцы в ResultSet.
Обратите внимание, что он ожидает столбцы, представляющие сам объект Manual, плюс столбец, образующий обратную ссылку на LegoSet.
Кроме того, все имена столбцов должны иметь префикс имени свойства + _, то есть в данном случае manual_.
Сообщение об ошибке фактически сообщает вам об отсутствующем столбце (по модулю отсутствующего пробела): Column not found: manual_handbuch_id.
В качестве альтернативы, вы также можете предоставить свой собственныйRowMapper
По поводу документации:
Вы в чем-то правы. Документация (почти) всех модулей Spring Data включает общую часть, которая легко приводит к путанице. Есть билет на поиск лучшего решения.
Из журнала я вижу, что собственный запрос для findAll () по умолчанию аналогичен тому, что вы упомянули, и я заменил свой запрос тем предложением plus where, которое сработало. Но не был уверен в соглашении об именах, таком как manual_handbuch_id. Также замечено от 1 до многих, это делается в отдельном запросе. Надеялся, что он тоже работает 1 на 1. Для более сложных случаев, когда у дочернего класса 1 на 1 есть собственный дочерний класс 1 на 1 и т. д., Тогда написание SQL будет нетривиальным и подверженным ошибкам.
Я согласен. Если у вас есть идея, как сделать это менее болезненным, создайте заявку. А пока, полагаю, я ожидаю, что люди будут много использовать специальные RowMappers для нетривиальных вещей.
Насколько сложно во внутренней реализации относиться к 1 к 1 так же, как к 1 ко многим? Если это просто по соображениям производительности, по крайней мере, было бы неплохо предоставить это как вариант. Другой подход - предоставлять производные запросы как другие данные Spring, которые должны охватывать более 90% наших случаев. Я вспомнил, что вы упомянули, что он уже в пути на ваших семинарах? Надеюсь, скоро увидим. Спасибо.
Присоединение к 1: произойдет много. То же самое для вывода запросов. Я думал об упрощении написания пользовательских запросов.
Думаю, я не совсем понимаю различия между Руководством и Моделью в этом примере. Они оба являются частью совокупности, почему в \ @Query я должен конкретно иметь дело с руководством, а не с моделью? В идеале мне не нужно беспокоиться о дочерних объектах в \ @Query.
Техническая причина заключается в том, что к совокупному корню можно присоединить любое количество взаимно однозначных отношений. Но с «один ко многим» в настоящее время ни одна из них не присоединяется (ожидается), поскольку, когда у вас более одной такой связи, вам нужно выбрать одну, к которой вы хотите присоединиться. В противном случае вы получите кросс-продукт с огромной мощностью.
Поддерживает ли Spring data jdbc настраиваемые изменяемые запросы, например пользовательский запрос на вставку? Я получаю A result was returned when none was expected.
@TobiAkinyemi Да, это так: github.com/spring-projects/spring-data-jdbc/blob/…
Я видел, как обновления работают нормально, но не вставки (возвращающие идентификатор). Это нормально работало с JPA
Вероятно, проблема в возврате идентификатора @TobiAkinyemi. Хотите создать проблему? jira.spring.io/browse/DATAJDBC
@JensSchauder Просто чтобы уточнить, нельзя ли с помощью spring data jdbc выполнить эту вставку и получить идентификатор?
@TobiAkinyemi в настоящее время не поддерживает аннотацию запроса. Стандартное сохранение делает это. Или вы можете написать для него собственный метод.
Позвольте нам продолжить обсуждение в чате.
Я думаю, вы пытаетесь выполнить собственный запрос. Попробуйте, как показано ниже.
@Query( value = "SELECT * FROM lego_set ls where ls.name = :name",
nativeQuery = true)
List<LegoSet> findByName(@Param("name") String name);
Это должно сработать.
Это относится к весенним данным jdbc, а не только к весенним данным jpa, поэтому nativeQuery не будет работать.
Так же, как завершение ответа @jens-schauder:
Запрос должен быть таким:
@Query("SELECT ls.id, ls.name, ls.min_age, ls.max_age, " +
"h.handbuch_id AS manual_handbuch_id, h.author AS manual_author, h.text AS manual_text " +
"FROM lego_set ls JOIN handbuch h ON ls.id = h.handbuch_id " +
"WHERE name = :name")
List<LegoSet> findByName(@Param("name") String name);
Используя этот метод, проходят следующие тесты:
@Test
public void so_52978700() {
// prepare
LegoSet cars = createLegoSet("Small Car - 01", 5, 10);
cars.setManual(new Manual("Just put all the pieces together in the right order", "Jens Schauder"));
repository.save(cars);
// execute
List<LegoSet> actual = repository.findByName("Small Car - 01");
// verify
assertThat(actual).hasSize(1);
assertThat(actual.get(0).getName()).isEqualTo("Small Car - 01");
assertThat(actual.get(0).getManual().getText()).isEqualTo("Just put all the pieces together in the right order");
}
Вероятно, вам нужно установить nativeQuery = true. Обратитесь к petrikainulainen.net/programming/spring-framework/…