Skip to content
Advertisement

Custom Repository Implementation is not being recognized

I am currently working on a project where I have created the following custom Repository:

public interface ServiceRepository<T extends ServiceEntity> extends JpaRepository<T, UUID>, ServiceRepositoryCustom {
}

public interface ServiceRepositoryCustom {
    List<ServiceEntity> findAllContainingName(String query);
}

@Repository("Repo")
public class ServiceRepositoryCustomImpl implements ServiceRepositoryCustom {


    private final EntityManager em;

    public ServiceRepositoryCustomImpl(EntityManager em) {
        System.out.println("I got constructed");
        this.em = em;
    }

    @Override
    public List<ServiceEntity> findAllContainingName(String name) {
        System.out.println("I got called with: " + name);
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<ServiceEntity> cq = cb.createQuery(ServiceEntity.class);

        Root<ServiceEntity> serviceEntity = cq.from(ServiceEntity.class);
        List<Predicate> predicates = new ArrayList<>();

        if(name != null)  {
            // predicates.add(cb.equal(serviceEntity.get("name"), name));
            predicates.add(cb.like(serviceEntity.get("name"), name + "%"));
        }
        cq.where(predicates.toArray(predicates.toArray(new Predicate[0])));

        return em.createQuery(cq).getResultList();
    }
}

The print statement “I got called with: ” never gets called. So for whatever reason Spring Boot is not running the method through my custom implementation.

Any suggestions? Any help is much appreciated

Edit: Here is the code that injects and uses the Repository in question

@Repository
public interface PineappleServiceRepository extends ServiceRepository<PineappleServiceEntity> {
}

@Component("Registry")
@DependsOn({"Context", "Repo"})
public class Registry {
    private final List<ServiceRepository<? extends ServiceEntity>> serviceRepositories = new ArrayList<>();

    public Registry(PineappleServiceRepository pineappleServiceRepository) {
        this.serviceRepositories.add(pineappleServiceRepository);
    }
}

Edit 2: The code prints “I got constructed”

Edit 3: Class where findAllContainingName is called

@RestController
@RequestMapping("/test")
@DependsOn("Registry")
public class ServiceController {

    private final Registry registry;

    public ServiceController(@NotNull Registry registry) {
        this.registry = registry;
    }

    @GetMapping("")
    List<ServiceEntity> all(@RequestParam("q") String query) {
        return getAllServices(query);
    }

    private @NotNull List<ServiceEntity> getAllServices(String query) {
        List<ServiceEntity> response = new ArrayList<>();
        for(ServiceRepository<? extends ServiceEntity> repo: this.registry.getServiceRepositories()){
             response.addAll(repo.findAllContainingName(query));
        }
        return response;
    }
}

Edit 4:

Here the entities:

@Entity
@Table(name = "services")
public abstract class ServiceEntity {

    protected @Id
    UUID id = UUID.randomUUID();
    protected String name;

    // Constructor + Getters and Setters
}

@Entity
public class PineappleServiceEntity extends ServiceEntity {
    // Additional Properties, matching Constructors, Getters and Setters
}

Advertisement

Answer

So I was able to reproduce your problem and fix it. Issue with your code is that your PineappleServiceRepository is not extending ServiceRepositoryCustom directly. It seems your repository needs to implement it directly if you are accessing custom repository methods from that repository. I got that idea from this post.

So to fix your issue, either remove PineappleServiceRepository(as you don’t have any properties in PineappleEntity) and use ServiceRepository to call that custom method or make PineappleServiceRepository extend ServiceRepositoryCustom.

I have pushed changes to GitHub with fix. You can take a look. If you want to keep PineappleServiceRepository and access custom method using this repository, let me know, I can update code.

6 People found this is helpful
Advertisement