0

I am trying to define an architecture for my project on spring boot

What I have do is to create a generic Repository that extends from JpaRepository

public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
}

After that, each EntityDao will extends from BaseRepository

@Repository    
public interface AuthorityDao extends BaseRepository<Authority, Long> {

        Authority findById(Long idRole);

        Authority findByRoleName(String findByRoleName);

    }

This is how I do it on the repository layer. At the Service Layer, I create a class named GenericService which implements IGenericService and I inject into it my BaseRepository:

@Service
public class GenericService<T, D extends Serializable> implements IGenericService<T, D> {

    @Autowired
    @Qualifier("UserDao")
    private BaseRepository<T, D> baseRepository;
// implemented method from IGenericService

}

And each Service will extends from GenericService:

public class AuthorityService extends GenericService<Authority, Long> implements IAuthorityService {

    @Autowired
    GenericService<Authority, Long> genericService;

When I run the project, I get this error:


APPLICATION FAILED TO START


Description:
Field baseRepository in fr.java.service.impl.GenericService required a bean of type 'fr.config.daogeneric.BaseRepository' that could not be found.

Action:
Consider defining a bean of type 'fr.config.daogeneric.BaseRepository' in your configuration.

How can I solve this problem?

UPDATE:

@SpringBootApplication
@EntityScan("fr.java.entities")
@ComponentScan("fr.java")
@EnableJpaRepositories("fr.java")
@EnableScheduling
@EnableAsync
@PropertySource({ "classpath:mail.properties", "classpath:ldap.properties" })
@EnableCaching
@RefreshScope
public class MainApplication extends SpringBootServletInitializer {

    private static final Logger log = LoggerFactory.getLogger(MainApplication.class);

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MainApplication.class);
    }

    public static void main(String[] args) {
        log.debug("Starting {} application...", "Java-back-end-java");

        SpringApplication.run(MainApplication.class, args);
    }

}
Hamdy
  • 430
  • 1
  • 6
  • 19

1 Answers1

0

You have this problem because you create GenericService as a bean and trying to inject BaseRepository but Spring can't do that because it isn't clear by which classes BaseRepository is parametrised.

From my side I can suggest you to do next: at first you GenericService shouldn't be a bean, all his children will be the beans, your should remove injecting of GenericService in your children classes, they already extends of it. Your GenericService should be abstract and it can have abstract method getRepository which will use inside GenericService, and injection of repository will be done in GenericService children classes.

So you should have something like this:

public abstract class GenericService<T, D extends Serializable> implements IGenericService<T,D> {
    abstract BaseRepository<T, D> getRepository();
}

@Service
public class AuthorityService extends GenericService<Authority, Long> implements IAuthorityService {

    @Autowired
    BaseRepository<Authority, Long> baseRepository;

    public BaseRepository<Authority, Long> getRepository() {
        retrurn baseRepository;
    }
}
  • thank you for your reply. this is very clever but it doesn't work. it's cannot creating a bean of base repository. I got this error: Error creating bean with name 'baseRepository': Invocation of init method failed; nested exception – Hamdy Aug 18 '18 at 16:05
  • and what this nested exception is? – Vitalii Muzalevskyi Aug 20 '18 at 12:19