Comments 14
Еще есть такая прикольная штука как CriteriaDefinition:

Когда мы работаем с
Tuple
, очень удобным решением является использование библиотеки hibernate-jpamodelgen, что позволяет нам пользоваться автосгенерированными константами.
и не только с Tuple, а вообще, в принципе, лучше генерировать так называемую метамодель данных чтобы запросы были type-safe. Т.е. вместо строковых названий таблиц/столбцов использовать сгенерированную метамодель.
Ну и лучше использовать HibernateCriteriaBuilder
вместоCriteriaBuilder

HibernateCriteriaBuilder builder = (HibernateCriteriaBuilder) em.getCriteriaBuilder();
Vlad Mihalchea предлагает способ, как писать select new PostWithAuthorFlatDto
без указания полного имени класса.
Но для этого нужно объявить свой IntegratorProvider, в котором перечислить все такие классы.
public class ClassImportIntegratorIntegratorProvider implements IntegratorProvider {
@Override
public List<Integrator> getIntegrators() {
return List.of(
new ClassImportIntegrator(
List.of(
PostDTO.class
)
)
);
}
}
spring.jpa.properties.hibernate.integrator_provider=your.awesome.app.ClassImportIntegratorIntegratorProvider
Лично мне кажется не супер полезной функциональностью
Любая критика JPA в своей сути о том, что это экстремально сложная спецификация.
К которой добавляются экстремально сложные реализации, которые не во всем спецификации следуют и к тому же тащат с собой сотни расширений.
И как вишенка на торте: дополнительные библиотеки Spring Data, DeltaSpike Data и т.п.
Всё это вместе: тысячи страниц документаций, сотни багов, пачки "воркараундов" ...
Нужны годы, буквально, опыта чтобы умело с этим работать и в любовно расставленные повсеместно ловушки не попадать.
Вот вы целую хорошую статью написали по сути о том, как не попасть в засаду выполняя тривиальный запрос.
А в соседней статье целый опус о том как не просто реализовать equals(!) для Entity.
Я о 10-ках подобных нюансов JPA мог бы рассказать, и это при том, что я убежден: за много лет я сталкивался я с каким-то небольшим подмножеством проблем.
И люди тащат этого монстра в микросервис с 5-ю запросами к базе.
Ну такое...
Как раз для приложения с 5 запросами он идеально подходит - нет сложной модели в 99% случаев, а значит запросы будут простые, доступные фактически из коробки и минимум сложностей. Все танцы в гибернейте начинаются под ростом нагрузки и сложности модели...
Только эти пять запросов так-то и на чистом SQL можно написать и потом замаппить на классы, если это вообще нужно.
Можно конечно, но 2-4 класса сущностей + репозиторий все равно проще и короче, чем 2-4 сущности, несколько мапперов (на каждый тип запроса) и репозиторий. Банально проще и быстрее. Но в целом да, написать это и руками совершенно не сложно. Но так можно сказать про проект в общем то любого размера. и в зависимости от того, какие запросы, какой формат БД, какой профиль нагрузки и прочее плюсы могут появиться как у JPA так и у нативных запросов. Серебряной пули я тут не встречал ни разу
Насчет "проще и короче" это, скажем прямо, далеко не всегда так.
Но дело не только в этом. А в том, что ради ничтожного объема кода связанного с DB, вы добавляете в приложение огромный JPA-runtime (~6-8 Mb) о котором просто необходимо много чего знать (иначе выстрел в ногу почти неминуем); платите некоторой потерей производительности и сильно возросшей сложностью.
Если уж так страшно иметь дело с чистым JDBC, то есть сильно более лекговестные и предсказуемые библиотеки, например JDBi или тот же Spring JdbcTemplate.
Проекты для которых праимущества JPA перевешивают связанные с ним сложности и накладные расходы они бывают, но сильно реже чем кажется.
JPA это совершенно точно не "лучший выбор по умолчанию". Особено для небольших приложений.
Планируете разобрать проблему n + 1 для случая с фильтром (например where title like ...) с пагинацией? То есть как не получить н+1 проблему, и проблему пагинации в памяти
JPA Entity. Загрузи меня не полностью