Чем Spring Data JPA отличается от Hibernate для больших проектов?

129

Мне трудно решить, следует ли мне придерживаться Hibernate для нового проекта или попробовать JPA и новую реализацию Spring Data.

Фреймворк Spring Data предназначен для крупных проектов или небольших проектов со скромными требованиями к запросам?

Хотя я определенно вижу преимущество сокращения кода за счет использования @Queryаннотации, что вы делаете для динамических запросов? А как насчет того, чтобы реализовать довольно сложный метод save ()?

В документации говорится о создании пользовательского интерфейса и реализации, которые реализует ваш основной репозиторий, но что, если вам нужно получить доступ к любым супер-методам в самом репозитории crud? Репозиторий crud реализует пользовательский, а не наоборот. Похоже на странный дизайн.

Я очень не уверен, сможет ли этот фреймворк решать задачи сложных и больших приложений. Я никогда не сталкивался со многими проблемами с Hibernate, и я подумываю придерживаться старого доброго надежного, а не использовать Spring Data JPA.

Что я должен делать? С какими непредвиденными осложнениями и расходами я столкнусь, если буду использовать Spring Data JPA?

egervari
источник
1
Насколько я знаю, это не имеет большого значения. Выбирайте тот, который вам удобнее. Почему споры?
duffymo 08
1
Мне, очевидно, удобнее работать с Hibernate, но если я могу делать то же самое и быть более продуктивным, я предпочитаю использовать новые подходы. Однако, если Hibernate все еще более мощный и у меня будет гораздо меньше проблем, то я хотел бы знать об этом.
egervari 08
3
JPA - это обобщение ORM, в котором Hibernate используется как одна из многих реализаций. Какие силы вы наделяете одним над другим? JPA - это стандарт, но я не вижу большой разницы между ними. В интересах полного раскрытия информации я скажу, что мне все равно ни один из них. Оба генерируют для вас SQL. Я лучше сам напишу. ORM подходит не для всех проблем и не для каждого пользователя.
duffymo 08
1
Я согласен. Когда дело касается только JPA или Hibernate, я бы каждый раз выбирал Hibernate. Честно говоря, мне не очень нравится реализация JPA сама по себе. Поддержка IDE в IDEA на самом деле все еще плохая, и она будет жаловаться, если сопоставления неверны при запуске приложения, вместо того, чтобы запускать модульные тесты. У меня много других придирок к JPA. Мне действительно нравятся старые файлы отображения XML Hibernate. У этого есть то преимущество, что мои объекты выглядят намного менее загроможденными. Spring Data JPA предлагает много новых функций, поэтому я наконец задумался, стоит ли его менять.
egervari
3
«Spring Data» не является реализацией JPA или чего-то еще. Он просто берет существующую реализацию JPA и упрощает то, что вы ей предоставляете. Реализация JPA по-прежнему выполняет всю работу под прикрытием
Нил Стоктон

Ответы:

104

Итак, spring-dataделает некоторую дополнительную магию, которая помогает со сложными запросами. Сначала это странно, и вы полностью пропускаете это в документации, но это действительно мощно и полезно.

