web-dev-qa-db-fra.com

Création d'un référentiel en lecture seule avec Spring Data

Est-il possible de créer des référentiels en lecture seule à l'aide de Spring Data?

J'ai des entités liées à des vues et des entités enfants pour lesquelles je voudrais fournir un référentiel avec des méthodes telles que findAll(), findOne() et des méthodes avec l'annotation @Query. J'aimerais éviter de fournir des méthodes telles que save(…) et delete(…) car elles n'ont aucun sens et pourraient créer des erreurs.

public interface ContactRepository extends JpaRepository<ContactModel, Integer>, JpaSpecificationExecutor<ContactModel> {
    List<ContactModel> findContactByAddress_CityModel_Id(Integer cityId);

    List<ContactModel> findContactByAddress_CityModel_Region_Id(Integer regionId);

    // ... methods using @Query

    // no need to save/flush/delete
}

Merci!

21
jpboudreault

Oui, la solution consiste à ajouter un référentiel de base fabriqué à la main. Vous utilisez habituellement quelque chose comme ceci:

public interface ReadOnlyRepository<T, ID extends Serializable> extends Repository<T, ID> {

  T findOne(ID id);

  Iterable<T> findAll();
}

Vous pouvez maintenant avoir vos dépôts concrets étendre celui qui vient d'être défini:

public interface PersonRepository extends ReadOnlyRepository<Person, Long> {

  T findByEmailAddress(String emailAddress);
}

La partie cruciale définissant le référentiel de base est que les déclarations de méthode portent la signature même signature que les méthodes déclarées dans CrudRepository si c'est le cas, nous pouvons toujours acheminer les appels dans le bean implémentation sauvegardant le proxy du référentiel. J'ai écrit un article de blog plus détaillé sur ce sujet dans le blog SpringSource.

44
Oliver Drotbohm

Pour développer la réponse d'Oliver Gierke, dans les versions les plus récentes de Spring Data, vous aurez besoin de l'annotation @NoRepositoryBean sur votre ReadOnlyRepository (interface parent) pour éviter les erreurs de démarrage de l'application:

import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;

@NoRepositoryBean
public interface ReadOnlyRepository<T, ID extends Serializable> extends Repository<T, ID> {

    T findOne(ID id);

    List<T> findAll();

}
20
Tristan Perry

Selon la documentation, cela est possible en implémentant org.springframework.data.repository.Repository .

6
Francisco Spaeth

Pour moi, ce qui suit a fonctionné. En utilisant la solution d'Oliver, l'erreur Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property findOne found for type apparaissait au démarrage.

@NoRepositoryBean
public interface ReadOnlyRepository<T,ID> extends Repository<T, ID> {
    Optional<T> findById(ID var1);
    boolean existsById(ID var1);
    Iterable<T> findAll();
    Iterable<T> findAllById(Iterable<ID> var1);
    long count();
}
0
Iqbal