Один из немногих разработчиков на ютубе, который так подробно и продвинуто обьясняет разработку приложений на спринг и все что с ним связано. У других максимум найдешь создание простых CRUD приложений, а тут на канале обхват тем и фич коллосальный. Очень много полезной инфы узнал из роликов!
Отличные уроки! Для всех кто пользуется Spring Boot 3.3.2: по мимо тех зависимостей, которые добавил Александр, нужно также добавлять flyway-database-postgresql для работы с postgresql из flyway. Версию можно неуказывать Dependecy manager сам разберется
Потрясающий универсальный подарок на 8 марта - годный контент от сельского джависта :) Твоих любимых и дорогих людей с праздником, Саня! Добра, любви, тепла и всего самого хорошего!
Спасибо за урок! Таймкоды, вдруг кому-то полезно будет: 00:00 - Об основных понятиях урока(JPA, Hibernate, Spring Data JPA, Flyway) 03:54 - Подключение зависимостей 04:36 - Описание структуры БД 07:42 - Маппинг сущности в коде на сущность в БД (@Entity) 14:08 - Создание @Repository 19:00 - Настройка подключения к БД 23:00 - Баг-фикс изменения товара(update в БД) 26:30 - Вводная информация по созданию пользовательских запросов к БД 28:00 - Cоздание пользовательского запроса к БД по названию метода в репозитории 35:45 - Создание пользовательского запроса к БД с использованием JPQL(@Query, @Param) 38:50 - Создание пользовательского нативного запроса к БД (nativeQuery = true) 39:50 - Создание пользовательского именованного запроса (@NamedQueries) 44:00 - Добавление возможности фильтрации списка товаров на UI 48:25 - Подведение итогов
Спасибо, Александр! Очень крутой цикл видео! И уровень разработки крутой. Отдельное спасибо за внимание к каждому комментарию, это очень приятно) Вы очень хорошее дело делаете! При просмотре не понял пару деталей: 1) зачем везде this? он вроде бесполезен в нормальном коде, где имена полей никогда не совпадают с именем аргумента 2) зачем такое именование полей БД? это же боль для стороннего программиста, тестировщика, DBA, аналитика 3) зачем примитивы в полях и аргументах? Это будущие NPE при взаимодействии слоев, сервисов, десериализации и вдобавок дефолтное значение в отличии от ссылки, несущее кучу неочевидных багов потенциально 4) зачем возвращать из репозитория Iterable? не лучше ли наследовать более подходящий интерфейс вместо Crud (JpaRepository например) 5) почему не использовались read only транзакции над методами чтения? будет лишний dirty checking при каждой выборке, а это создание, копирование и сравнение массивов всех полей всех сущностей каждый раз под капотом 6) операция patch тут разве правильно реализована? получается в реальности put (осуществляется замена всех полей сущности, а патч подразумевает только модификацию тех, которые были заданы), более того такая реализация неконсистентна со структурой сущности (структура изменится, а патч нет - придется руками менять при каждой модификации структуры) 7) почему обработка ошибок рест клиента через try-catch, ProblemDetail и cast к списку? выглядит как костыль. Тут разве не просится получение результата в виде Either объекта и дальнейшая обработка? использование в коде CRUD app явного cast, instanceof или reflection - плохой звоночек. Да и в целом не понятно почему не использовался HTTP Interfaces, там отличная поддержка для RestClient в новых версиях спринга 8) почему для Rest service не использовался @RestControllerAdvice? 9) почему вместо возврата List не возвращается Page/Slice? это и обертка над списком значений с метаданными и сразу готовя пагинация с сортировкой 10) почему не отключен open-in-view? мы же не дергаем прокси из контроллеров, но зато имеем из-за этого открытую сессию хибера на уровне контроллера, а не там, где она реально нужна. Стандартный антипаттерн вроде
Ох, сколько вопросов) 1. На мой взгляд упрощает читаемость кода, сразу понимаешь, где обращение к членам класса, а где - к локальным переменным. Но, возможно, это сила привычки 2. Чтобы по названию можно было определить, какую роль выполняет тот или иной элемент. Снова привычка 3. Ни разу не сталкивался с какими-либо проблемами из-за использования примитивов, стараюсь использовать именно примитивы там, где это возможно 4. Iterable используется, потому что возвращается по умолчанию, ну и от него требуется только возможность использования итератора. Не вижу смысла в использовании более специфичного JpaRepository в ситуациях, когда хватает функциональности более общего CrudRepository 5. Тут да, забыл, банально за всем не уследишь 6. В том-то и дело, что PUT подразумевает полную замену всех свойств сущности (id, title, details), иными словами замену всей сущности, а в запросе фигурируют только свойства, которые мы можем изменить (title, details). Именно поэтому PATCH, а не PUT. PUT замещает объект, а PATCH - изменяет свойства объекта. Для соблюдения консистентности можно воспользоваться версионированием API, но это я буду рассказывать вообще в отдельном ролике. 7. try/catch - вполне стандартный подход, ProblemDetail - опять же стандартный способ описания HTTP-ошибки в REST API (да, в черновике IETF, но лучше, чем что-то самописное), а каст нужен, т.к. список ошибок передаётся одним из свойств свободной формы. Да, можно было на стороне REST API сформировать строку ошибки и передать её в details. Использование HTTP-интерфейсов - это уже углубление, которое лучше разобрать в отдельном ролике. 8. Потому что достаточно и обычного @ControllerAdvice 9. Опять же углубление, про которое нужно отдельно рассказывать, у меня и так ролики получаются большие, а если раскрывать каждую деталь, то они будут ну очень большими 10. Банально потому что забыл, т.к. на практике давно MVC-приложений не пишу
@@shurik_codes Большое спасибо за такой детальный развернутый ответ!)) Ролики у Вас совсем не большие, имхо, максимально лаконично все уложено, даже чрезмерно где-то, а по такой теме 2-3 часа видео - это норма) тот кто смотрит ролик длиной 1ч, тот с удовольствием посмотрит и трехчасовой и пяти, будьте уверены)) Недаром на UA-cam при фильтре определяющие значения 4 мин и 20 мин, они проводили исследования по этому вопросу и 20 мин являются чертой, выше которой человек смотрит практически любой длины видео, а тот кто не смотрит длинные, тот 20 минут не осиливает в свою очередь чаще всего, самая ленивая группа смотрит менее 4 мин всегда (но это касается не только лени, но и типа видео, разумеется)
Еще важно отметить, что валидация должна делаться в dto, а в entity приводятся только наборы полей, которые мапятся на поля таблиц БД. Скорее всего для экономии времени в проекте это совмещено, но это плохая практика на реальном проекте, потому что приводит к спагетти-коду. Когда идет подключение к БД, в настройках конфигурации должен быть указан профиль, иначе ничего не запустится. Best practice - отдельный ямл без постфиксов, где указывается активный профиль, и ямл под каждое отдельное окружение (это будет работать, потому что специализированные ямлы будут наследовать все данные из дефолтного ямла).
Чётко Планируется ли ролик по интеграционному тестированию этого приложения? По юнит тестам много инфы, а вот хороший пример настойки тестконтейнеров и тестирования бд/брокеров сообщений найти не удалось
Спасибо за видео. А я думал, что без реализации репозитория в классе, нужно @Repository ставить над интерфейсов, оказалось оно там и не нужно. Этот урок оказался коротким, но даже тут узнал что-то новое и крайне полезное, но без заранее подготовленных знаний по работе с БД у новичков будет темный лес)) Но иначе бы пришлось делать урок на пару часов, например, нет ни слова про отношения OneToMany и т.д.
Если я правильно понял о чем речь, то если не ставить аннотацию то не будет в логах специфичные ошибки показывать для бд. А так можно хоть @Component поставить
Спасибо за очень информативные видео. Может сделаете видео как правильно загружать, хранить и получать файлы с сервера, например картинки через контролеры, тоесть чтоб Product был еще и с картинкой )
Все прекрасно у Вас получается! Спасибо ! Очень доходчиво. Но будет ли Join в запросах хотя бы один-ко многим из двух таблиц? И как сериализовать чтобы подучился Json с вложеными блоками в таком случае? И вообще как работает сериализация при запрсах nbgf JOIN итп. Оочень нужно...
Александр, спасибо вам за эти замечательные обучающие ролики, все лаконично и на современном стэке! Разрешите задать вопрос, в чем смысл в классах обращаться к инжектируемым сущностям через this, без него ведь то же все будет корректно работать? Вероятно, это просто ваш стиль программирования направленный на поддержание кода в более структурированном и понятном виде))
Привет! Спасибо за твои видосы :) Хочу предложить тему для ролика: OTP (one time password) в spring security. По ней достаточно мало материала, а тот что есть - сделан очень коряво. Я сейчас сам начал пытаться реализовать данную тему, и понял, что это прям очень сложно выглядит (приходится переопределять usernamepasswordauthenticationfilter и делать прочие шаманства, что реализовать безопасный ввод кода). Очень бы хотелось увидеть твою реализацию по данной теме. Надеюсь - заинтересует, спасибо!
Александр, здравствуйте, огромное спасибо за ролики! А вы не планируете в других роликах, вне цикла, рассмотрение фреймворка Camel? И еще вопрос, а вы использовали restclient, а feignclient в своей работе используете?
Привет. У меня возник вопрос по поводу баз данных. Что делать, если у нас есть несколько сущностей и они связаны между собой. Как сохранить эту связь между сервисами? Нужно создавать какой-то отдельный модуль для сущностей и настраивать там связи? Или просто передавать dto и как-бы не испольщовать аннотаци onetomany и т.д. ? Или в каждый сервис копировать сущности ? просто если нам не нужны все сущности в сервисе ? Вот например мы создаем сервис по формированию заказа, по идеи нам нужен товар, продавец и покупатель, но у покурателя наримеи есть еще поставщики, которые не нужны нам в этом сервисе. Как поступать в таких моментах ?
Использование названий методов - для самых простых вопросов, EntityManager - для самых сложных. В целом никто не запрещает для всех случаев использовать EntityManager. Тут характеристика лучше-хуже не совсем уместна)
пропустил момент почему используется не паблик схема в преимущества использование не по дефолту и в чем преимущества использования префиксов "t_table _name" и с колонками тоже, это сделано намеренно в целях наглядности, наверное
Интересно как реализован save при завешении транзакции, ведь как то где то должен отслеживаться список измененных объектов? Получается есть какой то менеджер объектов которых сохраняет ссылку на объект/егопрокси пока не произойдет завершение транзакции? Интересно как это в хибере и не только реализуется под капотом.
Cущесвует несколько уровней кэширования в Hibernate: - на уровне сессии(по умолчанию активно) - на уровне фабрики сессий(по умолчанию не активно) Кэширование на уровне сессии представляет из себя поле в объекте Session, являющееся объектом PersistenceContext, содержащее, строго говоря, набор мап и метаданных с информацией об активных entity. Основная из этих мап - поле HashMap entitiesByKey, где K - id сущности(объект EntityKey, содержащий id сущности, хэш и т.н. EntityPersister(специфичный преобразователь ORM, закрепленный за текущим типом entity)), а V - сама сущность. Т.о. при попытке получить сущность Hibernate сперва получает ее из этой мапы, а если в ней нет, то получает из DB, после чего добавляет в мапу, чтобы при следующем поиске не идти снова в DB. В другой мапе также инициализируется массив всех полей persistent объекта (добавленного в кэш), а при завершении транзакции происходит сравнение значений из этого массива с текущими значениями и если они не совпадают, то сессия считается "грязной"(были изменения объекта в ее ходе) и происходит дополнительный апдейт в БД. Этот механизм (dirty-checking'а, а не самого кэша) можно отключить, если использовать транзакцию с флагом read-only, тогда все апдейты нужно делать явно.
@@shurik_codes если имеется ввиду доп настройки в yaml/property или compose то таковых нет, postgre в Docker запустился нормально. я просто запустил ваш проект с git. Docker только вчера поставил, до этого в глаза его не видел
а каким образом определяется url для базы данных? (jdbc:postgresql://localhost:5432/catalogue). Просто определенный шаблон, который начинается с "jdbc:postgresql", а хост можно указать любой? И "/catalogue" здесь указывается название схемы?
Один из немногих разработчиков на ютубе, который так подробно и продвинуто обьясняет разработку приложений на спринг и все что с ним связано. У других максимум найдешь создание простых CRUD приложений, а тут на канале обхват тем и фич коллосальный. Очень много полезной инфы узнал из роликов!
Отличные уроки! Для всех кто пользуется Spring Boot 3.3.2: по мимо тех зависимостей, которые добавил Александр, нужно также добавлять flyway-database-postgresql для работы с postgresql из flyway. Версию можно неуказывать Dependecy manager сам разберется
Потрясающий универсальный подарок на 8 марта - годный контент от сельского джависта :)
Твоих любимых и дорогих людей с праздником, Саня!
Добра, любви, тепла и всего самого хорошего!
Спасибо за урок!
Таймкоды, вдруг кому-то полезно будет:
00:00 - Об основных понятиях урока(JPA, Hibernate, Spring Data JPA, Flyway)
03:54 - Подключение зависимостей
04:36 - Описание структуры БД
07:42 - Маппинг сущности в коде на сущность в БД (@Entity)
14:08 - Создание @Repository
19:00 - Настройка подключения к БД
23:00 - Баг-фикс изменения товара(update в БД)
26:30 - Вводная информация по созданию пользовательских запросов к БД
28:00 - Cоздание пользовательского запроса к БД по названию метода в репозитории
35:45 - Создание пользовательского запроса к БД с использованием JPQL(@Query, @Param)
38:50 - Создание пользовательского нативного запроса к БД (nativeQuery = true)
39:50 - Создание пользовательского именованного запроса (@NamedQueries)
44:00 - Добавление возможности фильтрации списка товаров на UI
48:25 - Подведение итогов
спасибо
Отлично. Смотрю дальше.
Огонь, едем дальше!
Счастья и здоровья тебе,добрый человек!
Это очень качественный и от настоящего профессионала, контент!
Всё по полочкам разложил, спасибо.
Спасибо ОГРОМЕННОЕ.
Супер! Спасибо) 🎉
Спасибо, Александр! Очень крутой цикл видео! И уровень разработки крутой. Отдельное спасибо за внимание к каждому комментарию, это очень приятно) Вы очень хорошее дело делаете!
При просмотре не понял пару деталей:
1) зачем везде this? он вроде бесполезен в нормальном коде, где имена полей никогда не совпадают с именем аргумента
2) зачем такое именование полей БД? это же боль для стороннего программиста, тестировщика, DBA, аналитика
3) зачем примитивы в полях и аргументах? Это будущие NPE при взаимодействии слоев, сервисов, десериализации и вдобавок дефолтное значение в отличии от ссылки, несущее кучу неочевидных багов потенциально
4) зачем возвращать из репозитория Iterable? не лучше ли наследовать более подходящий интерфейс вместо Crud (JpaRepository например)
5) почему не использовались read only транзакции над методами чтения? будет лишний dirty checking при каждой выборке, а это создание, копирование и сравнение массивов всех полей всех сущностей каждый раз под капотом
6) операция patch тут разве правильно реализована? получается в реальности put (осуществляется замена всех полей сущности, а патч подразумевает только модификацию тех, которые были заданы), более того такая реализация неконсистентна со структурой сущности (структура изменится, а патч нет - придется руками менять при каждой модификации структуры)
7) почему обработка ошибок рест клиента через try-catch, ProblemDetail и cast к списку? выглядит как костыль. Тут разве не просится получение результата в виде Either объекта и дальнейшая обработка? использование в коде CRUD app явного cast, instanceof или reflection - плохой звоночек. Да и в целом не понятно почему не использовался HTTP Interfaces, там отличная поддержка для RestClient в новых версиях спринга
8) почему для Rest service не использовался @RestControllerAdvice?
9) почему вместо возврата List не возвращается Page/Slice? это и обертка над списком значений с метаданными и сразу готовя пагинация с сортировкой
10) почему не отключен open-in-view? мы же не дергаем прокси из контроллеров, но зато имеем из-за этого открытую сессию хибера на уровне контроллера, а не там, где она реально нужна. Стандартный антипаттерн вроде
Ох, сколько вопросов)
1. На мой взгляд упрощает читаемость кода, сразу понимаешь, где обращение к членам класса, а где - к локальным переменным. Но, возможно, это сила привычки
2. Чтобы по названию можно было определить, какую роль выполняет тот или иной элемент. Снова привычка
3. Ни разу не сталкивался с какими-либо проблемами из-за использования примитивов, стараюсь использовать именно примитивы там, где это возможно
4. Iterable используется, потому что возвращается по умолчанию, ну и от него требуется только возможность использования итератора. Не вижу смысла в использовании более специфичного JpaRepository в ситуациях, когда хватает функциональности более общего CrudRepository
5. Тут да, забыл, банально за всем не уследишь
6. В том-то и дело, что PUT подразумевает полную замену всех свойств сущности (id, title, details), иными словами замену всей сущности, а в запросе фигурируют только свойства, которые мы можем изменить (title, details). Именно поэтому PATCH, а не PUT. PUT замещает объект, а PATCH - изменяет свойства объекта. Для соблюдения консистентности можно воспользоваться версионированием API, но это я буду рассказывать вообще в отдельном ролике.
7. try/catch - вполне стандартный подход, ProblemDetail - опять же стандартный способ описания HTTP-ошибки в REST API (да, в черновике IETF, но лучше, чем что-то самописное), а каст нужен, т.к. список ошибок передаётся одним из свойств свободной формы. Да, можно было на стороне REST API сформировать строку ошибки и передать её в details. Использование HTTP-интерфейсов - это уже углубление, которое лучше разобрать в отдельном ролике.
8. Потому что достаточно и обычного @ControllerAdvice
9. Опять же углубление, про которое нужно отдельно рассказывать, у меня и так ролики получаются большие, а если раскрывать каждую деталь, то они будут ну очень большими
10. Банально потому что забыл, т.к. на практике давно MVC-приложений не пишу
@@shurik_codes Большое спасибо за такой детальный развернутый ответ!)) Ролики у Вас совсем не большие, имхо, максимально лаконично все уложено, даже чрезмерно где-то, а по такой теме 2-3 часа видео - это норма) тот кто смотрит ролик длиной 1ч, тот с удовольствием посмотрит и трехчасовой и пяти, будьте уверены)) Недаром на UA-cam при фильтре определяющие значения 4 мин и 20 мин, они проводили исследования по этому вопросу и 20 мин являются чертой, выше которой человек смотрит практически любой длины видео, а тот кто не смотрит длинные, тот 20 минут не осиливает в свою очередь чаще всего, самая ленивая группа смотрит менее 4 мин всегда (но это касается не только лени, но и типа видео, разумеется)
Очень понятно и при этом хорошо раскрывается тема. Спасибо!
Лайк циклу, лайк ролику, лайк автору =)
Спасибо за урок . Лайк / подписка 🙌
Отличный материал!!!
Еще важно отметить, что валидация должна делаться в dto, а в entity приводятся только наборы полей, которые мапятся на поля таблиц БД. Скорее всего для экономии времени в проекте это совмещено, но это плохая практика на реальном проекте, потому что приводит к спагетти-коду.
Когда идет подключение к БД, в настройках конфигурации должен быть указан профиль, иначе ничего не запустится. Best practice - отдельный ямл без постфиксов, где указывается активный профиль, и ямл под каждое отдельное окружение (это будет работать, потому что специализированные ямлы будут наследовать все данные из дефолтного ямла).
спасибо)!
Саша, спасибо за контент
Подскажи, когда планируешь и планируешь ли снимать создание рест приложений с использованием webflux?
В 7 ролике цикла будет
Спасибо!
крутой ролик получился
Чётко
Планируется ли ролик по интеграционному тестированию этого приложения?
По юнит тестам много инфы, а вот хороший пример настойки тестконтейнеров и тестирования бд/брокеров сообщений найти не удалось
В 5 ролике будет
Спасибо за видео.
А я думал, что без реализации репозитория в классе, нужно @Repository ставить над интерфейсов, оказалось оно там и не нужно.
Этот урок оказался коротким, но даже тут узнал что-то новое и крайне полезное, но без заранее подготовленных знаний по работе с БД у новичков будет темный лес)) Но иначе бы пришлось делать урок на пару часов, например, нет ни слова про отношения OneToMany и т.д.
Если я правильно понял о чем речь, то если не ставить аннотацию то не будет в логах специфичные ошибки показывать для бд. А так можно хоть @Component поставить
Спасибо за очень информативные видео. Может сделаете видео как правильно загружать, хранить и получать файлы с сервера, например картинки через контролеры, тоесть чтоб Product был еще и с картинкой )
Подумаю
Все прекрасно у Вас получается! Спасибо ! Очень доходчиво. Но будет ли Join в запросах хотя бы один-ко многим из двух таблиц? И как сериализовать чтобы подучился Json с вложеными блоками в таком случае? И вообще как работает сериализация при запрсах nbgf JOIN итп. Оочень нужно...
В рамках этого цикла роликов - нет, отдельно надо подумать
Александр, спасибо вам за эти замечательные обучающие ролики, все лаконично и на современном стэке! Разрешите задать вопрос, в чем смысл в классах обращаться к инжектируемым сущностям через this, без него ведь то же все будет корректно работать? Вероятно, это просто ваш стиль программирования направленный на поддержание кода в более структурированном и понятном виде))
Да, это стиль программирования, сразу видно, где обращение к локальным переменным, а где - к свойствам класса
Привет! Спасибо за твои видосы :) Хочу предложить тему для ролика: OTP (one time password) в spring security. По ней достаточно мало материала, а тот что есть - сделан очень коряво. Я сейчас сам начал пытаться реализовать данную тему, и понял, что это прям очень сложно выглядит (приходится переопределять usernamepasswordauthenticationfilter и делать прочие шаманства, что реализовать безопасный ввод кода). Очень бы хотелось увидеть твою реализацию по данной теме. Надеюсь - заинтересует, спасибо!
Постараюсь такой ролик записать
47:57 Почему знак вопроса - это процент? И зачем вообще их туда добавлять, т.е. почему без них не работает?
Знаки процента, банальная оговорка. Добавлять нужно для нестрогого сравнения по тексту
Комент для продвижения
Александр, здравствуйте, огромное спасибо за ролики! А вы не планируете в других роликах, вне цикла, рассмотрение фреймворка Camel? И еще вопрос, а вы использовали restclient, а feignclient в своей работе используете?
OpenFeign не использую, Camel, скорее всего, будет
28:20 Где настроить эти подсказки?
Оно уже сконфигурировано в IDEA Ultimate
Александр, напоминай пожалуйста, что не стоит писать select * from, тебя же новички смотрят)
как вариант еще можно фильтрацию реализовать через findByTitleContainingIgnoreCase(String filter);
не нужно будет делать проверку на null и blank
Можно и так, я привычен к failfast-стилю
всё прекрасно, одно маленькое замечание не у всех ультимейт версия идеи.
это да
Привет. У меня возник вопрос по поводу баз данных. Что делать, если у нас есть несколько сущностей и они связаны между собой. Как сохранить эту связь между сервисами? Нужно создавать какой-то отдельный модуль для сущностей и настраивать там связи? Или просто передавать dto и как-бы не испольщовать аннотаци onetomany и т.д. ? Или в каждый сервис копировать сущности ? просто если нам не нужны все сущности в сервисе ?
Вот например мы создаем сервис по формированию заказа, по идеи нам нужен товар, продавец и покупатель, но у покурателя наримеи есть еще поставщики, которые не нужны нам в этом сервисе. Как поступать в таких моментах ?
Хотел уточнить, какой вариант запроса лучше использовать на практике или в какой ситуации лучше использовать тот или иной метод создания запроса?
Использование названий методов - для самых простых вопросов, EntityManager - для самых сложных. В целом никто не запрещает для всех случаев использовать EntityManager. Тут характеристика лучше-хуже не совсем уместна)
Чтобы запрос был более красивым поможет настройка
spring.jpa.properties.hibernate.format_sql=true
Как называется тема на intellij idea? Понравился визуал значков и сочетание цветов
New UI
пропустил момент почему используется не паблик схема в преимущества использование не по дефолту и в чем преимущества использования префиксов "t_table _name" и с колонками тоже, это сделано намеренно в целях наглядности, наверное
Про схему: 5:25, префиксы для наглядности, да
Интересно как реализован save при завешении транзакции, ведь как то где то должен отслеживаться список измененных объектов?
Получается есть какой то менеджер объектов которых сохраняет ссылку на объект/егопрокси пока не произойдет завершение транзакции?
Интересно как это в хибере и не только реализуется под капотом.
Persistence Context
Cущесвует несколько уровней кэширования в Hibernate:
- на уровне сессии(по умолчанию активно)
- на уровне фабрики сессий(по умолчанию не активно)
Кэширование на уровне сессии представляет из себя поле в объекте Session, являющееся объектом PersistenceContext, содержащее, строго говоря, набор мап и метаданных с информацией об активных entity.
Основная из этих мап - поле HashMap entitiesByKey, где K - id сущности(объект EntityKey, содержащий id сущности, хэш и т.н. EntityPersister(специфичный преобразователь ORM, закрепленный за текущим типом entity)), а V - сама сущность.
Т.о. при попытке получить сущность Hibernate сперва получает ее из этой мапы, а если в ней нет, то получает из DB, после чего добавляет в мапу, чтобы при следующем поиске не идти снова в DB.
В другой мапе также инициализируется массив всех полей persistent объекта (добавленного в кэш), а при завершении транзакции происходит сравнение значений из этого массива с текущими значениями и если они не совпадают, то сессия считается "грязной"(были изменения объекта в ее ходе) и происходит дополнительный апдейт в БД. Этот механизм (dirty-checking'а, а не самого кэша) можно отключить, если использовать транзакцию с флагом read-only, тогда все апдейты нужно делать явно.
@@AlexSmile-y2x СпасиБо за развернутый ответ!
Здравствуйте, а для создания таблицы if not exists уже не нужно указывать?
Это не обязательные атрибуты
Можно указывать, для схемы я указываю, т.к. FlywayDB сама создаёт схему ЕМНИП, и я не хочу конфликта при выполнении скрипта
сделайте какой-то новый проект более интересный и больший - когда будут новые уроки
А у меня упорно не стартует ваш проект. WARN на flyway и на отсутствие коннекта к БД, раз я JPA и Postgre в POM указал
А параметры подключения к БД?
@@shurik_codes если имеется ввиду доп настройки в yaml/property или compose то таковых нет, postgre в Docker запустился нормально. я просто запустил ваш проект с git. Docker только вчера поставил, до этого в глаза его не видел
Наверное уже не надо, но у меня была такая проблема и решил ее добавлением flyway-database-postgresql зависимости в maven, может кому поможет
без зависимости flyway-database-postgresql кидал Unsupported Database
Код к ролику: github.com/alex-kosarev/sc24/tree/SC24EP03-spring-data-jpa всё работает без этой зависимости
спасибо большое! думал щас на 2 часа застряну с этой проблемой
Спас ваш комментарий! Спасибо)
А не подскажите почему без нее не работало?
Ты на мак пересел?
Нет
а каким образом определяется url для базы данных? (jdbc:postgresql://localhost:5432/catalogue). Просто определенный шаблон, который начинается с "jdbc:postgresql", а хост можно указать любой? И "/catalogue" здесь указывается название схемы?
jdbc:://:/, подробнее: docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html
Огонь. Огромное спасибо