Soy bastante nuevo en JPA / Hibernate y spring boot, y me gustaría hacer consultas dinámicas en función de los parámetros recibidos. Estaba siguiendo este enfoque https://www.baeldung.com/spring-data-jpa -consulta, pero tengo una duda cuando dice: "Además, debemos asegurarnos de incluir el postfix Impl en el nombre de la clase. Spring buscará la implementación UserRepositoryCustom como UserRepositoryCustomImpl. Dado que los fragmentos no son repositorios por sí mismos , Spring confía en este mecanismo para encontrar la implementación del fragmento ".

Qué significa ? ¿Cómo puedo incluir el postfix Impl en el nombre de la clase?

Gracias

0
Antonio Diaz 22 jun. 2020 a las 19:10

2 respuestas

La mejor respuesta

Significa que si necesita algún método personalizado en su repositorio, debe declarar una interfaz de la siguiente manera

public interface UserRepositoryCustom {
List<User> findUserByEmails(Set<String> emails);
}

Y ahora debe proporcionar la implementación de la interfaz de la siguiente manera

public class UserRepositoryCustomImpl implements UserRepositoryCustom {

@PersistenceContext
private EntityManager entityManager;

@Override
public List<User> findUserByEmails(Set<String> emails) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<User> query = cb.createQuery(User.class);
    Root<User> user = query.from(User.class);

    Path<String> emailPath = user.get("email");

    List<Predicate> predicates = new ArrayList<>();
    for (String email : emails) {
        predicates.add(cb.like(emailPath, email));
    }
    query.select(user)
        .where(cb.or(predicates.toArray(new Predicate[predicates.size()])));

    return entityManager.createQuery(query)
        .getResultList();
}
}

Spring intentará encontrar la implementación de la interfaz con el postfix Impl y aquí está UserRepositoryCustomImpl (nombre de la interfaz: UserRepositoryCustom + Impl (postfix)). si prefiere otro postfix, puede agregar @EnableJpaRepositories( repositoryImplementationPostfix = "Impl2", ) en su configuración aquí Impl2 es tu arreglo de publicación personalizado. Por lo tanto, el nombre de la clase de implementación debe ser UserRepositoryCustomImpl2

1
Tanmoy Majumdar 22 jun. 2020 a las 16:28

Supongamos que tiene una entidad Person. Creas una interfaz de repositorio para eso.

public interface PersonRepository extends JpaRepository<Person, String>{}

Entonces necesitas una lógica personalizada. Entonces creas una interfaz de repositorio personalizada:

@NoRepositoryBean
public interface CustomPersonRepository { 
   [...]
}

Y la clase de implementación con postfix Impl:

@Repository
public class CustomPersonRepositoryImpl implements CustomPersonRepository{
   
   @PersistenceContext
   private EntityManager entityManager;

   [...]
}

Ahora agrega la interfaz personalizada a la interfaz del repositorio original:

public interface PersonRepository extends JpaRepository<Person, String>,CustomPersonRepository{

}

Cuando @Autowired la interfaz PersonRepository, y llama a un método en los beans inyectados que pertenece a CustomPersonRepository, Spring utilizará el método de CustomPersonRepositoryImpl.

Por lo tanto, el nombre de la clase de implementación debe ser el mismo nombre que la interfaz personalizada + un Impl al final. Puede parametrizar ese postfix de todos modos con la propiedad repositoryImplementationPostfix en la anotación @EnableJpaRepositories.

0
zlaval 22 jun. 2020 a las 16:24