Skip to content

Spring cannot create UserService bean

Dao tier. I have abstract jpa dao interface, extended interface, and I added abstract implementation, from which I extend other real used implementations. These classes as follows:

public interface AbstractDao<E> {

    E findById(Long id);

    List<E> findAll();

    void save(E entity);

    void update(E entity);

    void delete(E entity);

    void deleteById(Long entityId);

}
public interface UserDao extends AbstractDao<User> {
}
public abstract class AbstractDaoImpl<E> implements AbstractDao<E> {

   private final Class<E> clazz;

   @PersistenceContext
   protected EntityManager entityManager;

   public AbstractDaoImpl(Class<E> clazz) {
      this.clazz = clazz;
   }

   @Override
   public E findById(Long id) {
      return entityManager.find(clazz, id);
   }

   @SuppressWarnings("unchecked")
   @Override
   public List<E> findAll() {
      return entityManager
              .createQuery("from " + clazz.getName())
              .getResultList();
   }

   @Override
   public void save(E entity){
      entityManager.persist(entity);
   }

   @Override
   public void update(E entity){
      entityManager.merge(entity);
   }

   @Override
   public void delete(E entity) {
      entityManager.remove(entity);
   }

   @Override
   public void deleteById(Long entityId){
      E entity = findById(entityId);
      delete(entity);
   }
}
@Repository
public class UserDaoImpl extends AbstractDaoImpl<User> implements UserDao {
    public UserDaoImpl() {
        super(User.class);
    }
}

Service tier. Here I also have abstract service interface, one extended interface (UserService) and its abstract and real implementations:

public interface AbstractService<E, DTO> {
    E findById(Long id);

    List<E> findAll();

    void save(E entity);

    void update(E entity);

    void delete(E entity);

    void deleteById(Long entityId);

    DTO convertToDTO(E entity);
}
public interface UserService extends AbstractService<User, UserDTO> {
}
@Getter @Setter @AllArgsConstructor
public abstract class AbstractServiceImpl<E, D extends AbstractDao<E>, DTO> implements AbstractService<E, DTO> {

    private D dao;
    private ModelMapper mapper;

    @Override
    public E findById(Long id) {
        return dao.findById(id);
    }

    @Override
    public List<E> findAll() {
        return dao.findAll();
    }

    @Override
    public void save(E entity) {
        dao.save(entity);
    }

    @Override
    public void update(E entity) {
        dao.update(entity);
    }

    @Override
    public void delete(E entity) {
        dao.delete(entity);
    }

    @Override
    public void deleteById(Long entityId) {
        dao.deleteById(entityId);
    }


}
@Service
public class UserServiceImpl extends AbstractServiceImpl<User, UserDao, UserDTO> implements UserService {

    @Autowired
    public UserServiceImpl(UserDao dao, ModelMapper mapper) {
        super(dao, mapper);
    }

    @Override
    public UserDTO convertToDTO(User entity) {
        return getMapper().map(entity, UserDTO.class);
    }
}

In my real project I got many extended interfaces from AbstractDao and AbstractServie. You can see the actual hierarchy: enter image description here

I can’t understand why spring can’t create @Service annotated beans and autowire those in my Controllers. Any help would be appreciated.

Answer

I took the liberty to look into your project in github https://github.com/tuanalexeu/JavaSchoolFinalTask

The problem is how you initialize your spring contexts, The AppConfig context is not read at all. This context has all your configurations.

By modifying your initializer to include your AppConfig as root, all beans should be present in the same context. (You can also choose to have parent -> child contexts as well, but that too should be done in the initializer). Hope it helps. Good luck.

public class MainWebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(final ServletContext sc) throws ServletException {

        AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
        root.register(AppConfig.class);
        
        Dynamic servlet = sc.addServlet("dispatcher", new DispatcherServlet(root));
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");

        sc.addListener(new ContextLoaderListener(root));
        sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
                .addMappingForUrlPatterns(null, false, "/*");

    }
}