0

Having a lot of duplicate code in a lot of service classes, I decided to move it to a base service class and then re-use it.

public class BaseService<ENTITY, ID> {

@Autowired
private BaseDao<ENTITY, ID> baseDao;

protected boolean isExist(ENTITY e) {
    Map<Field, Object> allValues = ReflectUtils.getAllValues(e);
    //...

}

}

In isExist(ENTITY e) method I'd like to call a baseDao method to find an entity (at the runtime it has to know which exact entity) and pass allValues to it. Basically, I'd like to know if it's possible to do smth like this with Spring Data:

public interface BaseDao<ENTITY, ID> extends JpaRepository<ENTITY, ID> {

Optional<ENTITY> findByFields(Map<Field, Object> allValues);
}
  • 1
    I believe it's not possible with `Map` parameter. But it should be doable by combining your reflective approach to create examples and using the [Query by Example API](https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#query-by-example). A guide about it - [Spring Data JPA Query by Example](https://www.baeldung.com/spring-data-query-by-example). – Chaosfire Jun 16 '23 at 10:07
  • @Chaosfire thx. That's exactly what I need. Can I accept your answer? – Iva_Only_Java Jun 16 '23 at 10:46
  • I added it as an answer. – Chaosfire Jun 16 '23 at 15:46

1 Answers1

1

You can't do that by providing Map parameter to a repository method, but it's possible by combining the reflective approach with spring's Query By Example API. Simplified example:

public <Entity> Optional<Entity> findByFields(Map<Field, Object> allValues) throws IllegalAccessException {
  Entity entity = create an instance;
  for (Map.Entry<Field, Object> entry : allValues.entrySet()) {
    //allow access to the field
    entry.getKey().set(entity, entry.getValue());
    //restore access to previous state
  }
  Example<Entity> example = Example.of(entity);
  return queryByExampleExecutor.findOne(example);
}

Probably helpful questions:

  1. Set field value with reflection
  2. Spring Data JPA: Query by Example?
Chaosfire
  • 4,818
  • 4
  • 8
  • 23