2 votes

Spring Data JPA + Hibernate Marquage des méthodes comme transactionnelles

J'utilise le référentiel de Spring data JPA pour mon application. Actuellement, j'utilise les opérations CRUD de base fournies par défaut par les référentiels Spring Data JPA et pour les requêtes de jointure complexes, j'écris des requêtes JPQL personnalisées comme suit :

public interface ContinentRepository extends JpaRepository<Continent, Long>
{
    @Query(value = "SELECT u FROM Continent u JOIN FETCH ... WHERE u.id = ?1")
    public List<Continent> findContinent(Long id);
}

Dans ma classe de service, je suis en train de câbler ce référentiel et d'effectuer des opérations sur la base de données.

@Service
public class MyService
{
    @Autowired
    public ContinentRepository cr;

    public void read()
    {
        var result1 = cr.findContinent(1);
        var result2 = cr.findContinent(2);
    }

    @Transactional
    public void write()
    {
        var c = new Continent();
        // setters
        c = cr.save(c);
    }
}

Actuellement, je ne fais que marquer le write() como org.springframework.transaction.annotation.Transactional .

  1. Dois-je également marquer read() méthode avec Transactional(readOnly = true) ? Comme il n'effectue que des opérations de lecture.
  2. Dois-je également marquer le findContinent(Long id) comme Transactional(readOnly = true) ? J'ai lu que toutes les méthodes par défaut sont marquées comme transactionnelles. https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
  3. Dans l'interface du référentiel, dois-je marquer l'annotation Transactional au niveau de la méthode ou au niveau de l'interface. (De plus, je pense que la plupart des méthodes personnalisées seront en lecture seule).
  4. Est-il bon d'avoir @Transactional à la fois dans la couche Service et dans la couche Référentiel ?

2voto

Octavian R. Points 382
  1. Dois-je également marquer la méthode read() avec Transactional(readOnly = true) ? Car elle n'effectue que des opérations de lecture.

Ce n'est pas vraiment nécessaire, mais cela pourrait créer des optimisations concernant la consommation de la mémoire cache en fonction de ce blog. https://vladmihalcea.com/spring-read-only-transaction-hibernate-optimization/

  1. Dois-je également marquer le findContinent(Long id) comme transactionnel(readOnly = true) ? J'ai lu que toutes les méthodes par défaut comme marquées comme Transactionnelles https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

La même réponse que dans le premier cas

  1. Dans l'interface du référentiel, dois-je marquer l'annotation Transactional au niveau de la méthode ou au niveau de l'interface. (De plus, je suspecter que la plupart des méthodes personnalisées seront en lecture seule)

En général, j'ai ajouté au niveau de la méthode, car j'ai plus de contrôle sur les paramètres comme le retour en arrière.

  1. Est-il bon d'avoir @Transactional à la fois dans la couche Service et dans la couche Référentiel ?

Je vous recommande d'avoir au niveau Service car, là, vous pouvez mettre à jour de nombreuses tables (donc vous pouvez utiliser de nombreux référentiels), et vous voulez que toute votre mise à jour soit transactionnelle.

0voto

nbjibjssr Points 41
  1. Dois-je également marquer la méthode read() avec Transactional(readOnly = true) ? Car elle n'effectue que des opérations de lecture.

Oui, c'est une bonne pratique, vous saurez immédiatement que cette méthode ne change rien dans la base de données, et ce qui est plus important, vous désactiverez certains changements involontaires dans la base de données en utilisant cette méthode de service. Si cette méthode tente d'effectuer une mise à jour de la base de données, une exception sera levée et un retour en arrière sera appelé.

  1. Dois-je également marquer la fonction findContinent(Long id) comme transactionnelle (readOnly = true) ? J'ai lu que toutes les méthodes par défaut comme marquées comme Transactionnelles https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

Cela dépend de l'utilisation que vous en faites. Si vous l'appelez toujours depuis @Sevice, alors non. Je pense que c'est un cas d'utilisation courant, pour autant que je sache.

  1. Dans l'interface du référentiel, dois-je marquer l'option Transactionnel au niveau de la méthode ou au niveau de l'interface. (Aussi, je suspecter que la plupart des méthodes personnalisées seront en lecture seule)

Identique au 2.

  1. Est-il bon d'avoir @Transactional à la fois dans la couche Service et dans la couche Référentiel ? et du référentiel ?

Identique au 2.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X