Czym różni się JPA Spring Data od Hibernate w przypadku dużych projektów?

129

Trudno mi się zdecydować, czy powinienem pozostać przy Hibernate przy nowym projekcie, czy też zmoczyć stopy dzięki JPA i nowej implementacji Spring Data.

Czy framework Spring Data jest przeznaczony dla dużych projektów lub małych projektów ze skromnymi wymaganiami dotyczącymi zapytań?

Chociaż z pewnością dostrzegam zalety redukcji kodu przy użyciu @Queryadnotacji, co robisz w przypadku zapytań dynamicznych? A co jeśli chcesz zaimplementować dość złożoną metodę save ()?

Dokumentacja mówi o stworzeniu niestandardowego interfejsu i implementacji, które implementuje twoje główne repozytorium, ale co, jeśli potrzebujesz dostępu do super metod w samym repozytorium crud? Repozytorium crud implementuje własne - a nie na odwrót. Wydaje się, że to dziwny projekt.

Nie jestem pewien, czy te ramy sprostają wyzwaniom związanym ze złożonymi i dużymi aplikacjami. Nigdy nie napotkałem wielu problemów z Hibernacją i rozważam trzymanie się starego, dobrego, niezawodnego, zamiast iść z Spring Data JPA.

Co powinienem zrobić? Jakie nieprzewidziane komplikacje i koszty napotkam, jeśli zdecyduję się na Spring Data JPA?

egervari
źródło
1
O ile wiem, nie ma to większego znaczenia. Idź z tym, z którym czujesz się bardziej komfortowo. Dlaczego debata?
duffymo
1
Oczywiście czuję się o wiele bardziej komfortowo z Hibernacją, ale jeśli mogę robić to samo i być bardziej produktywnym, wolę przyjąć nowsze podejście. Jeśli jednak Hibernate jest nadal potężniejsze i napotkam znacznie mniej problemów, to chciałbym się o tym dowiedzieć.
egervari
3
JPA to uogólnienie ORM, które wykorzystuje Hibernate jako jedną z wielu implementacji. Jakie moce przypisujesz jednemu ponad drugiemu? JPA to standard, ale widzę niewielką różnicę między nimi. W celu pełnego ujawnienia powiem, że nie obchodzi mnie żaden z nich. Obie generują dla Ciebie SQL. Wolałbym napisać to sam. ORM nie jest dla każdego problemu i dla każdego użytkownika.
duffymo
1
Zgadzam się. Jeśli chodzi tylko o JPA lub hibernację, za każdym razem wybrałbym Hibernację. Szczerze mówiąc, nie podoba mi się samo wdrożenie JPA. Obsługa IDE w IDEA jest nadal trochę zła i będzie narzekać, jeśli mapowania nie są poprawne podczas uruchamiania aplikacji, zamiast pozwolić na uruchomienie testów jednostkowych. W JPA mam wiele innych dziwaków. Właściwie to lubię stare pliki mapowania Hibernate XML. Ma tę zaletę, że sprawia, że ​​moje obiekty również wyglądają na znacznie mniej zagracone. Spring Data JPA oferuje wiele nowych funkcji, więc w końcu zastanawiałem się, czy warto się przełączyć.
egervari
3
„Spring Data” nie jest implementacją JPA ani czymkolwiek. Po prostu bierze istniejącą implementację JPA i upraszcza to, co do niej zapewniasz. Implementacja JPA nadal wykonuje całą pracę pod osłonami
Neil Stockton

Odpowiedzi:

104

Więc spring-datarobi trochę dodatkowej magii, która pomaga przy złożonych zapytaniach. Na początku jest to dziwne i całkowicie pomijasz to w dokumentach, ale jest naprawdę potężne i przydatne.

