Spring АйО
7.68K subscribers
262 photos
158 videos
338 links
Русскоязычное сообщество Spring-разработчиков.

Habr: bit.ly/433IK46
YouTube: bit.ly/4h3Ci0x
VK: bit.ly/4hF0OG8
Rutube: bit.ly/4b4UeX6
Яндекс Музыка: bit.ly/3EIizWy

Канал для общения: @spring_aio_chat
Download Telegram
#ВопросЭксперту: Spring Data R2DBC. Что не так с реактивными ORM?

В новом посте из цикла "#ВопросЭксперту" Михаил Поливаха – эксперт сообщества Spring АйО, ответил на мучающий многих вопрос и рассказал про нюансы Spring Data R2DBC.

–––

Работать с RDBMS в реактивных приложениях бывает сложно, и на то есть реальные причины. Тут совершенно неважно, написаны эти приложения с использованием RXJava или Project Reactor, есть некоторые проблемы на стыке концепций. Но надо понимать, что иногда с этим добром приходится работать, поэтому предлагаю взглянуть на пример ниже (полный код можно увидеть в моем playground репо на GitHub'е):


@Table("orders")
public class Order {

@Id
@EqualsAndHashCode.Include
private Long id;
private String status;
@MappedCollection(keyColumn = "order_id", idColumn = "order_id")
private List<OrderItem> orderItems;
}

@Table("order_item")
public class OrderItem {

@Id
@EqualsAndHashCode.Include
private Long id;
private String name;
private double price;
}

public interface OrderRepository extends ReactiveCrudRepository<Order, Long> { }

// INSERT INTO orders(id, "status") VALUES(1, 'NEW');
// INSERT INTO order_item("name", "order_id") VALUES('Lego', 1);
class OrderRepositoryTest extends AbstractPostgreSQLIntegrationTest {
@Test
void testR2dbcAggregateLoading() {
StepVerifier
.create(orderRepository.findById(1L))
.expectNextMatches(order -> {
System.out.println(order);
return order.getOrderItems().size() == 2 && order.getStatus().equals("NEW");
})
.expectComplete()
.verify();
}
}


А теперь ответьте на вопрос: "Пройдет ли тест успешно?". Я специально сделал пример довольно простым, убрал какие-то доп. компоненты/настройки.

На самом деле проблема в том, что у нас не подгрузилось One-To-Many отношение. Казалось бы, в концепцию DDD оно нормально ложится, и в Spring Data JDBC оно работает нормально. В таком случае вопрос: "Что пошло не так и почему?". Наверное, многим будет интересно узнать, что же случилось?

Ответ я разобью на пункты:

1. Это не баг, поддержки любого рода relation'ов в Spring Data R2DBC сейчас нет.
2. Конкретно в текущем случае, который мы рассматриваем, сделать поддержку relation'ов можно.
3. Почему поддержки relation'ов нет сейчас? TL;DR: потому что отсутствует нормальный способ реализовать поддержку relation'ов в общем случае(!) для Aggregates с учетом парадигмы реактивного программирования.

Хочу заметить, что, в целом, реализовать поддержку relation'ов можно, но будут свои нюансы и вытекающие проблемы. Поскольку эта тема очень большая, детали того, почему же так, что делать, и какие планы работы с этим, я поясню на своем докладе на Joker.
Please open Telegram to view this post
VIEW IN TELEGRAM
⚠️ Критическая уязвимость с оценкой CVSS 9.9 обнаружена в системах GNU/Linux

Недавно была обнаружена критическая уязвимость, угрожающая всем системам GNU/Linux, которая позволяет выполнять код удаленно без аутентификации. Проблема затронула такие компании, как Canonical и Red Hat, и получила оценку 9.9 из 10 по шкале CVSS, что подтверждает её серьёзность. Пока патч не выпущен, разработчики и пользователи находятся в состоянии неопределенности, опасаясь возможных последствий.

В новом переводе от команды Spring АйО приводятся подробности о сроках раскрытия деталей уязвимости и предлагаются временные меры для защиты систем.

📚Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/846498/
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🗓 Еженедельный дайджест №15

Для тех, кто был слишком занят на неделе или просто пропустил некоторые посты, публикуем дайджест!

Взлом JVM-приложения с помощью отладчика IntelliJ IDEAизменили функциональность приложения, при этом не притронулись к исходному коду

Hibernate 7.0 уже близко!поделились новостью про грядущее обновление Hibernate

#ВопросЭксперту: Spring Data R2DBC. Что не так с реактивными ORM?посмотрели на интересный кейс из реактивного стека от эксперта сообщества

Критическая уязвимость с оценкой CVSS 9.9 обнаружена в системах GNU/Linuxне оставили без внимания недавно обнаруженную проблему в GNU/Linux, а также способы ее обхода

Если бы программисты строили дома #old_but_goldпоностальгировали и посмеялись с рассказа с аналогией между строителями и программистами

😌 @spring_aio
Please open Telegram to view this post
VIEW IN TELEGRAM
📏 Почему нет достойных форматтеров кода для Java?

Форматирование кода в Java всегда было темой обсуждения среди разработчиков. Многочисленные инструменты предлагают свои решения, но ни один из них не кажется идеальным. Так, возникает вопрос: есть ли форматтер, который действительно отвечает всем нашим требованиям?

В новом переводе от команды Spring АйО рассмотрены популярные инструменты, их плюсы и минусы, а также рассуждения на тему: может ли Java-экосистема предложить достойный форматтер?

📚Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/846278/
🔧 Целостность данных при использовании JSON-колонок в базе данных

Всё чаще можно заметить хранение данных в формате JSON в реляционных базах данных. Использование JSON позволяет упростить структуру таблиц, заменяя сложные отношения между ними. Однако такое упрощение может привести к неожиданным проблемам с целостностью данных.

Если мы храним данные в JSON-колонках без строгой валидации, возникает риск получить неструктурированные данные или ошибки в ожидаемом нами формате. Например, ожидаемый массив строк может неожиданно содержать числа или другие типы данных. Из-за чего мы можем столкнуться с проблемами при обработке данных в приложении.

В MySQL валидировать содержимое JSON-колонок можно прямо "из коробки", а для PostgreSQL есть специальное расширение. Ниже рассмотрим пример использования этого расширения.

Представьте, что у вас есть таблица products с колонкой attributes, где вы храните дополнительные характеристики продукта в формате JSON.


CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
price DECIMAL(10, 2) NOT NULL,
attributes JSON NOT NULL DEFAULT '{}'
);


