Search code examples
javaspringspring-data

Spring Data find entity by its fields with reflection


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);
}

Solution

  • 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?