В первой статье из цикла "Как жить без IntelliJ IDEA" мы рассмотрели возможные альтернативы привычной многим IDE.
Во второй статье из цикла команда Spring АйО выяснила, какие есть альтернативы Ultimate в части поддержки Spring и насколько хорошо они справляются со своей задачей.
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤21👍10🔥4⚡2👎2
При юнит-тестировании часто требуется проверить методы, которые используют цепочки вызовов, например, в WebClient из Spring WebFlux.
⚠️ Если задача позволяет, лучше воспользоваться MockWebServer или WireMock для гибкого тестирования HTTP-клиентов. Здесь WebClient выбран лишь из-за своей наглядности и популярности.
Представим клиент, запрашивающий случайную цитату у удалённого сервиса:
public class InspirationalQuotesClient {
private final WebClient webClient;
public InspirationalQuotesClient(WebClient webClient) {
this.webClient = webClient;
}
public String fetchRandomQuote() {
try {
return this.webClient
.get()
.uri("/api/quotes")
.retrieve()
.bodyToMono(String.class)
.block();
} catch (WebClientException e) {
return "Every time a mock returns, a mock a fairy dies.";
}
}
}
Для тестирования такого клиента стандартным способом нужно замокировать каждый вызов в цепочке, чтобы избежать
NullPointerException
. Это может сделать тест слишком громоздким:
@ExtendWith(MockitoExtension.class)
class InspirationalQuotesClientTest {
@Mock private WebClient webClient;
@InjectMocks private InspirationalQuotesClient cut;
@Test
void shouldReturnInMockingHell() {
WebClient.RequestHeadersUriSpec requestHeadersUriSpec = Mockito.mock(WebClient.RequestHeadersUriSpec.class);
WebClient.ResponseSpec responseSpec = Mockito.mock(WebClient.ResponseSpec.class);
when(webClient.get()).thenReturn(requestHeadersUriSpec);
when(requestHeadersUriSpec.uri("/api/quotes")).thenReturn(requestHeadersUriSpec);
when(requestHeadersUriSpec.retrieve()).thenReturn(responseSpec);
when(responseSpec.bodyToMono(String.class)).thenReturn(Mono.just("We've escaped hell"));
String result = cut.fetchRandomQuote();
assertEquals("We've escaped hell", result);
}
}
Решение? Deep Stubs в Mockito. С ними можно упростить тест, описав всю цепочку вызовов сразу в конструкции
when
. Это значительно уменьшит количество кода:
@ExtendWith(MockitoExtension.class)
class DeepStubClientTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private WebClient webClient;
@InjectMocks private InspirationalQuotesClient cut;
@Test
void shouldReturnQuoteFromRemoteSystem() {
Mockito.when(webClient.get().uri("/api/quotes").retrieve().bodyToMono(String.class))
.thenReturn(Mono.just("Less setup hell - but not better"));
String result = cut.fetchRandomQuote();
assertEquals("Less setup hell - but not better", result);
}
}
Используя параметр
answer = Answers.RETURNS_DEEP_STUBS
, мы возвращаем заглушку для каждого метода в цепочке. Но помните, что этот подход увеличивает зависимость теста от конкретной структуры вызовов, и любые изменения в цепочке потребуют изменений в тесте.P.S. А как вы мокируете вызовы внешних API?
Ставьте 🔥 если считаете функциональность полезной.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥41👍9❤7⚡4👎4🤯2
Команда Spring АйО перевела статью об исследовании Uplevel, которое показало, что использование GitHub Copilot не улучшает производительность разработчиков, а наоборот — увеличивает количество ошибок в коде.
Разработчики стали тратить больше времени на проверку ИИ-сгенерированного кода, что снижает ожидаемую экономию времени. Хотя компании активно внедряют ИИ-инструменты, их реальная польза для повышения продуктивности остается под вопросом.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍23🔥7⚡5❤3
🧩 Исключение строк из уникальных индексов
Представьте, что вам нужно поддерживать уникальность данных, например, адресов электронной почты в таблице базы данных. Но что делать, если в таблице есть строки, помеченные как удаленные, например, с помощью дополнительного поля
Partial индекс позволяет задать условие (например,
⚠️ Советуем сделать бэкап своей БД перед выполнением запросов во избежании потери данных
Реализация
В PostgreSQL добавление уникального индекса для активных пользователей выглядит так:
В этом случае строки, у которых
Для MySQL требуется обходной путь, так как partial индексы в нем не поддерживаются. С использованием конструкции
Здесь
Как это работает?
Есть некое свойство базы данных, что значения
Преимущества частичных индексов
Кроме того, partial индексы сокращают объем данных, включаемых в индекс, тем самым экономя место и ускоряя операции поиска. PostgreSQL предлагает удобный и простой способ реализации частичных индексов, в то время как MySQL требует определенных обходных решений.
Представьте, что вам нужно поддерживать уникальность данных, например, адресов электронной почты в таблице базы данных. Но что делать, если в таблице есть строки, помеченные как удаленные, например, с помощью дополнительного поля
deleted_at
? При этом важно учитывать, что удаленные данные тоже находятся в таблице, поэтому в поле с почтой будут дубли, сделать уникальный индекс не получится. Здесь на помощь приходят partial индексы.Partial индекс позволяет задать условие (например,
WHERE deleted_at IS NULL
), чтобы включать только нужные строки и игнорировать удаленные. Эта функция доступна в PostgreSQL, где можно исключать строки с soft delete, сохраняя требуемую уникальность и оптимизируя размер индекса.Реализация
В PostgreSQL добавление уникального индекса для активных пользователей выглядит так:
CREATE UNIQUE INDEX users_email_uniq ON users (
) WHERE deleted_at IS NULL;
В этом случае строки, у которых
deleted_at
не задан, включаются в индекс, а остальные игнорируются, что делает индекс более компактным и эффективным.Для MySQL требуется обходной путь, так как partial индексы в нем не поддерживаются. С использованием конструкции
IF(deleted_at, NULL, 1)
можно эмулировать аналогичное поведение. Пример индекса:
CREATE UNIQUE INDEX users_email_uniq ON users (
email,
(IF(deleted_at, NULL, 1))
);
Здесь
NULL
используется чтобы исключить удаленные строки из индекса: строки, помеченные как удаленные, получают значение NULL
и не конфликтуют с другими значениями.Как это работает?
Есть некое свойство базы данных, что значения
NULL
не рекомендуется сравнивать ни с чем, используя ANSI SQL стандартные операторы (=, !=, <> и т.д.), т.к. сравнение приведёт к unknown
. Получится так, что два значения (example@example.com, null)
в индексе могут спокойно существовать, в то время как два значения (example@example.com, 1)
будут конфликтовать. Это свойство позволяет обойти ограничение MySQL и реализовать функциональность partial индекса. Например, строка с адресом foo@example.com
, если пользователь помечен как удаленный, получит значение индекса (foo@example.com, NULL)
и не создаст конфликта, даже если аналогичная строка существует. Такая стратегия помогает соблюсти уникальность данных, сохраняя логическую целостность таблицы и избегая лишних конфликтов в MySQL.Преимущества частичных индексов
Кроме того, partial индексы сокращают объем данных, включаемых в индекс, тем самым экономя место и ускоряя операции поиска. PostgreSQL предлагает удобный и простой способ реализации частичных индексов, в то время как MySQL требует определенных обходных решений.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍35🔥13❤6🤩1
🧠 AI-ассистент со Spring AI (Часть 2)
Не так давно мы публиковали первую часть статьи по написанию AI-ассистента со Spring AI. В продолжении статьи автор углубляется в возможности генерации с поддержкой поиска (RAG), чтобы LLM могла учесть некоторую контекстуальную информацию данных, превоначально невходившую в ее обучающую выборку.
В новом переводе от команды Spring АйО рассматривается польза Spring AI и векторной БД, благодаря которым система не просто сопоставляет ключевые слова, но и понимает смысловые запросы пользователей, делая взаимодействие с приложением еще более естественным.
📚Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/855398/
Не так давно мы публиковали первую часть статьи по написанию AI-ассистента со Spring AI. В продолжении статьи автор углубляется в возможности генерации с поддержкой поиска (RAG), чтобы LLM могла учесть некоторую контекстуальную информацию данных, превоначально невходившую в ее обучающую выборку.
В новом переводе от команды Spring АйО рассматривается польза Spring AI и векторной БД, благодаря которым система не просто сопоставляет ключевые слова, но и понимает смысловые запросы пользователей, делая взаимодействие с приложением еще более естественным.
📚Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/855398/
👍11🔥8❤4
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Сегодня не для всех weekend, но всё же #weekend_memes 😁
Please open Telegram to view this post
VIEW IN TELEGRAM
😁47🔥9👍5❤3👎1
Для тех, кто был слишком занят на неделе или просто пропустил некоторые посты, публикуем дайджест!
– Как жить без IntelliJ IDEA? Часть 2. Поддержка Spring – посмотрели на альтернативы IntelliJ IDEA Ultimate в части поддержки Spring и провели их анализ
– Создание Deep Stubs в Mockito – познакомились с мокированием целой цепочки вызовов
– Действительно ли ИИ-помощники экономят время разработчиков? – узнали, насколько полезен ИИ для разработчкиков в наши дни
– Исключение строк из уникальных индексов – рассмотрели способ включения только нужных строк при создании индекса БД
– AI-ассистент со Spring AI (Часть 2) – ознакомились со второй частью серии статей про внедрение AI-ассистента с помощью Spring AI
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥5❤4
Команда Spring АйО перевела статью, раскрывающую преимущества использования OpenTelemetry для мониторинга и трассировки Spring Boot приложений.
В статье показано, как интеграция с OpenTelemetry с использованием OTLP и других компонентов позволяет легко встроить стандартизированный сбор метрик, логов и трассировок в экосистему Spring.
📚Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/855868/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥6❤4
@ManyToMany
Использовать
CascadeType.ALL
для @ManyToMany
не рекомендуется, так как это может привести к непредсказуемым результатам во время удаления JPA сущностей. Вместо этого следует использовать CascadeType.DETACH
, CascadeType.MERGE
, CascadeType.PERSIST
и CascadeType.REFRESH
. Подробнее об этом рассказано в отдельном видео!
Please open Telegram to view this post
VIEW IN TELEGRAM
YouTube
Никогда не используй CascadeType.ALL вместе с @ManyToMany | Amplicode
#Amplicode #Spring #SpringBoot #SpringData #JPA #Hibernate #IntelliJ #Java #Kotlin
Использовать CascadeType.ALL для @ManyToMany не рекомендуется, так как это может привести к непредсказуемым результатам во время удаления JPA сущностей. Вместо этого следует…
Использовать CascadeType.ALL для @ManyToMany не рекомендуется, так как это может привести к непредсказуемым результатам во время удаления JPA сущностей. Вместо этого следует…
👍23🔥7❤4
Команда Spring АйО перевела и адаптировала доклад "Garbage Collection in Java: The progress since JDK 8" Стефана Йоханссона (Stefan Johansson) с последнего Devoxx Belgium.
Доклад получилось поделить на две статьи. В первой вы узнаете об основах работы сборки мусора в Java, различных сборщиках мусора, а также об их особенностях, плюсах и минусах.
📚Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/856468/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🔥12❤5
Forwarded from Amplicode
В следующем мажорном релизе мы планируем расширить поддержку Spring Data, реализовав поддержку Spring Data JDBC и добавив возможности, которые ранее были доступны только для Spring Data JPA.
Придерживаясь CDD
Если вы хотите:
– Принять участие в развитии продукта
– Поделиться своим опытом и рассказать о задачах и трудностях, с которыми сталкиваетесь, работая с Spring Data JDBC
то заполните короткую форму, и мы свяжемся с вами в ближайшее время!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍9❤4👌1
Liquibase объявила о включении анонимного сбора данных в версии 4.30.0 и выше для пользователей Open Source версии.
Телеметрия активируется только при запуске команд и по умолчанию отключена только для пользователей Pro версии. Компания подчеркивает, что данные обезличены и не передаются третьим лицам.
Сбор статистики позволит команде лучше понять, как используется продукт, и повысить его качество, выявляя популярные команды, частые ошибки и оптимизируя поддержку различных баз данных.
Однако, если вы не хотите делиться статистикой, то можете её выключить, используя:
* Параметр
--analytics-enabled=false
в CLI* Глобальную настройку
liquibase.analytics.enabled: false
в liquibase.properties файле* Или переменную окружения
LIQUIBASE_ANALYTICS_ENABLED=false
#breaking_news #liquibase
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯52👍21⚡8❤2🔥2
Какой системой версионирования баз данных пользуетесь в продакшене?
Anonymous Poll
24%
Flyway
64%
Liquibase
3%
Пользуюсь собственным велосипедом
9%
Не пользуюсь
1%
Другое, напишу в комментарии
👍8❤4🔥4
Для тех, кто был слишком занят на неделе или просто пропустил некоторые посты, публикуем дайджест!
– Давайте использовать OpenTelemetry со Spring! – показали преимущества использования OpenTelemetry для мониторинга и трассировки Spring Boot приложений
– CascadeType.ALL и @ManyToMany – представили видео, в котором показали, почему не рекомендуется использовать CascadeType.ALL для
@ManyToMany
– Сборка мусора в Java. Часть №1. Обзор сборщиков мусора и их различий – узнали основы работы сборки мусора в Java, а также особенности различных сборщиков мусора
– Liquibase теперь собирает статистику использования – рассказали о том, что начиная с версии Liquibase 4.30.0 и выше для пользователей Open Source версии сбор аннонимизированной статистики будет включен по умолчанию
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍7❤5👌2
Команда Spring АйО перевела статью, в которой Steve Reisenberg рассказал о множестве полезных улучшений для работы с OAuth2 в Security 6.4.
Прочитав статью вы узнаете, как отправлять запросы к защищенным ресурсам без дополнительных зависимостей, а также переопределять параметры в запросах токенов доступа для реализации сложных сценариев.
📚Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/857664/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥25👍19❤7