2013-01-03 24 views
15

Moje pytanie brzmi następująco: Czy kiedykolwiek zgłoszono WZP merge w bezpaństwowej aplikacji internetowej?JPA połączyć w RESTful aplikacji sieci web z DTO i Optymistyczne blokowanie?

Istnieje wiele dyskusji na temat SO na temat operacji merge w WZP. Istnieje również great article on the subject, który kontrastuje scalanie JPA poprzez bardziej ręczny proces Do-It-Yourself (gdzie znajduje się podmiot za pośrednictwem podmiotu zarządzającego i wprowadzają zmiany).

Moja aplikacja ma bogaty model domeny (projekt oparty na domenie ala), który korzysta z adnotacji @Version w celu skorzystania z optymistycznego blokowania. Stworzyliśmy również DTO, aby wysłać przewód w ramach naszych usług internetowych RESTful. Utworzenie tej warstwy DTO pozwala nam również przesłać klientowi wszystko, czego potrzebuje, i nic, czego nie potrzebuje.

Do tej pory rozumiem, że jest to dość typowa architektura. Moje pytanie dotyczy metod usługi, które wymagają aktualizacji (tj. HTTP PUT) istniejących obiektów. W tym przypadku mamy te dwa podejścia: 1) JPA Merge i 2) DIY.

Nie rozumiem, w jaki sposób scalanie JPA można nawet uznać za opcję obsługi aktualizacji. Oto moje myślenie i zastanawiam się, czy jest coś, czego nie rozumiem:

1) Aby poprawnie utworzyć odłączony obiekt JPA z DTO wire, numer wersji musi być ustawiony poprawnie ... inaczej OptimisticLockException Jest rzucony. Ale spec WZP mówi:

Jednostka może uzyskać dostęp do stanu swojej dziedzinie wersję lub mienia lub eksportować sposób użycia przez aplikację, aby uzyskać dostęp do wersji, ale nie musi zmodyfikować wartość wersji [30] . Tylko dostawca utrwalania może ustawiać lub aktualizować wartość atrybutu wersji w obiekcie .

2) Scalanie nie obsługuje relacji dwukierunkowych ... pola z informacjami zwrotnymi zawsze kończą się jako puste.

3) Jeśli w DTO brakuje jakichkolwiek pól lub danych (z powodu częściowej aktualizacji), wówczas scalenie JPA usunie te relacje lub wyłączy te pola. Hibernacja może obsługiwać częściowe aktualizacje, ale nie łączy się JPA. DIY może obsługiwać częściowe aktualizacje.

4) Pierwszą rzeczą, którą zrobi metoda scalania, jest zapytanie do bazy danych o identyfikator jednostki, więc nie ma żadnej korzyści z wydajności w stosunku do majsterkowania.

5) W aktualizacji DYI ładujemy encję i wprowadzamy zmiany zgodnie z DTO - nie ma połączenia z merge lub persist, ponieważ kontekst WZP implementuje wzorzec jednostki pracy w polu.

Czy mam to proste?

Edit:

6) Scalanie zachowań w odniesieniu do leniwych załadowanych relacje mogą differ amongst providers.

Odpowiedz

13

Korzystanie z funkcji Merge wymaga wysłania i odebrania kompletnej reprezentacji obiektu lub zachowania stanu po stronie serwera. Dla trywialnych operacji typu CRUD-y jest to łatwe i wygodne. Użyłem go dużo w bezpaństwowych aplikacjach internetowych, w których nie ma znaczącego zagrożenia dla bezpieczeństwa, aby pozwolić klientowi zobaczyć cały podmiot.

Jeśli jednak ograniczyłeś już operacje tylko do przekazywania natychmiast istotnych informacji, musisz również ręcznie wpisać odpowiednie usługi.

Pamiętaj tylko, że podczas aktualizacji "Zrób to sam" musisz jeszcze podać numer wersji na urządzeniu DTO i ręcznie porównać go z tym, który pochodzi z bazy danych. W przeciwnym razie nie otrzymasz Optymistycznego blokowania, które obejmuje "czas myślenia użytkownika", który miałbyś, gdybyś używał prostszego podejścia z łączeniem.

  1. Nie można zmienić wersję na podmiot utworzony przez usługodawcę, ale po dokonaniu własną instancję klasy podmiotu ze słowem kluczowym new to jest w porządku i oczekiwać, aby ustawić wersję na nim.

  2. Spowoduje to, że reprezentacja trwała będzie zgodna z przedstawioną w pamięci reprezentacją, co może obejmować wprowadzanie wartości NULL. Pamiętaj, że kiedy obiekt jest scalony, obiekt ten powinien zostać odrzucony i zastąpiony przez ten, który został zwrócony przez scalenie. Nie powinno się scalać obiektu, a następnie kontynuować jego używanie. Jego stan nie jest określony przez specyfikację.

  3. Prawda.

  4. Najprawdopodobniej tak długo, jak Twoje rozwiązanie dla majsterkowiczów używa również identyfikatora jednostki, a nie arbitralnego zapytania. (Istnieją inne korzyści z zastosowania metody "znajdowania" w zapytaniu).

  5. Prawda.

4

Dodałbym:

7) Scalanie przekłada się wstawić lub zaktualizować w zależności od istnienia rekordu w DB, stąd też nie zajmuje poprawnie z update-vs-delete optymistycznej współbieżności. Oznacza to, że jeśli inny użytkownik jednocześnie usuwa rekord i aktualizujesz go, musi (1) wyrzucić wyjątek współbieżności ... ale tak nie jest, po prostu wstawia rekord jako nowy.

(1) Przynajmniej w większości przypadków moim zdaniem powinien. Mogę sobie wyobrazić kilka przypadków, w których chciałbym użyć tego przypadku, aby uruchomić nową wkładkę, ale są one dalekie od zwykłych. Przynajmniej chciałbym, aby deweloper dwukrotnie się nad tym zastanowił, a nie tylko zaakceptował, że "merge() == updateWithConcurrencyControl()", ponieważ tak nie jest.

Powiązane problemy