0

I'm using SpringBoot and I am trying to create a service layer for my web application but i cant make it work.

My classes look like this

ServiceFactory

@Service
public class ServiceFactory {

  @Autowired
  public static EncuestaService getEncuestaService()
  {
    return new EncuestaServiceImpl();
  }
}

EncuestaService

public interface EncuestaService {

void crearEncuesta(Encuesta encuesta, Map<String,String> parametros);

}

EncuestaServiceImpl

@Service
public class EncuestaServiceImpl implements EncuestaService {

@Override
public void crearEncuesta(Encuesta encuesta, Map<String, String> parametros) {
    CrearEncuesta nueva = new CrearEncuesta(encuesta,parametros);
    nueva.execute();
   }
}

CrearEncuesta

@Service
public class CrearEncuesta {

private Encuesta encuesta;
private Map<String,String> parametros;

@Autowired
private RespuestasRepository respuestasRepository;
@Autowired
private EncuestasRepository encuestasRepository;

public CrearEncuesta(Encuesta encuesta, Map<String,String> parametros) {
    super();
    this.encuesta = encuesta;
    this.parametros = parametros;
}



public void execute()
{
    encuestasRepository.save(encuesta);
}
}

Everytime I call ServiceFactory.getEncuestasService().crearEncuesta() from any Controller it returns me a NullPointerException.

From what I have been reading I should not be creating a new EncuestsaServiceImpl() in my ServiceFactory but I don't really know the correct way to do so. I would appreciate if anyone could help me out :P.

Edit:

@SpringBootApplication
public class Application {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

Controller

@Controller
public class EncuestaController {
@RequestMapping(value ="registrarEncuesta", method = RequestMethod.POST)
private String formularioEncuesta(@Valid @ModelAttribute("formEncuesta") EncuestaForm formEncuesta, BindingResult bindingResult,@RequestParam Map<String,String> allRequestParams)
{
    if (bindingResult.hasErrors()) {
            return "nuevaEncuesta";
        }
        try {
        Encuesta nueva = formEncuesta.toEncuesta();
        ServiceFactory.getEncuestaService().crearEncuesta(nueva,allRequestParams);
        } catch (DataIntegrityViolationException e) {
                return "nuevaEncuesta";
         }
    return "redirect:/encuestas";
 }
}
QoP
  • 27,388
  • 16
  • 74
  • 74

1 Answers1

0

You will have to read a little bit more about dependency injection. The central principle in Spring Framework is dependency injection which should be used to avoid referencing beans (service implementations, repository implementations etc...) statically. Spring container also servers as a bean factory that will instantiate and inject (autowire) implementations to beans that need them.

Because Spring will instantiate service interface implementations for you, you don't need ServiceFactory. In your controller you need to add a reference (a field) to EncuestaService and annotate it as Autowired and Spring will wire in the implementation. And then you can just use it in your controller.

@Controller
public class EncuestaController {

@Autowired
EncuestaService encuestaService;

@RequestMapping(value ="registrarEncuesta", method = RequestMethod.POST)
private String formularioEncuesta(@Valid @ModelAttribute("formEncuesta") EncuestaForm formEncuesta, BindingResult bindingResult,@RequestParam Map<String,String> allRequestParams)
{
    if (bindingResult.hasErrors()) {
            return "nuevaEncuesta";
        }
        try {
        Encuesta nueva = formEncuesta.toEncuesta();
        encuestaService.crearEncuesta(nueva,allRequestParams);
        } catch (DataIntegrityViolationException e) {
                return "nuevaEncuesta";
         }
    return "redirect:/encuestas";
 }
}
Krešimir Nesek
  • 5,302
  • 4
  • 29
  • 56