Мы ожидаем, что поле tags внутри этого JSON будет массивом строк. Однако без строгой проверки на уровне базы данных нет гарантии, что кто-то не запишет туда числа, объекты или вообще что-то неподходящее.

Чтобы сохранить гибкость JSON и одновременно обеспечить строгую структуру данных, можно использовать валидацию JSON-схемы на уровне базы данных. Для этого нужно добавить constraint, который автоматически проверит соответствие содержимого JSON определенной схеме при каждой операции вставки или обновления.

Пример для PostgreSQL:

ALTER TABLE products ADD CONSTRAINT data_is_valid CHECK(
validate_json_schema(
'{
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": { "type": "string" }
}
},
"additionalProperties": false
}',
attributes
)
);


Теперь, попытка вставить данные с невалидным значение для tags приведёт к ошибке:

INSERT INTO products (..., attributes) VALUES
(..., '{}'), -- Пустой объект, допускается
(..., '{"tags": []}'), -- Пустой массив строк
(..., '{"tags": ["test"]}'); -- Массив со строкой
-- Результат: Операция успешна

INSERT INTO products (..., attributes) VALUES
(..., '{"tags": [2]}'); -- Массив с числом вместо строки
-- Ошибка: Нарушен constraint


#DatabaseTip #SQL #JSONSchema
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡️ Стала известна дата релиза Spring Framework 7.0!

Команда Spring АйО перевела письмо Юргена Хёллера Spring-сообществу.

Тезисно:

☝️ Первый Spring Framework 7.0 milestone ожидается в начале 2025 года
✍️ Spring Boot 3.5 будет базироваться на Spring Framework 6.2.x.
🆕 Spring Boot 4.0 будет основан на Spring Framework 7.0 GA

📚 Прочитать письмо Юргена целиком можно на Хабре: https://habr.com/ru/companies/spring_aio/news/847460/
Please open Telegram to view this post
VIEW IN TELEGRAM
🧠 AI-ассистент со Spring AI (Часть 1)

В новом переводе от команды Spring АйО показан процесс интеграции AI в немалоизвестное приложение Spring Petclinic.

