Implement custom behaviour to a repository method in spring-data-jpa

circular-dependency, dependency-injection, spring, spring-data-jpa

Solution

There are two problems with your classes:

remove @Repository annotation from this declaration:

@Repository
public interface ProductRepositoryCustom {

This will solve your current issue but another one will appear.

The solution to this is to rename

ProductRepositoryCustomImpl

to

ProductRepositoryImpl

Problem

I'm trying to implement custom behaviour to a method in Repository using `spring-data-jpa`. The `ProductRepository` interfaces is ``` @Repository public interface ProductRepository extends JpaRepository, ProductRepositoryCustom { public List findByProductName(String productName); } ``` The `ProductRepositoryCustom` interface contain a `saveCustom` to which I want to implement custom behaviour. ``` @Repository public interface ProductRepositoryCustom { public Product saveCustom(Product product); } ``` This is the implementation for `ProductRepositoryCustom` interface. The method `saveCustom` here is just an example. What I really want to do is define a custom method such that it contains a series of instructions involving core `JpaRepository` methods. For that I tried to inject `ProductRepository` instances but I got errors as shown below. ``` public class ProductRepositoryCustomImpl implements ProductRepositoryCustom { @Inject private ProductRepository repo; @Override public Product saveCustom(Product product) { // other executions of methods in ProductRepository(repo) return repo.save(product); } } ``` This is simple `ServerApp` application that I run. ``` public class ServerApp { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext( AppContext.class); ProductRepository repo = context.getBean(ProductRepository.class); Product testProduct = new Product(); testProduct.setProductName("Test Product"); repo.saveCustom(testProduct); } } ``` This is the stacktrace of program when I start the `ServerApp`. ``` Exception in thread "main" org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'productRepositoryCustomImpl': Bean with name 'productRepositoryCustomImpl' has been injected into other beans [productRepository] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:551) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.context.annotation.AnnotationConfigApplicationContext.(AnnotationConfigApplicationContext.java:73) at devopsdistilled.operp.server.ServerApp.main(ServerApp.java:16) ``` What can I do to implement custom behaviour like `saveCustom` ?

Original source