Reputation: 11758
I found a strange behaviour in my Spring App.
The @autowired of an Entity is not working all the time.
I use the Elide project to build an JSONAPI and some custom controllers.
In one controller, one @Autowrited of an entity stays null however it use correctly working when called from Elide.
Controller:
@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 "";
}
}
Entity
@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
@Repository
@Transactional
public interface ItemRepository extends JpaRepository<Item, Long> {
Integer countByProjectId(long projectId);
}
Configuration
@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");
}
};
}
}
I don't understand why but the itemRepository
in null in Project.getNumberOfItems
.
Upvotes: 1
Views: 513
Reputation: 363
An Entity
should be a glorified POJO
, never complicate it embedding repos inside
so autowire ItemRepository
a level up, atUploadController
itself.
@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 "";
}
}
and as a good practice, you can always do a constructor injection making it easy to test
e.g. instead of
@Autowired
private ProjectRepository projectRepo;
@Autowired
private ItemRepository itemRepo;
do a constructor injection
private final ProjectRepository projectRepo;
private final ItemRepository itemRepo;
@Autowired
public UploadController(final ProjectRepository projectRepo, final ItemRepository itemRepo) {
this.projectRepo = projectRepo;
this.itemRepo = itemRepo;
}
this way,
@Autowire
on variable directly)Upvotes: 0
Reputation: 22343
The problem you have is, that your Project
is no managed by spring. You have to add the @Configurable
annotation to your class. Then your Autowired
annotation will work.
But I would really refactor your code. You should not have spring-objects in your Entities.
Upvotes: 1
Reputation: 464
This is not a way how you should do that. Don't use @Autowired
in your entities. This annotation is managed by Spring, but your entities are managed and created by Hibernate and it doesn't care about Spring annotations. You could find another way to add this property to your entity(let it be field in a database for example).
Upvotes: 3