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