7

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 ?

TheKojuEffect
  • 20,103
  • 19
  • 89
  • 125

1 Answers1

11

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
Community
  • 1
  • 1
František Hartman
  • 14,436
  • 2
  • 40
  • 60
  • 4
    Thanks very much, I'm feeling stupid I didn't try removing that `@Repository` annotation, LOL. And about that second problem, I have faced that problem prior than that first one and solved it after about an hour of frustration doing some customization to my `ApplicationContext` config by using `@EnableJpaRepositories(basePackages = "packages.repo", repositoryImplementationPostfix = "CustomImpl")` – TheKojuEffect May 05 '13 at 15:09
  • didn't know about the repositoryImplementationPostfix option, +1 – František Hartman May 05 '13 at 17:26
  • You can do as `` if you're using XML based configuration. Refer to this [Reference Documentation](http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.single-repository-behaviour) for further detail. – TheKojuEffect May 06 '13 at 06:54
  • @TheKojuEffect what if we do not use xml configuration? how we can put this config by code or annotation? – Mahdi Jan 31 '17 at 13:32
  • 1
    @Kenji Check out this doc, it's even better: http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations – TheKojuEffect Jan 31 '17 at 17:28