Он включает в себя создание пользовательского Repositoryи пользовательского `RepositoryImpl 'и указание Spring, где его найти. Вот пример:

Класс конфигурации - укажите на все еще необходимую конфигурацию xml с аннотацией, указывающей на ваш пакет репозиториев ( *Implтеперь он автоматически ищет классы):

@Configuration
@EnableJpaRepositories(basePackages = {"com.examples.repositories"})
@EnableTransactionManagement
public class MyConfiguration {
}

jpa-repositories.xml - скажите, Springгде найти свои репозитории. Также скажите Springискать собственные репозитории с CustomImplименем файла:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<jpa:repositories base-package="com.example.repositories" repository-impl-postfix="CustomImpl" />

</beans>

MyObjectRepository- здесь вы можете поместить аннотированные и неаннотированные методы запроса. Обратите внимание, как этот интерфейс репозитория расширяет его Custom:

@Transactional
public interface MyObjectRepository extends JpaRepository<MyObject, Integer>, MyObjectRepositoryCustom {

    List<MyObject> findByName(String name);

    @Query("select * from my_object where name = ?0 or middle_name = ?0")
    List<MyObject> findByFirstNameOrMiddleName(String name);
}

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

public interface MyObjectRepositoryCustom {

    List<MyObject> findByNameWithWeirdOrdering(String name);
}

MyObjectRepositoryCustomImpl- где вы фактически реализуете эти методы с помощью autowired EntityManager:

public class MyObjectRepositoryCustomImpl implements MyObjectRepositoryCustom {

    @Autowired
    private EntityManager entityManager;

    public final List<MyObject> findByNameWithWeirdOrdering(String name) {
        Query query = query(where("name").is(name));
        query.sort().on("whatever", Order.ASC);
        return entityManager.find(query, MyObject.class);
    }
}

Удивительно, но все это собрано вместе, и методы из обоих интерфейсов (и интерфейса CRUD, который вы реализуете) все появляются, когда вы это делаете:

myObjectRepository.

Ты увидишь:

myObjectRepository.save()
myObjectRepository.findAll()
myObjectRepository.findByName()
myObjectRepository.findByFirstNameOrMiddleName()
myObjectRepository.findByNameWithWeirdOrdering()

Это действительно работает. И вы получаете один интерфейс для запросов. spring-dataдействительно готов для большого приложения. И чем больше запросов вы можете вставить в простые или аннотационные, тем лучше для вас.

Все это задокументировано на сайте Spring Data Jpa .

Удачи.

sbzoom
источник
4
На самом деле это то, что я пробовал, и это в некоторой степени работает. У меня возникла проблема: что, если вы хотите переопределить save ()? Например, представьте, что вы сохраняете блог и хотите обработать / сохранить теги, связанные с ним, в методе save (), поскольку размещение его в службе не имеет большого смысла. Это легко сделать с необработанным Hibernate, но я не вижу хорошего способа сделать это с помощью Spring JPA. Я отмечу ваш ответ как правильный, потому что он правильный. В основном это то, что вы можете делать с помощью Spring Data JPA. Я думаю, что буду придерживаться Hibernate. Этот ответ обязательно поможет другим.
egervari
8
Вы можете реализовать свои собственные JpaRepository-> MyJpaRepository. Вы также должны создать, MyJpaRepositoryFactoryBeanно если вы все настроите правильно, вы можете переопределить метод .save (). Вот документы Spring Data JPA: static.springsource.org/spring-data/data-jpa/docs/current/… Не сдавайтесь!
sbzoom
@Picrochole, как вы интерпретируете «нижний уровень приложения»? Служба, которая вызывает DAO, находится на более низком уровне?
Румид
12

Я использовал Spring Data JPA в малых и больших проектах с простыми запросами. Главное преимущество - отсутствие необходимости использовать @Queryаннотацию. В Spring Data нет ничего, что мешало бы вам использовать его в больших проектах, и недавняя QueryDSLподдержка может вам помочь. Это пример использования QueryDSL для Hibernate.

Если вы предвидите сложные запросы и чувствуете себя комфортно, используя объекты Hibernate без JPA, я думаю, что альтернативной комбинацией может быть простая Spring Data Repositoryрядом со сложными на основе Hibernate с конкретными методами, которые могут вам понадобиться. Возможно, это будет менее громоздко, чем превращение реализации Hibernate в структуру Spring Data JPA.

madth3
источник
2
Я думаю, что я бы предпочел использовать один и тот же согласованный api для запросов, а не смешивать и сопоставлять в одном проекте. Я до сих пор не нашел хорошего решения для сложного материала jpa с данными Spring, и, поскольку в целом у меня есть довольно много придирок к jpa, я думаю, что, возможно, мне будет проще принять спящий режим в качестве своего orm. У меня будет много сложных запросов, и я не могу позволить себе сочетание 40/60. Мне это не стоит :(
egervari
1
Вы также можете использовать Querydsl напрямую без Spring Data, что дает вам один мощный слой запросов поверх JPA.
Timo Westkämper
4

Spring JPA предоставит вам много абстракций от написания SQL и даже немного HQL с использованием объявления метода запроса. Spring JPA сияет своей генерацией запросов, но если вам нужно чисто спящее решение, вы можете настроить его по мере необходимости, поскольку Spring JPA по-прежнему основан на спящем режиме. Дополнительную информацию см. В документации http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html .

FOO
источник