我在Spring应用程序中发现了一个奇怪的行为。
实体的@autowired一直无法正常工作。
我使用Elide项目来构建JSONAPI和一些自定义控制器。
在一个控制器中,一个实体的@Autowrited保持为空,但是当从Elide调用时,它使用正常。
控制器:
@RestController
public class UploadController {
@Autowired
private ProjectRepository projectRepository;
@PostMapping(value = "/api/projects/{projectId}/upload")
public String uploadItem(@PathVariable long projectId, @RequestParam("file") MultipartFile file,
@RequestParam("projectName") String projectName,
RedirectAttributes redirectAttributes) throws IOException {
Project project = projectRepository.findOneByProjectIdAndName(projectId, projectName);
Integer result = project.getNumberOfItems();
return "";
}
}
实体
@Setter
@NoArgsConstructor
@Table(name = "projects")
@Entity
@Include(rootLevel = true, type = "projects")
public class Project extends DiffShelfBase {
@Autowired
@Transient
private ItemRepository itemRepository;
@Transient
@ComputedAttribute
public Integer getNumberOfItems() {
return itemRepository.countByProjectId(this.getId());
}
}
存储库
@Repository
@Transactional
public interface ItemRepository extends JpaRepository<Item, Long> {
Integer countByProjectId(long projectId);
}
配置
@Configuration
@EnableSpringConfigured
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*")
.allowedOrigins("http://localhost:4200");
}
};
}
}
我不明白为什么,但是itemRepository
中的Project.getNumberOfItems
为空。
答案 0 :(得分:3)
这不是您应该怎么做的方法。不要在您的实体中使用@Autowired
。这个注释是由Spring管理的,但是您的实体是由Hibernate管理和创建的,它并不关心Spring注释。您可以找到另一种将此属性添加到实体的方法(例如,使其成为数据库中的字段)。
答案 1 :(得分:1)
您遇到的问题是,Project
不能由spring管理。您必须在课程中添加@Configurable
批注。然后您的Autowired
批注将起作用。
但是我真的会重构您的代码。您的实体中不应包含弹簧对象。
答案 2 :(得分:0)
Entity
应该是光荣的POJO
,切勿使其复杂化,将其嵌入存储库中
因此在ItemRepository
本身上自动上线UploadController
。
@RestController
public class UploadController {
@Autowired
private ProjectRepository projectRepo;
@Autowired
private ItemRepository itemRepo;
@PostMapping(value = "/api/projects/{projectId}/upload")
public String uploadItem(@PathVariable long projectId, @RequestParam("file") MultipartFile file,
@RequestParam("projectName") String projectName,
RedirectAttributes redirectAttributes) throws IOException {
Project project = projectRepo.findOneByProjectIdAndName(projectId, projectName);
Integer result = itemRepo.countByProjectId(project.getId());
return "";
}
}
作为一种好的实践,您总是可以进行构造函数注入,从而使其易于测试
例如代替
@Autowired
private ProjectRepository projectRepo;
@Autowired
private ItemRepository itemRepo;
进行构造函数注入
private final ProjectRepository projectRepo;
private final ItemRepository itemRepo;
@Autowired
public UploadController(final ProjectRepository projectRepo, final ItemRepository itemRepo) {
this.projectRepo = projectRepo;
this.itemRepo = itemRepo;
}
这样
@Autowire
不可能)