В статье автор пошагово делится своим опытом внедрения Spring AI, чтобы сделать приложение более интерактивным.

📚Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/848016/
🪲 JUnit 4 и JUnit 5 – как избежать ошибок?

Довольно распространённой ошибкой при тестировании приложений на Java, приводящей к неожиданным результатам тестов, является совместное использование JUnit 4 и JUnit 5 в одном и том же тестовом классе.

Не смотря на то, что первая версия JUnit 5 вышла в 2017 году, до сих пор существуют проекты, которые используют его предшественника — и это вполне нормально.

JUnit 5 поддерживает запуск тестов JUnit 4 вместе с тестами JUnit 5 благодаря JUnit Vintage Engine. Благодаря этой фиче мы можем постепенно мигрировать с JUnit 4 на JUnit 5.

Именно JUnit Vintage Engine делает возможным выполнение тестов, написанных на JUnit 4, в среде JUnit 5. Однако использование аннотаций и API JUnit 4 и JUnit 5 (точнее, JUnit Jupiter) одновременно в одном тестовом классе не работает. Нам нужно выбирать что-то одно.

Мы можем использовать как тесты JUnit 4, так и тесты JUnit 5 в одном проекте, но каждый отдельный тестовый класс должен использовать либо JUnit 4, либо JUnit 5.

Например, тест MyOrderTest может быть написан на JUnit 4, а MyPricingServiceTest — на JUnit 5, и это абсолютно нормально.

✍️ Хорошая статья про миграцию с JUnit 4 на JUnit 5 в блоге Oracle (en): https://blogs.oracle.com/javamagazine/post/migrating-from-junit-4-to-junit-5-important-differences-and-benefits
Please open Telegram to view this post
VIEW IN TELEGRAM
🗓 Еженедельный дайджест №16

Для тех, кто был слишком занят на неделе или просто пропустил некоторые посты, публикуем дайджест!

Почему нет достойных форматтеров кода для Java? – выяснили, какие есть инструменты для форматирования java-кода, а также узнали, какие у них преимущества и недостатки

Целостность данных при использовании JSON-колонок в базе данных – разрабрались с тем, как задавать ограничения для JSON-колонок на уровне базы данных

Стала известна дата релиза Spring Framework 7.0 – сообщили о ближайшем релизе Spring Framework 6.2, а также узнали, когда стоит ждать седьмую версию нашего любимого фреймворка

AI-ассистент со Spring AI (Часть 1) – узнали, как можно использовать Spring AI в существующем приложении благодаря очень подробному step-by-step туториалу

JUnit 4 и JUnit 5 – как избежать ошибок? – разобрали одну из самых частых проблем, с которой можно столкнуться при миграции с одной версии JUnit на другую

😌 @spring_aio
Please open Telegram to view this post
VIEW IN TELEGRAM
😀 Spring АйО х Joker

Друзья, с радостью сообщаем о том, что команда Spring АйО примет участие в ближайшей конференции JUG Ru Group – Joker 2024.

Мы станем партнёрами лаунж-зоны, где вы сможете пообщаться с нашими экспертами, задать интересующие вас вопросы и обсудить новости из мира Spring'а в неформальной обстановке.

Приходите, будем рады видеть каждого из вас 💚
Please open Telegram to view this post
VIEW IN TELEGRAM
✍️ Туториал по Spring Data Envers для начинающих

Команда Spring АйО перевела статью, которая отлично подойдёт тем, кто ещё не знаком со Spring Data Envers. В статье на простых примерах объясняется, как отслеживать изменения данных в приложении, используя этот инструмент.

📚 Подробнее читайте на Хабре: https://habr.com/ru/companies/spring_aio/articles/849086/
Please open Telegram to view this post
VIEW IN TELEGRAM
#анонсы

Бесплатные доклады для всех в Community Day

Joker 2024 стартует 9 октября в онлайне. В этот день часть докладов любой сможет посмотреть бесплатно — достаточно зарегистрироваться.

Мы называем это Community Day. Так мы делимся частью конференции со всеми желающими: новые участники смогут оценить формат и контент, а те, кто давно не участвовал в Joker, — освежить воспоминания и вновь почувствовать себя частью сообщества.

Что входит в программу Community Day:

