Transakcje przy repozytoriach Spring Data

Odpowiedz Nowy wątek
2014-08-26 09:55
0

W jaki sposób najczęściej obsługuje się transakcje, gdy korzysta się ze Spring Data? Tworzy się dodatkowy serwis, z metodami dla których chcemy nałożyć transakcje?

Repozytorium:

package com.mp.webapp.repository;

import com.mp.webapp.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<UserEntity, Long> {
}

Serwis:

package com.mp.webapp.service;

import com.mp.webapp.entity.UserEntity;
import com.mp.webapp.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserService implements IUserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    @Transactional
    public UserEntity save(UserEntity user) {
        return userRepository.save(user);
    }

    @Override
    @Transactional
    public Iterable<UserEntity> save(Iterable<UserEntity> users) {
        return userRepository.save(users);
    }

    @Override
    @Transactional
    public void delete(UserEntity user) {
        userRepository.delete(user);
    }

    @Override
    @Transactional
    public void delete(Iterable<UserEntity> users) {
        userRepository.delete(users);
    }

    @Override
    @Transactional
    public void delete(Long id) {
        userRepository.delete(id);
    }

    @Override
    public List<UserEntity> findAll() {
        return userRepository.findAll();
    }
}

Korzystając z takiego serwisu nie mamy dostępu do wszystkich metod jakie udostępnia interfejs JpaRepository. Może jest jakiś lepszy sposób?

Pozostało 580 znaków

2014-08-26 10:02
0

A na interfejsie od repo nie mozesz dac Transactional

Pozostało 580 znaków

2014-08-26 10:07
0

Ale wtedy wszystkie metody interfejsu są objęte transakcją, tak się robi?

Pozostało 580 znaków

2014-08-26 10:12
1

@Szczery adnotacja transactional nie działa dla interfejsów. Musi być aplikowana dla konkretnych klas. Polecam korzystać z IntelliJ, on ładnie oznacza takie rzeczy i od razu widzisz które metody złapały jakieś AOP a które nie.
@bakeraw2 możesz zawsze adnotować całą klasę, ale nie interfejs ;)
Ale generalnie zrobiłeś to źle, a przynajmniej niezbyt dobrze.

  1. Ten twój serwis to DAO, nie bardzo rozumiem co on niby dodaje do tego dao co mu wstrzykujesz skoro on tylko deleguje metody. Po co ta klasa w ogóle jest? o_O
  2. Transakcje lepiej wyciagać wysoko, z powodu wydajności i z powodu atomowych operacji. W jakimś faktycznym serwisie który obsługuje logikę biznesową będziesz często miał kilka operacji związanych z jedną "logiką" i warto żeby cały taki zestaw był atomowy.

Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...
edytowany 1x, ostatnio: Shalom, 2014-08-26 10:13
ad 1. Nie zawsze da się to zrobić tak jak piszesz. Serwis może tylko wywołany jako np. usługa sieciowa (co jest dośc proste do zrobienia), a przygotowanie DAO jako WS-a choć nadal proste to wprowadza duży fakap do kodu. Prosta usluga - Zapisz mi notkę do bazy. masz sobie NotkaService, który jest wrapperem dla DAOsa. - Koziołek 2014-08-26 14:54
Ja rozumiem że jeśli faktycznie coś wprowadza dodatkową logikę to ma sens. Gdyby ten serwis to było jakieś Remote czy endpoint dla WebService to bym się nie przyczepił, ale w tym przypadku jestem prawie że pewien że tak nie jest, że to jest tylko zbędna warstwa która deleguje sobie wywołania. Może to jest jakaś fasada żeby ograniczyć API do DAO? - Shalom 2014-08-26 14:58

Pozostało 580 znaków

2014-08-26 22:34
1

Bzdury, bzdury, bzdury!!!

Crudowe metody w JPA Data są objęte transakcją domyślnie. Na metodach interfejsu ze Spring DATA! można oczywiście definiować @Transactional !

Radzę poczytać dokumentację, a nie wypisywać głupoty. To tylko ok. 40 stron. Proszę się zapoznać z tym:

http://docs.spring.io/spring-[...]/reference/html/#transactions

A co do pomysłu z posta autora co do klasy serwisu opakowującej DAO, to jest poroniony pomysł. Głupota do kwadratu. Jak już napisał kolega Shalom, serwis to tylko z logiką biznesową.

Pozostało 580 znaków

2014-08-27 02:10
0

@krgr albo ja nie rozumiem o co ci chodzi, albo ty nie rozumiesz o czym pisałem, więc po kolei:
Nie można dać @Transactional na interfejsie. Tzn można, ale to wcale nie sprawi że wszystkie klasy które go implementują nagle będą miały @Transactional. Tak samo zresztą jest dla metod w definicji interfejsu - nie można na nich dać @Transactional. W konkretnych implementacjach możemy jak najbardziej dodać taką adnotację i będzie ok i zupełnie bez znaczenia jest czy będzie to metoda z takiego czy innego interfejsu.
Wyobraź sobie że znam dokumentację jak i Springa całkiem znośnie ;) Ja polecam za to czytać posty ze zrozumieniem. Są krótsze niż 40 stron, więc może dasz radę ;)
Ale skoro polecasz dokumentację której sam nie czytasz?

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies ( proxy-target-class="true") or the weaving-based aspect ( mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2014-08-27 09:13
1

Shalom kolego,

Czy znasz Spring Data JPA? Tam się nie implementuje interfejsów. Dałem konkretnego linka do konkretnego przypadku, który autor rozpatrywał. Zresztą wyraźnie napisałem, że chodzi o Spring DATA!

Pozostało 580 znaków

2014-08-27 09:38
0

@krgr kajam się, faktycznie nie zrozumiałem do końca o co autor pytał a potem źle zrozumiałem twój komentarz. Mea culpa!

@bakeraw2 tak jak napisał @krgr repozytoria generowane przez Spring Data automatycznie są tranzakcyjne, nie musisz nic więcej z nimi robić. Ale ja bym się zastanowił czy to jest całkiem dobre rozwiązanie. Bo zakładanie tranzakcji tak nisko, szczególnie jeśli potem operujesz sporo na bazie, może być zwyczajnie bardzo kosztowne. Dlatego mimo wszystko obejmowanie metod biznesowego serwisu tranzakcjami ma sens.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2014-08-27 09:58
0

Ok,

Co do service'u to uważam że zazwyczaj jest niezbędny. Domyślnie Spring załatwia za nas wszystkie problemy, które mogłyby wyniknąć z zarządzania transakcjami - poprzez poziom propagacji transakcji ustawiony na REQUIRED. Dzięki temu transakcje w serwisie 'opakują' transakcje na DAO. Więc tymi transakcjami na DAO bym się nie przejmował.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0