Mówiąc jako ktoś, kto spędził sporo czasu pracując z JPA (Java Persistence API, w zasadzie znormalizowany ORM API dla Java / J2EE / EJB), który obejmuje Hibernate, EclipseLink, Toplink, OpenJPA i inne, podzielę się niektórymi moimi obserwacje.
- ORM nie są szybkie. Mogą być odpowiednie i przez większość czasu wystarczające jest OK, ale w środowisku o dużych opóźnieniach i małych opóźnieniach są nie-nie;
- W językach programowania ogólnego przeznaczenia, takich jak Java i C #, potrzeba ogromnej ilości magii, aby mogły działać (np. Tkanie w czasie ładowania w Javie, oprzyrządowanie itp.);
- Korzystając z ORM, zamiast wchodzić dalej w SQL (co wydaje się być intencją), będziesz zaskoczony, ile czasu spędzasz na ulepszaniu XML i / lub adnotacji / atrybutów, aby ORM wygenerował wydajny SQL;
- W przypadku złożonych zapytań tak naprawdę nie ma substytutu. Podobnie jak w JPA, istnieje kilka zapytań, które po prostu nie są możliwe, które są w surowym SQL, a kiedy trzeba użyć surowego SQL w JPA, to nie jest ładne (C # /. Net przynajmniej ma typy dynamiczne - var - co jest dużo ładniejszy niż tablica obiektów);
- Podczas korzystania z ORM jest bardzo dużo „gotchas”. Obejmuje to niezamierzone lub nieoczekiwane zachowanie, fakt, że musisz wbudować możliwość wykonywania aktualizacji SQL bazy danych (za pomocą funkcji refresh () w JPA lub podobnych metodach, ponieważ JPA domyślnie buforuje wszystko, aby nie przechwycić bezpośredniej bazy danych aktualizacja - uruchamianie bezpośrednich aktualizacji SQL jest częstym działaniem wspierającym produkcję);
- Niedopasowanie obiektowo-relacyjne zawsze będzie powodować problemy. Przy każdym takim problemie występuje kompromis między złożonością a kompletnością abstrakcji. Czasami czułem, że JPA posunął się za daleko i osiągnął prawdziwe prawo malejących zwrotów, w których złożoność nie była uzasadniona abstrakcją.
Jest jeszcze jeden problem, który wymaga nieco więcej wyjaśnień.
Tradycyjny model aplikacji internetowej ma warstwę utrwalającą i warstwę prezentacji (być może z usługami lub innymi warstwami pomiędzy nimi, ale są to dwie ważne w tej dyskusji). ORM wymuszają sztywny widok od twojej warstwy trwałości do warstwy prezentacji (tj. Twoich jednostek).
Jedną z krytyk bardziej surowych metod SQL jest to, że otrzymujesz wszystkie VO (obiekty wartości) lub DTO (obiekty przesyłania danych), które są używane przez jedno zapytanie. Jest to reklamowane jako zaleta ORM, ponieważ się tego pozbywasz.
Chodzi o to, że problemy te nie znikają z ORM, po prostu przechodzą do warstwy prezentacji. Zamiast tworzyć VO / DTO dla zapytań, tworzysz niestandardowe obiekty prezentacji, zwykle po jednym dla każdego widoku. Jak to jest lepsze? IMHO nie jest.
Pisałem o tym w ORM lub SQL: Czy już tam jesteśmy? .
Moją wybraną obecnie technologią trwałości (w Javie) jest ibatis. Jest to dość cienkie opakowanie wokół SQL, które robi ponad 90% tego, co potrafi JPA (może nawet leniwie ładować relacje, chociaż nie jest to dobrze udokumentowane), ale ma znacznie mniejszy narzut (pod względem złożoności i faktycznego kodu).
Tak było w zeszłym roku w aplikacji GWT, którą pisałem. Wiele tłumaczeń z EclipseLink na obiekty prezentacji w implementacji usługi. Gdybyśmy korzystali z ibatis, znacznie łatwiej byłoby stworzyć odpowiednie obiekty za pomocą ibatis, a następnie przekazać je w górę iw dół stosu. Niektórzy puryści mogą argumentować, że to Bad ™. Być może tak (teoretycznie), ale powiem ci: co prowadziłoby do prostszego kodu, prostszego stosu i większej wydajności.