Home > front end >  How to use unit of work in rest controller properly?
How to use unit of work in rest controller properly?

Time:12-10

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 ?

CodePudding user response:

Your class need to be annotated with @Component to be used with DI provider by @Autowired annotation

For the same reason each repository of your class need to be annotated with @Autowired

CodePudding user response:

The Error Message gives the answer.

Field uow in com.srs.TestController required a bean of type 'com.srs.uow.UnitOfWork' that could not be found.

spring is searching for a bean from type UnitOfWork. You have to add this class to the application context from spring boot. To accomplish this you have to annotate the class UnitOfWork with @bean or @Data if you use lombok. After this the spring application can find the Class UnitOfWork and auto wire it.

CodePudding user response:

Since UnitOfWork (a somewhat misleading name in the JPA context) autowires data repositories, it has to be a Spring Bean itself.

The easiest and most common way is to annotate the class with one of the annotations @Service, @Component or @Bean, depending on the semantic of the class. There are also other ways, like the @Bean on method-level as you used.

To use the fully initialized bean you need to autowire it where you want to use it, not calling the create method. E.g. calling uow() as in your sample, bypasses the Spring Bean mechanism and creates a new instance, which hasn't been fully initialized (thus the NullPointerException).

Usually, the beans are autowired as fields, sometimes they are autowired in mehtod parameters (especially when working with @Bean on method-level in the same class).

E.g.

 @Component
 @Getter
 @RequiredArgsConstructor 
 public class UnitOfWork {

    private final CourseRepo courses;
    private final StudentRepository students;
    private final StudyProgramRepository studyPrograms;
    private final StudySchemeRepo studySchemes;
    private final FeeStructureRepository feeStructures;
}
  • Related