Polega na utworzeniu niestandardowego Repositoryi niestandardowego `RepositoryImpl 'oraz wskazaniu Springowi, gdzie go znaleźć. Oto przykład:

Klasa konfiguracji - wskaż wciąż potrzebną konfigurację xml z adnotacją wskazującą na pakiet repozytoriów (teraz szuka *Implklas automatycznie):

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

jpa-repositories.xml - powiedz, Springgdzie znaleźć swoje repozytoria. Powiedz również, Springaby poszukać niestandardowych repozytoriów o CustomImplnazwie pliku:

<?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- tutaj możesz umieścić metody zapytań z adnotacjami i bez adnotacji. Zwróć uwagę, jak ten interfejs repozytorium rozszerza ten 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 - metody repozytorium, które są bardziej złożone i nie można ich obsłużyć za pomocą prostego zapytania lub adnotacji:

public interface MyObjectRepositoryCustom {

    List<MyObject> findByNameWithWeirdOrdering(String name);
}

MyObjectRepositoryCustomImpl- gdzie faktycznie zaimplementujesz te metody z 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);
    }
}

O dziwo, wszystko to łączy się ze sobą, a metody z obu interfejsów (i interfejsu CRUD, który implementujesz), pojawiają się, gdy to zrobisz:

myObjectRepository.

Zobaczysz:

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

To naprawdę działa. Otrzymujesz jeden interfejs do wykonywania zapytań.spring-datanaprawdę jest gotowy na dużą aplikację. A im więcej zapytań umieścisz w prostych lub tylko adnotacjach, tym lepiej będziesz.

Wszystko to jest udokumentowane w witrynie Spring Data Jpa .

Powodzenia.

sbzoom
źródło
4
Właśnie tego próbowałem i do pewnego stopnia działa. Problem, który miałem, to co zrobić, jeśli chcesz nadpisać save ()? Na przykład wyobraź sobie, że zapisujesz bloga i chcesz przetworzyć / zapisać powiązane z nim tagi w metodzie save (), ponieważ umieszczanie go w usłudze nie ma większego sensu. Jest to łatwe do zrobienia z surowym Hibernate, ale nie widzę dobrego sposobu na zrobienie tego z Spring JPA. Zaznaczę jednak twoją odpowiedź jako poprawną, ponieważ jest poprawna. W zasadzie to możesz zrobić z Spring Data JPA. Myślę jednak, że zostanę przy Hibernate. Ta odpowiedź z pewnością pomoże innym.
egervari
8
Możesz wdrożyć własne JpaRepository-> MyJpaRepository. Musisz także utworzyć, MyJpaRepositoryFactoryBeanale jeśli ustawisz to wszystko poprawnie, możesz nadpisać metodę .save (). Oto dokumenty JPA Spring Data: static.springsource.org/spring-data/data-jpa/docs/current/… Nie poddawaj się jeszcze!
sbzoom
@Picrochole Jak interpretujesz „niższy poziom aplikacji”? Czy usługa, która wywołuje DAO, ma niższy poziom?
Rumid
12

Używałem Spring Data JPA w małych i dużych projektach z prostymi zapytaniami. Główną zaletą jest to, że nie trzeba nawet używać @Queryadnotacji. W Spring Data nic nie stoi na przeszkodzie, abyś używał go w dużych projektach, a ostatnie QueryDSLwsparcie może ci pomóc. To jest przykład użycia QueryDSL do kierowania na Hibernate.

Jeśli przewidujesz złożone zapytania i czujesz się komfortowo używając obiektów Hibernate bez JPA, myślę, że alternatywną kombinacją może być posiadanie prostych Spring Data Repositoryobok złożonych opartych na Hibernacji z określonymi metodami, których możesz potrzebować. Może być mniej kłopotliwe niż przekręcenie implementacji Hibernate w strukturę JPA Spring Data.

szaleństwo3
źródło
2
Myślę, że wolałbym raczej używać tego samego spójnego interfejsu API do zapytań niż mieszać i dopasowywać w tym samym projekcie. Nadal nie znalazłem dobrego rozwiązania dla skomplikowanych wiosennych danych jpa, a ponieważ ogólnie mam sporo czubków z jpa, myślę, że może być bardziej szczęśliwy, jeśli zaakceptuję hibernację jako mój orm. Będę miał wiele skomplikowanych zapytań i nie stać mnie na mieszankę 40/60. Nie jest to dla mnie warte :(
egervari
1
Możesz również używać Querydsl bezpośrednio, bez Spring Data, co daje pojedynczą potężną warstwę zapytań nad JPA.
Timo Westkämper
4

Spring JPA zapewni Ci dużo abstrakcji od pisania SQL, a nawet niektórych HQL za pomocą deklaracji metody zapytania. Spring JPA wyróżnia się generowaniem zapytań, ale jeśli potrzebujesz rozwiązania czysto hibernacyjnego, możesz dostosować je w razie potrzeby, ponieważ wiosenny JPA nadal jest oparty na hibernacji. Więcej informacji znajdziesz w dokumentacji http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html .

BLA
źródło