TGViewer
Spring АйО Spring АйО @spring_aio · 11K subscribers
Post #156 3.68K
❓ #ВопросЭксперту: Есть ли в Spring Data JDBC поддержка SpEL?

Во втором посте из цикла "#ВопросЭксперту" Михаил Поливаха рассказал, что из себя представляет поддержка SpEL в Spring Data JDBC и как мы с вами можем сделать её ещё лучше.

–––

Периодически получаю вопросы, связанные с работой Spel-a в Sping Data JDBC (на самом деле, все ниже сказанное относится также к R2DBC модулю). Решил написать пост с объяснением, почему имеем то, что имеем, и, что также важно - что можно улучшить.

Чтобы пояснить проблематику, предлагаю посмотреть на запрос ниже и сказать, все ли в нем корректно:


@Modifying
@Query("update :#{#entityName} set captured = false where captured = true and captured_time < :#{#dateMillis.toEpochMilli()}")
Long updateCaptureFlag(Instant dateMillis);


На самом деле ответ следующий - в целом, этот запрос, с точки зрения SPEL-а, написан вполне корректно. Единственный момент - работать он не будет из-за одного нюанса, который заключается в placeholder-е - в entityName.

Начнем с того, что в рамках запроса в репозитории создается EvaluationContext. Если коротко - это контекст, в рамках которого происходит evalutaion (там находятся пары ключ значение, объекты и т.д - потенциально все, на что мы ссылаемся в рамках Spel-а). Однако в нашем случае Sprign Data JDBC/R2DBC создает его лишь со значениями параметров вызываемого query метода. Иными словами, в рамках expression-а мы можем лишь резолвить ссылки на параметры query метода (updateCaptureFlag например, в нашем случае). Этот момент в целом можно расширить, если работать с EvaluationContextExtension, но конкретно сделать так, чтобы entityName резолвился в имя сущности в текущем контексте запроса не получится.

Наверняка опытные пользователи Spring Data JPA знают, что в ней достаточно давно существует специальный placeholder для того, чтобы внутри запроса по SPEL-у запросить имя сущности. Это бывает полезно, если какой-то общий запрос описывается в родительском репозитории, а в каждом наследнике этого репозитория этот placeholder в запросе будет резолвится в соответствующе конкретное имя сущности. То есть технически на самом деле это реализовать вполне реально.

С другой стороны, обратите внимание, как резолвится #entityName:

> The entityName is resolved as follows: If the domain type has set the name property on the @Entity annotation, it is used. Otherwise, the simple class-name of the domain type is used.


Фактически, для Spring Data JDBC/R2DBC имя класса бесполезно. Данные модули не работают с JPA, там нет Persistence Context-а, JPQL и пр. Поэтому изначально при проектировании этого не было заложено, но, как оказалось, потребность в этом есть.

Тогда, если сформулировать корректно, нас должна интересовать возможность иметь placeholder с указанием на актуальное имя таблицы, которое ассоциировано с тем aggregate-ом, которым мы оперируем.

Именно такой тред обсуждения мы недавно завели на GitHub: https://github.com/spring-projects/spring-data-relational/issues/1856

Поэтому, если есть интерес, можете зайти и выразить поддержку этому треду комментарием/лайком.
  • 👍 16
  • ❤ 5
  • 🔥 2
More from @spring_aio
  1. Oct 16, 2026😀 Joker 2026 && Spring АйО 🍃 Два дня в Петербурге пролетели быстрее, чем прогрев JVM. До…
  2. Oct 11, 2026🎬 Записи докладов с JPoint 2026 уже в открытом доступе JUG Ru Group выложили записи с про…
  3. Oct 9, 2026👩‍💻 Kotlin получил почти настоящие статики Начиная с Kotlin 2.5.0-Beta1 можно эксперимен…
  4. Oct 8, 2026🍃 Spring Boot ломает совместимость, G1 тормозит микросервисы, Java долго релизит фичи | S…
  5. Oct 6, 2026👩‍💻 Spring Config Import без магии У наших друзей из Axelix вышла статья о том, как Spri…
  6. Oct 5, 2026🥲 В Java 27 TLS научился переживать квантовую атаку При установке HTTPS-соединения клиент…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →