Aymen Kanzari
Aymen Kanzari

Reputation: 2013

Parameter 0 of constructor in ..... Spring Boot

I have a problem when launch my app. Could somebody help me to solve this issue?

Parameter 0 of constructor in com.journaldev.elasticsearch.service.BookServiceImpl required a bean of type 'com.journaldev.elasticsearch.dao.search.BookRepositorySearch' that could not be found.
Action:
Consider defining a bean of type 'com.journaldev.elasticsearch.dao.search.BookRepositorySearch' in your configuration.

GenericRepository

public interface GenericRepository<T, K> {
  Map<String, Object> get(final K id);
}

GenericRepositoryImpl

public class GenericRepositoryImpl<T, K extends Serializable> implements GenericRepository<T, K> { 

  private RestHighLevelClient restHighLevelClient;

  private ObjectMapper objectMapper;

  public GenericRepositoryImpl(ObjectMapper objectMapper, RestHighLevelClient restHighLevelClient) {
    this.objectMapper = objectMapper;
    this.restHighLevelClient = restHighLevelClient;
  }

  @Override
  public Map<String, Object> get(K id) {
    return null;
  }
}

BookRepositorySearch

@Component
public interface BookRepositorySearch extends GenericRepository<Book, Long> {}

BookService

public interface BookService {
  Map<String, Object> get(final Long id);    
}

BookServiceImpl

@Service
public class BookServiceImpl implements BookService {

  private final BookRepositorySearch bookRepositorySearch;

  public BookServiceImpl(BookRepositorySearch bookRepositorySearch) {
    this.bookRepositorySearch = bookRepositorySearch;
  }      
  @Override
  public Map<String, Object> get(Long id) {
    return null;
  }
}

Upvotes: 10

Views: 75356

Answers (6)

Karan
Karan

Reputation: 499

I wasted a whole day and in the end, it was found that I was using the below dependencies in my pom.xml. may be that can help someone

<dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
        </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <scope>test</scope>
    </dependency>

on commenting on the below dependency, my code worked

<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!--            <scope>test</scope>-->
<!--        </dependency>-->

Upvotes: -1

Ibtissam Hatime
Ibtissam Hatime

Reputation: 1

You must add @EnableJpaRepositories("org.tennis.Tennnis.dao") in Prin

Upvotes: 0

MG KYAING
MG KYAING

Reputation: 51

I solved it with this configuration. Look for @EnableAutoConfiguration in your Configuration file.

@Configuration

@EnableJpaRepositories(basePackages = "com.akog02.repostories")

@EntityScan(basePackages = "com.akog02.domain")

@EnableTransactionManagement

@EnableAutoConfiguration

public class WebConfiguration {

}

Upvotes: 3

Always Learning
Always Learning

Reputation: 2713

From your previous comments, looks like you want to keep BookRepositorySearch as an interface. If that's the case, you need to create a concrete instance of that interface and put @Component on that.

You don't need @Component on your interface declaration and you can't extend a class in an interface.

public interface BookRepositorySearch {}

Create a concrete type that implements the interface and extends extends GenericRepository<Book, Long> you want to autowire and put @Component on it:

@Component
public class BookRepositorySearchImpl 
    implements BookRepositorySearch 
    extends GenericRepository<Book, Long>  
{}

https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-class-ctor

Instantiation with a constructor

When you create a bean by the constructor approach, all normal classes are usable by and compatible with Spring. That is, the class being developed does not need to implement any specific interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice. However, depending on what type of IoC you use for that specific bean, you may need a default (empty) constructor.

The Spring IoC container can manage virtually any class you want it to manage; it is not limited to managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-argument) constructor and appropriate setters and getters modeled after the properties in the container. You can also have more exotic non-bean-style classes in your container. If, for example, you need to use a legacy connection pool that absolutely does not adhere to the JavaBean specification, Spring can manage it as well.

Upvotes: 7

Jan Ossowski
Jan Ossowski

Reputation: 338

First of, You need to "tell" spring what to pass as a parameter. The simplest option is the one mentioned by @Berger in a comment. If for some reason that is not a good approach for you (eg. BookRepositorySearch is not a spring managed bean), you can make a java config file with some more logic:

@Configuration
public class Config {

   // you can use @Autowired here


   @Bean
   public BookService bookService() {
      return new BookServiceImpl(--pass your parameter here, get it however you want--)
   }

}

edit:

Apparently Spring doesn't require @Autowired anymore (thanks @Mark Rotteveel). So the problem is that spring doesn't have an instance of your class. The reason for that is (I think) that you use a class parameter instead of an interface. If You just create a marker interface that BookRepositorySearch implements and use that as an argument instead of the actual inplementation, I would expect it to work. Another solution is what I wrote above already, but for the BookRepositorySearch class.

@Configuration
public class Config {

   // you can use @Autowired here


   @Bean
   public BookRepositorySearch bookRepositorySearch () {
      return new BookRepositorySearch();
   }

}

This way Spring will have it's beloved instance ;)

Upvotes: 1

developer-guy
developer-guy

Reputation: 157

How do you inherit a class as an interface?

  @Component 
  public interface BookRepositorySearch extends GenericRepository<Book, Long> {}

Change this interface with a class then try again.

  @Component
  public class BookRepositorySearch extends GenericRepository<Book, Long> {}

Upvotes: 0

Related Questions