Printemps de Données par défaut de substitution méthodes de certains dépôts
Je suis juste en regardant avec spring-data
et spring-data-rest
et je veux vraiment profiter de ce que ces outils ont à offrir. Pour la plupart des cas, la fonctionnalité de base est parfait pour mon cas d'utilisation cependant, il existe certains cas où j'ai besoin de personnaliser les fonctionnalités de base un peu, et de manière sélective affecter certains dépôts d'hériter de la mesure de la fonctionnalité que je suis après.
Pour expliquer le problème un peu mieux, en spring-data
il y a 2 interfaces possibles de laquelle vous pouvez hériter de la fonctionnalité de, CrudRepository
ou PagingAndSortingRepository
. Je veux ajouter un troisième appelé disons PesimisticRepository
Tous les PesimisticRepository
n'est de gérer la notion de supprimé @Entity différemment. Un supprimé entité est celui où ses supprimé propriété est NOT NULL
. Cela signifie qu'un @Entité qui peut être manipulé par un PesimisticRepository
a avoir un supprimé propriété.
Tout cela est possible, j'ai effectivement mis en œuvre il y a deux ans. (Vous pouvez le vérifier ici dans le cas où vous êtes intéressé)
Ma tentative à l'aide de printemps-les données sont les suivantes:
Une extension de la PagingAndSortingRepository
package com.existanze.xxx.datastore.repositories;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.io.Serializable;
@NoRepositoryBean
public interface PesimisticRepository<T,ID extends Serializable> extends PagingAndSortingRepository<T,ID> {
}
Pour qui j'ai de fournir une implémentation par défaut l'extension de JPARepository
package com.existanze.xxx.datastore.repositories;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.Serializable;
import java.util.Date;
public class JpaPesimisticRepository<T,ID extends Serializable> extends SimpleJpaRepository<T,ID> implements PesimisticRepository<T,ID> {
private final EntityManager entityManager;
public JpaPesimisticRepository(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
this.entityManager = em;
}
@Override
@Transactional
public Page<T> findAll(Specification<T> spec, Pageable pageable) {
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = cb.createQuery(getDomainClass());
Root<T> from = criteriaQuery.from(this.getDomainClass());
Predicate deleted = cb.equal(from.get("deleted"), cb.nullLiteral(Date.class));
criteriaQuery.select(from).where(deleted);
TypedQuery<T> query = this.entityManager.createQuery(criteriaQuery);
return pageable == null ? new PageImpl<T>(query.getResultList()) : readPage(query, pageable, spec);
}
}
Et puis pour les bean pour laquelle je souhaite gérer la suppression à l'aide de l'pessimiste méthode que je définir comme tel
package com.existanze.xxx.datastore.repositories;
import com.existanze.xxx.domain.Phone;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource
public interface PhoneRepository extends PesimisticRepository<Phone,Integer> {
}
Il est important d'expliquer pourquoi je souhaite remplacer ces méthodes au lieu de fournir de nouvelles personnalisées, comme findAllButDeleted
. La raison en est parce que je veux aussi que le pessimiste supprimer pour descendre spring-data-rest
. De sorte que les points de terminaison HTTP généré n'aurez pas besoin de toute forme de personnalisation.
Cela semble fonctionner pour le findAll
méthode. Cependant, pour le reste des méthodes actuelles exception est levée.
$ curl http://localhost:8881/phones/23
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 500 </title>
</head>
<body>
<h2>HTTP ERROR: 500</h2>
<p>Problem accessing /phones/23. Reason:
<pre> org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: object is not an instance of declaring class; nested exception is java.lang.IllegalArgumentException: object is not an instance of declaring class</pre></p>
<hr /><i><small>Powered by Jetty://</small></i>
</body>
</html>
En outre, j'ai lu la documentation qui vous permet de modifier la valeur par défaut JpaRepository pour tous les Référentiels, mais encore une fois j'ai besoin pour ce faire sur un référentiel de base.
J'espère avoir été suffisamment descriptif. S'il vous plaît laissez-moi savoir dans la section commentaires si il ya quelque chose qui a besoin d'une meilleure explication.
OriginalL'auteur Fotis Paraskevopoulos | 2015-01-14
Vous devez vous connecter pour publier un commentaire.
Vous pouvez créer un référentiel, quelque chose comme ceci:
Vous aurez besoin de trop une usine sur mesure de la fève à la configuration personnalisée des dépôts. Ressembler à ceci:
Et enfin, le contexte de l'application de configuration.
Commun des référentiels de configuration ressembler à ceci:
Et de la coutume, comme ceci (vous pouvez ou ne pas utiliser separeted EMF et gestionnaire de transactions):
L'exemple 1, en utilisant JpaRepository:
L'exemple 2, à l'aide personnalisée référentiel:
Cela fait partie de ce que je fais habituellement. Si vous avez besoin, je peux créer une application de base comme un exemple.
Oui, j'ai lu ce que vous dites. C'est un moyen de faire ce dont vous avez besoin, créer un référentiel pour les entités personnalisées. BTW, est plus un problème conceptuel que technique.
Mais comment voulez-vous éviter les entités qui ne s'étend pas CustomGenericRepository, pour devenir CustomGenericRepositoryImpl? Qui est ce qui se passe avec votre exemple? J'ai besoin de la distinction entre les Dépôts
Je suppose que la magie sera dans le
getRepositoryBaseClass
etgetTargetRepository
méthodes - là, vous pourriez peut-être vérifier la incommingRepositoryMetadata
et le retour de différents types sur la base des Métadonnées?bon point, qui est une manière de tester 🙂
OriginalL'auteur Bruno César