Reputation: 3912
I have a few repositories that extend org.springframework.data.mongodb.repository.MongoRepository
. I have added some methods for searching entities by different parameters, however, in any search, I only want to search for entities that have the active
field set to true
(have opted for marking as active=false
in place of deleting). For example, two sample repositories would look like this:
interface XxRepository extends MongoRepository<Xx, String> {
Optional<Xx> findOneByNameIgnoreCaseAndActiveTrue(String name)
Page<Xx> findByActiveTrue(Pageable pageable)
Xx findOneByIdAndActiveTrue(String id)
}
interface YyRepository extends MongoRepository<Yy, String> {
Optional<Yy> findOneByEmailAndActiveTrue(String email)
}
Is there any way that would allow me not to add byActiveTrue
\ andActiveTrue
to each and every method and set it up somewhere in one place for all the queries?
Upvotes: 6
Views: 906
Reputation: 3960
Please try this. No need to provide implementation. Change 'active' and 'email' to your db column name.
interface YyRepository extends MongoRepository<Yy, String> {
@Query(value = "{ 'active' : { '$eq': true }, 'email' : ?0 }")
Optional<Yy> findOneByEmailAndActiveTrue(@Param("email") String email)
}
Upvotes: 4
Reputation: 734
You can write an template query into the MongoRepository using Criteria. Example
class abstract MongoRepository<W, X> {
protected Class<W> typeOfEntity;
private Class<X> typeOfId;
public MongoRepository() {
typeOfEntity = (Class<W>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
typeOfId = (Class<X>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public W get(X id) throws Exception {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<W> q = cb.createQuery(typeOfEntity);
Root<W> r = q.from(typeOfEntity);
String idName = CommonEntity.findIdFieldName(typeOfEntity);
Predicate andClose = cb.and(cb.equal(r.get("active"), true));
q.where(cb.equal(r.get(idName), id), andClose);
return em.createQuery(q).getSingleResult();
}
}
After that, you stay confident into the object running way ans stereotyping to run the good type of request.
The findIdFieldName
is an method using the @Id to get the id field name.
public abstract class CommonEntity implements Serializable {
public static String findIdFieldName(Class cls) {
for (Field field : cls.getDeclaredFields()) {
String name = field.getName();
Annotation[] annotations = field.getDeclaredAnnotations();
for (int i = 0; i < annotations.length; i++) {
if (annotations[i].annotationType().equals(Id.class)) {
return name;
}
}
}
return null;
}
}
Upvotes: 1