es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo utilizar correctamente la unidad de trabajo en un controlador REST?

public interface CourseRepo extends CrudRepository<Course, Long> {

}

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor 
public class UnitOfWork {
    CourseRepo courses;
    StudentRepository students;
    StudyProgramRepository studyPrograms;
    StudySchemeRepo studySchemes;
    FeeStructureRepository feeStructures;
}

@RestController
public class TestController {

    @Autowired
    UnitOfWork uow;

    @GetMapping("/addcr")
    public String addCourse() {
        Course cr = new Course();
        cr.setTitle("DingDong course");
        uow.getCourses().save(cr);
        return "course Added..!!" ;
    }
}
APPLICATION FAILED TO START

Description:
Field uow in com.srs.TestController required a bean of type 'com.srs.uow.UnitOfWork' that could not be found.
The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)

Action:
Consider defining a bean of type 'com.srs.uow.UnitOfWork' in your configuration.

If I remove @Autowired and add a bean

@RestController
public class TestController {

    @Bean
    public UnitOfWork uow() {
        return new UnitOfWork();
    }

    @GetMapping("/addcr")
    public String addCourse() {
        Course cr = new Course();
        cr.setTitle("DingDong course");
        uow().getCourses().save(cr);
        return "course Added..!!" ;
    }
}

java.lang.NullPointerException: Cannot invoke "com.srs.jpa.CourseRepo.save(Object)" because the return value of "com.srs.uow.UnitOfWork.getCourses()" is null.

I tried both @Autowired and in this case, how can I use @Autowired or @Bean properly?
“`

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error indica que el contenedor Spring no puede encontrar un bean del tipo UnitOfWork para inyectarlo en la clase TestController.

    Para usar Autowired correctamente, debes asegurarte de que el bean UnitOfWork esté configurado y registrado correctamente en el contenedor Spring. Una forma de hacer esto es definirlo como un bean en una clase de configuración:

    @Configuration
    public class AppConfig {
    
      @Bean
      public UnitOfWork uow(CourseRepo courses, StudentRepository students, 
                            StudyProgramRepository studyPrograms, 
                            StudySchemeRepo studySchemes, FeeStructureRepository feeStructures) {
        return new UnitOfWork(courses, students, studyPrograms, studySchemes, feeStructures);
      }
    
      // otras definiciones de beans...
    }
    

    Luego, podrás usar @Autowired para inyectar el bean UnitOfWork en el controlador:

    @RestController
    public class TestController {
    
        @Autowired
        UnitOfWork uow;
    
        @GetMapping("/addcr")
        public String addCourse() {
    
            Course cr = new Course();
            cr.setTitle("Curso DingDong");
            uow.getCourses().save(cr);
    
            return "¡Curso agregado!";
        }
    }
    

    La NullPointerException que encuentras con tu implementación actual de TestController se debe a que estás llamando al método uow() para obtener una nueva instancia de UnitOfWork en cada llamada al método, en lugar de obtener la instancia autowired. Esta nueva instancia no tiene el bean CourseRepo correctamente inyectado en ella, de ahí la NullPointerException.

    Entonces, si quieres definir UnitOfWork como un bean dentro del controlador, debes asegurarte de que todas las dependencias necesarias estén correctamente inyectadas en él:

    @RestController
    public class TestController {
    
        @Bean
        public UnitOfWork uow(CourseRepo courses, StudentRepository students, 
                            StudyProgramRepository studyPrograms, 
                            StudySchemeRepo studySchemes, FeeStructureRepository feeStructures) {
          return new UnitOfWork(courses, students, studyPrograms, studySchemes, feeStructures);
        }
    
        @GetMapping("/addcr")
        public String addCourse() {
    
            Course cr = new Course();
            cr.setTitle("Curso DingDong");
            uow.getCourses().save(cr);
    
            return "¡Curso agregado!";
        }
    }
    

    Ten en cuenta que en este caso, no puedes usar @Autowired para inyectar el bean UnitOfWork en el controlador, ya que el bean se define dentro de la misma clase.

Comments are closed.