→ Александр Белов — Jimmer ORM. Сравнение с JPA
→ Вадим Бубликов — Разрабатываем модульный бэкенд, используя стандартные возможности Spring Boot
→ Андрей Чухлебов — GraalVM Native Image: как правильно подойти к переходу на Native на примере тонкого клиента Ignite
→ Феликс Десятириков — Java с правильной ориентацией: DOP
→ Обсуждение «Java 23. Горячие JEP'ы»

Все эти выступления — для вас! Зарегистрируйтесь до 9 октября включительно и подключайтесь.
🆕 Вышел Spring AI 1.0.0 M3

Spring выпустил Spring AI 1.0.0 M3, который принес множество значительных улучшений и новых возможностей в разработку AI-приложений.

В новом переводе от команды Spring АйО рассказывается про улучшения, связанные с observability, совершенствование системы advisor`ов и оптимизацию работы с функциями и embedding моделями.

📚 Читать на Хабр: https://habr.com/ru/companies/spring_aio/articles/849752/
Please open Telegram to view this post
VIEW IN TELEGRAM
⭐️ Лучший способ создания нескольких окружений для Spring Boot приложения

Недавно мы вкратце рассказывали, какие есть способы управления окружением с использованием Docker Compose.

В новой статье от команды Amplicode более подробно рассказывается про каждый из способов, их преимущества и недостатки, а также поддержку со стороны инструментов разработки.

📚 Читать на Хабре: https://habr.com/ru/companies/haulmont/articles/848696/
Please open Telegram to view this post
VIEW IN TELEGRAM
🎲 Рандомный порт для Spring Boot приложения

Чтобы запустить Spring Boot приложение на любом свободном порту достаточно указать в application.properties/yaml файле server.port=0. В этом случае Spring Boot автоматически подберёт свободный порт, и постарается избежать конфликта с другими приложениями.

Но что если хочется выбрать свободный порт из определенного диапазона? В таком случае можно использовать выражение ${random.int(min,max)}. Например, для выбора порта в пределах от 8000 до 8100 свойство будет выглядеть так:

server.port=${random.int(8000,8100)}

За случайный выбор значений отвечает класс RandomValuePropertySource.

#SpringTips #Simple
🗓 Еженедельный дайджест №17

Для тех, кто был слишком занят на неделе или просто пропустил некоторые посты, публикуем дайджест!

Spring АйО х Joker сообщили об участии команды Spring АйО в Joker 2024

Туториал по Spring Data Envers для начинающихразобрались, как отслеживать изменения данных в приложении, используя Spring Data Envers

Вышел Spring AI 1.0.0 M3сообщили о релизе Spring AI 1.0.0 M3, который содержит достаточно большое кол-во улучшений

Лучший способ создания нескольких окружений для Spring Boot приложенияананосировали статью про имеющиеся способы управления окружением с использованием Docker Compose в деталях

Рандомный порт для Spring Boot приложениярассказали, как можно зарандомить порт или выбрать порт рандомно из диапазона для Spring Boot приложения

😌 @spring_aio
Please open Telegram to view this post
VIEW IN TELEGRAM
Чем заняться в перерывах между докладами?

Познакомиться с коллегами по цеху и обсудить с ними актуальные вопросы из разных сфер: безопасности, паттернов проектирования, тестирования, управления данными и будущего технологий. Всё это можно сделать на Random coffee от Spring АйО.

Как проходит активность?

В 30-минутных перерывах между докладами приходите к столам возле Дискуссионки 3. На них будут лежать карточки с вопросами для обсуждения. За каждым столиком будет по два человека, которые обсудят вопрос, а спустя 5 минут поменяются «парами», чтобы подискутировать на новые темы. 

В одном раунде Random coffee участвуют 10 человек, включая эксперта. Полное расписание с темами и экспертами можно посмотреть по ссылке.
😀 Joker 2024 x День №1

Вот и прошел первый день главного события этой осени для Java разработчиков - Joker 2024!

💚 Дружественная атмосфера и куча крутых докладов, в том числе по нашей любимой теме - Spring Framework
🥰 Отлично проведённое время на Random Coffee с экспертами сообщества и его участниками
😡 Бесконечное количество интересных обсуждений на тему архитектуры приложений, безопасности приложений, тестирования и многого другого

⚠️ Кто не успел дойти сегодня – приходите завтра!

P.S. Увидимся на After Party!
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM