2009-10-18 10 views
5

nowego do wiosny, a tu @stackoverflowWiosna @Transactional scalania i utrzymują pytanie

buduję inwentaryzacji autonomicznego & Sales śledzenia aplikacji (Apache Pivot/wiosna/JPA/Hibernate/MySQL) dla firmy rozprowadzającej .

Do tej pory uważam, że wszystko jest CRUD, więc planuję mieć klasę bazową ze wszystkim @ Transactional.

Potem dostałem problem z moją generyczną metodą składowania. Czy utrzymywanie i łączenie metody EntityManager od wiosny ma znaczenie?

Próbowałem uruchomić i zadzwoniłem do zapisywania zarówno wstawiania i aktualizowania i działało dobrze (myślę, że wiosna automatycznie odświeża encję za każdym razem, gdy wywołuję moją metodę zapisu // zobaczyłem, że zapytania hibernacji są rejestrowane, czy to prawda?).

@Transactional 
public abstract class GenericDAO { 

    protected EntityManager em; 

// em [email protected]/setter 

    public void save(T t) { 
//  if (t.getId() == null) // create new 
//  { 
//   em.persist(t); 
//  } else // update 
//  { 
      em.merge(t); 
//  } 
    } 
} 

A przy okazji, bez takiej konfiguracji, nie będę narażać na szwank wydajności? Na przykład wywołanie metody salesDAO.findAll() do generowania raportów (która nie musi być transakcyjna, prawda?).

dzięki !!!

Odpowiedz

5

This SO question to dobra dyskusja na temat utrzymywania kontra łączenia, a zaakceptowana odpowiedź wyjaśnia to całkiem dobrze. Druga odpowiedź również zawiera link do dobrego wpisu na blogu na ten temat.

Zgodnie z pierwszą odpowiedzią pod numerem this other post brzmi to tak, jakby można było wywołać scalanie zarówno w celu zapisywania, jak i aktualizowania obiektu, ale tak nie zrobiłem. W moich aplikacjach Spring/JPA mam tylko moje DAO, które rozszerzają JpaDaoSupport i używają getJpaTemplate() w następujący sposób.

/** 
* Save a new Album. 
*/ 
public Album save(Album album) { 
    getJpaTemplate().persist(album); 
    return album; 
} 

/** 
* Update an existing Album. 
*/ 
public Album update(Album album) { 
    return getJpaTemplate().merge(album); 
} 
+0

Jestem gościem to najprostsza droga. Więc jeśli mam JpaDaoSupport, a otrzymam od niego jednostkę, wszelkie zmiany zostaną automatycznie zatwierdzone? Myślę, że będę miał dwie odmiany metody oszczędzania, która będzie obowiązywać nadal i która będzie wywoływać flush. Wszelkie uwagi na ten temat? – thirdy

+0

Masz na myśli automatyczne, jak w zatwierdzonym bez zapisu lub aktualizacji? Jeśli tak, to nie sądzę, że zawsze po prostu dzwonię zapisać na nowym podmiocie lub aktualizować na istniejącym, aby kontynuować. Nigdy nie musiałem wywoływać metody flush, ale mój dostęp do bazy danych jest dość prosty dla dowolnego żądania. –

+0

Muszę teraz zrezygnować ze sprawdzania wiosny. Ciekawe, w jaki sposób Grails poprawia to? Nie będę musiał napotykać takich problemów w Grails, prawda? – thirdy

4

link do drugiej SO pytanie Kaleb pisał robi dobrą robotę pokrycia różnic i pułapek z utrzymują() vs seryjnej(). Jednak zawsze zaimplementowałem swoje klasy Dao za pomocą jednej metody save(), która tylko wywołuje funkcję merge(), aby obsłużyć zarówno inserty, jak i aktualizacje, i nigdy nie natknąłem się na żaden z argumentów persist() vs merge().

Jeśli chodzi o metody i metody transakcyjne: Stosowanie metod, które są tylko operacjami odczytu, nie ma większego wpływu na wydajność, ale wolę używać adnotacji na poziomie metody tylko po to, abym mógł łatwo stwierdzić, które metody są uaktualnione i które są czytane. Możesz to zrobić, ustawiając atrybut readOnly na adnotacji @Transactional.

Jeśli zastosujemy się do konwencji nazewnictwa w swoich metod (tj każda metoda read zawsze zaczyna się getXXX), można również użyć składni poincut w pliku konfiguracyjnym wiosennym automatycznie dokonać tego rozróżnienia:

<tx:advice id="txAdvice" transaction-manager="txManager"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true"/> 
     <tx:method name="*"/> 
    </tx:attributes> 
    </tx:advice> 

Zobacz Spring documentation on Transactions, aby uzyskać więcej informacji.

Ponadto zazwyczaj umieszczam atrybuty @Transactional o jeden poziom wyżej niż moje klasy Dao w warstwie usługi. Metody na klasach Dao to oddzielne operacje na bazie danych dla każdego wywołania metody, podczas gdy metody serwisowe mogą wykonać pojedyncze zatwierdzenie/wycofanie dla serii aktualizacji.

+0

dzięki za odpowiedź. Myślę, że pozostanę przy czystym JPA (nie potrzebuję elastyczności) – thirdy