【问题标题】:How to use unit of work in rest controller properly?如何正确使用休息控制器中的工作单元?
【发布时间】:2022-01-14 17:24:26
【问题描述】:
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.

如果我删除 autowired 并添加一个 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:无法调用“com.srs.jpa.CourseRepo.save(Object)” 因为“com.srs.uow.UnitOfWork.getCourses()”的返回值为null

我尝试了 autowired,在这种情况下,我该如何正确使用 autowired 或 bean?

【问题讨论】:

  • 向 UnitOfWork 添加“@Component”注释。此外,您可以将 for lombok 注释替换为 @Data 注释(它是启用您添加的 4 个注释的快捷方式)。
  • 是的,它有效。非常感谢您抽出宝贵的时间 :) 我喜欢 stack over flow。

标签: spring spring-boot spring-mvc spring-data-jpa unit-of-work


【解决方案1】:

您的类需要使用@Component 进行注释,以便通过@Autowired 注释与DI 提供程序一起使用

出于同样的原因,您的类的每个存储库都需要使用 @Autowired 进行注释

【讨论】:

    【解决方案2】:

    错误信息给出了答案。

    com.srs.TestController 中的字段 uow 需要一个无法找到的“com.srs.uow.UnitOfWork”类型的 bean。

    spring 正在从 UnitOfWork 类型中搜索一个 bean。您必须从 Spring Boot 将此类添加到应用程序上下文中。要做到这一点,如果您使用 lombok,您必须使用 @bean@Data 注释 UnitOfWork 类。 在此之后,spring 应用程序可以找到 Class UnitOfWork 并自动连接它。

    【讨论】:

      【解决方案3】:

      由于 UnitOfWork(JPA 上下文中的一个有点误导的名称)自动连接数据存储库,它本身必须是一个 Spring Bean。

      最简单和最常用的方法是使用注释@Service@Component@Bean 之一来注释类,具体取决于类的语义。还有其他方法,例如您使用的方法级别的@Bean

      要使用完全初始化的 bean,你需要在你想使用它的地方自动装配它,而不是调用 create 方法。例如。在您的示例中调用 uow() 会绕过 Spring Bean 机制并创建一个尚未完全初始化的新实例(因此是 NullPointerException)。

      通常,bean 会作为字段自动装配,有时它们会在 mehtod 参数中自动装配(尤其是在同一类的方法级别使用 @Bean 时)。

      例如

       @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;
      }
      

      【讨论】:

      • 非常感谢您的详细解答。现在概念很清楚了。
      猜你喜欢
      • 2017-03-10
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      • 2022-10-18
      • 2019-03-27
      • 2018-07-31
      • 1970-01-01
      • 2013-11-10
      相关资源
      最近更新 更多