Je regarde dans Spring Data JPA. Considérez l'exemple ci-dessous où je ferai fonctionner toutes les fonctionnalités crud et finder par défaut et si je veux personnaliser un finder, cela peut également être fait facilement dans l'interface elle-même.
@Transactional(readOnly = true)
public interface AccountRepository extends JpaRepository<Account, Long> {
@Query("<JPQ statement here>")
List<Account> findByCustomer(Customer customer);
}
Je voudrais savoir comment puis-je ajouter une méthode personnalisée complète avec son implémentation pour le AccountRepository ci-dessus? Comme c'est une interface, je ne peux pas implémenter la méthode là-bas.
la source
AccountRepositoryImpl
not :,AccountRepositoryCustomImpl
etc. - c'est une convention de dénomination très stricte.Error creating bean with name 'accountRepositoryImpl': Bean with name 'accountRepositoryImpl' has been injected into other beans [accountRepository] in its raw version as part of a circular reference, but has eventually been wrapped.
QueryDslRepositorySupport
Vous devez également injecter le référentiel via l'injection de champ ou de setter plutôt que l'injection de constructeur, sinon il ne pourra pas créer le bean. Cela semble fonctionner mais la solution semble un peu `` sale '', je ne suis pas sûr qu'il y ait des plans pour améliorer la façon dont cela fonctionne de la part de l'équipe Spring Data.En plus de la réponse d'axtavt , n'oubliez pas que vous pouvez injecter Entity Manager dans votre implémentation personnalisée si vous en avez besoin pour créer vos requêtes:
la source
La réponse acceptée fonctionne, mais présente trois problèmes:
AccountRepositoryImpl
. La documentation indique clairement qu'il doit être appeléAccountRepositoryCustomImpl
, le nom de l'interface personnalisée plusImpl
@Autowired
qui est considérée comme une mauvaise pratiqueJ'ai trouvé un moyen de le rendre parfait, mais non sans utiliser une autre fonctionnalité Spring Data non documentée:
la source
accountRepositoryBasic
). Sinon, Spring s'est plaint qu'il y avait 2 choix de haricots pour l'injection dans mon*Impl
constructeur.AccountRepositoryBasic
etAccountRepositoryCustom
sera disponible via un injectéAccountRepository
L'utilisation est limitée, mais pour les méthodes personnalisées simples, vous pouvez utiliser des méthodes d'interface par défaut telles que:
ÉDITER:
Dans ce tutoriel de printemps, il est écrit:
Il est donc même possible de déclarer simplement une méthode comme:
et si l'objet
Hobby
est une propriété du client, Spring définira automatiquement la méthode pour vous.la source
J'utilise le code suivant pour accéder aux méthodes de recherche générées à partir de mon implémentation personnalisée. Faire passer l'implémentation via la fabrique de haricots évite les problèmes de création de haricots circulaires.
la source
Comme spécifié dans la fonctionnalité documentée , le
Impl
suffixe nous permet d'avoir une solution propre:@Repository
interface, par exempleMyEntityRepository
, des méthodes Spring Data ou des méthodes personnaliséesMyEntityRepositoryImpl
(leImpl
suffixe est la magie) n'importe où (n'a même pas besoin d'être dans le même package) qui implémente uniquement les méthodes personnalisées et annotez cette classe avec@Component
** (@Repository
ne sera pas fonctionnera ).MyEntityRepository
via@Autowired
pour une utilisation dans les méthodes personnalisées.Exemple:
Classe d'entité:
Interface du référentiel:
Bean d'implémentation des méthodes personnalisées:
Les petits inconvénients que j'ai identifiés sont:
Impl
classe sont marquées comme inutilisées par le compilateur, donc le@SuppressWarnings("unused")
suggestion.Impl
classe. (Alors que dans l'implémentation régulière des interfaces de fragment, les documents suggèrent que vous pourriez en avoir beaucoup.)la source
MyEntityRepository
, pas le*Impl
.Si vous souhaitez pouvoir effectuer des opérations plus sophistiquées, vous devrez peut-être accéder aux composants internes de Spring Data, auquel cas les opérations suivantes (comme ma solution provisoire pour DATAJPA-422 ):
la source
Compte tenu de votre extrait de code, veuillez noter que vous ne pouvez passer des objets natifs qu'à la méthode findBy ###, disons que vous souhaitez charger une liste de comptes appartenant à certains clients, une solution est de le faire,
Faites en sorte que le nom de la table à interroger soit le même que la classe Entity. Pour d'autres implémentations, veuillez consulter ceci
la source
Il y a une autre question à considérer ici. Certaines personnes s'attendent à ce que l'ajout d'une méthode personnalisée à votre référentiel les expose automatiquement en tant que services REST sous le lien '/ search'. Ce n'est malheureusement pas le cas. Spring ne prend pas en charge cela actuellement.
Il s'agit d'une fonctionnalité `` par conception '', Spring Data Rest vérifie explicitement si la méthode est une méthode personnalisée et ne l'expose pas en tant que lien de recherche REST:
C'est une question d'Oliver Gierke:
Pour plus de détails, consultez ce numéro: https://jira.spring.io/browse/DATAREST-206
la source
@RestResource(path = "myQueryMethod")
annotation à la méthode. La citation ci-dessus indique simplement que Spring ne sait pas comment vous voulez le mapper (c'est-à-dire GET vs POST, etc.), c'est donc à vous de le spécifier via l'annotation.Ajout d'un comportement personnalisé à tous les référentiels:
Pour ajouter un comportement personnalisé à tous les référentiels, vous ajoutez d'abord une interface intermédiaire pour déclarer le comportement partagé.
Désormais, vos interfaces de référentiel individuelles étendront cette interface intermédiaire au lieu de l'interface de référentiel pour inclure la fonctionnalité déclarée.
Ensuite, créez une implémentation de l'interface intermédiaire qui étend la classe de base du référentiel spécifique à la technologie de persistance. Cette classe agira alors comme une classe de base personnalisée pour les proxys du référentiel.
Spring Data Repositories Partie I. Référence
la source
J'étend le SimpleJpaRepository:
et ajoute cette classe à @EnableJpaRepositoryries repositoryBaseClass.
la source