Why can't #Autowired a JPA repository - Spring boot + JPA - spring-boot

I'm giving this error:
Parameter 0 of constructor in x.microservice.module.business.application.BusinessCreator required a bean of type 'x.microservice.module.business.infrastructure.HibernateJpaRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=false)
Action:
Consider defining a bean of type 'x.microservice.module.business.infrastructure.HibernateJpaRepository' in your configuration.
The controller:
#Slf4j
#RestController
public final class BusinessPostController {
#Autowired
private BusinessCreator creator;
#PostMapping(value = "/business")
public ResponseEntity create(#RequestBody Request request){
BusinessCreatorDto businessCreatorDto = new BusinessCreatorDto(IdentifierEpoch.generate(),request.getName());
return ResponseEntity.ok(
creator.create(businessCreatorDto)
);
}
}
The Application Layer:
#AllArgsConstructor
#Service
public class BusinessCreator {
#Autowired
private HibernateJpaRepository repository;
public BusinessResponse create(BusinessCreatorDto dto){
Business business = new Business(dto.getId(), dto.getName());
repository.save(business);
return BusinessResponse.fromAggregate(business);
}
}
In the Infrastructure layer
#Repository
public abstract class HibernateJpaRepository implements JpaRepository<Business, Long> {
}
The boot Application:
#EnableJpaRepositories
#SpringBootApplication
public class MicroserviceApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceApplication.class, args);
}
}
All dependencies are resolved and the others classes I believe that are irrellevant.
Any suggestions? Thank you very much

Probably, the error cause is HibernateJpaRepository - it has to be an interface that extends JpaRepository.

You could write your own Repository in a interface:
#Repository
public interface HibernateJpaRepository extends JpaRepository < Business, Long > {
}
Then your Class:
#AllArgsConstructor
#Service
public class BusinessCreator {
#Autowired
private HibernateJpaRepository repository;
public BusinessResponse create(BusinessCreatorDto dto){
Business business = new Business(dto.getId(), dto.getName());
repository.save(business);
return BusinessResponse.fromAggregate(business);
}
}

Related

How to #Autwired MessageSource in spring into Entity class correctly?

I have the following entity in spring boot application:
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#Audited
#XmlRootElement
#XmlAccessorType(XmlAccessType.NONE)
#Table(name = "currency", catalog = "currency_db")
public class Currency implements java.io.Serializable {
#Autowired
Messages messages;
As for message, it just a container of spring MessageSource here it is:
#ApplicationScope
#Component
#Slf4j
public class Messages {
#Autowired
private MessageSource messageSource;
private MessageSourceAccessor accessor;
#PostConstruct
private void init() {
accessor = new MessageSourceAccessor(messageSource, Locale.ENGLISH);
log.info("Messages initialized");
}
public String get(String code) {
return accessor.getMessage(code);
}
}
I'm getting the following error when run mvn clean install. Any idea what I'm missing here?
org.hibernate.MappingException: Could not determine type for: com.company.currencyservice.Messages, at table: currency, for columns: [org.hibernate.mapping.Column(messages)]
It's looks like hibernate think it's a column. Thanks.
Entities are not Spring beans and therefor you cannot use dependency injection in entities.
If you want to access a Spring bean from within an entity you can use a helper class like this:
#Service
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public static <T> T bean(Class<T> beanType) {
return context.getBean(beanType);
}
public static Object bean(String name) {
return context.getBean(name);
}
#Override
public void setApplicationContext(#SuppressWarnings("NullableProblems") ApplicationContext ac) {
context = ac;
}
}
Then you can use ApplicationContextProvider.getBean(Messages.class) to get access to the Messages.

Spring Boot and/or Vaadin autowiring behaviors I do not understand

I am working on a Spring Boot application an am having issues where items are not being auto-wired as I expect. What is adding to this confusion is that I have another Spring Boot application that also happens to involve Vaadin. In this application, auto-wiring seems more "automated".
Here is what I mean. In the Vaadin app, a #Service object, is injected into a Vaadin "view" with little effort. Additionally, the service object itself is injected with a Repository object. I need to do almost nothing to make this all happen.
In my other non-Vaadin application, I set up the code to do similar things, but in this case, it does not work. The application fails to start and complains as below:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.mycompany.app.backend.service.TaskMasterService required a bean of type 'com.mycompany.app.backend.repository.TaskMasterRepository' that could not be found.
Action:
Consider defining a bean of type 'com.mycompany.app.backend.repository.TaskMasterRepository' in your configuration.
I assume that I'm missing some configuration somewhere, or that the Vaadin application has "extra" functionality added that makes this work.
Here are snippets of the Vaadin application:
TasksView.java:
#Route("main")
public class TasksView extends VerticalLayout {
private final TaskService taskService;
private final TaskNoteService noteService;
public TasksView(TaskService taskService, TaskNoteService noteService) {
this.taskService = taskService;
this.noteService = noteService;
}
...
}
TaskService.java:
#Service
#Transactional
public class TaskService {
private TaskRepository taskRepo;
public TaskService(TaskRepository taskRepo) {
this.taskRepo = taskRepo;
}
...
}
TaskRepository.java:
public interface TaskRepository extends JpaRepository<Task, Long>, TaskRepositoryCustom {
...
}
I don't need to #Autowired anything or provide a #Configuration class or define a #Bean anywhere. It just works.
Here are some snippets from the non-Vaadin application:
IngesterRunner.java:
#Service
public class IngesterRunner {
private TaskMasterService tmService;
private TaskRelationshipService trService;
private VariantDetailService vdService;
public IngesterRunner(TaskMasterService tmService, TaskRelationshipService trService,
VariantDetailService vdService) {
this.tmService = tmService;
this.trService = trService;
this.vdService = vdService;
}
...
}
TaskMasterService.java:
#Service
#Transactional
public class TaskMasterService {
private final TaskMasterRepository repo;
public TaskMasterService(TaskMasterRepository repo) {
this.repo = repo;
}
...
}
TaskMasterRepository.java:
package com.mycompany.app.backend.repository;
public interface TaskMasterRepository extends JpaRepository<TaskMaster, Long> {
}
JPAConfiguration.java:
#Configuration
#EnableJpaRepositories(basePackages = "com.mycompany.app.backend.repository", transactionManagerRef = "jpaTransactionManager")
#EnableTransactionManagement
public class JPAConfiguration {
private static final String[] ENTITY_PACKAGES_TO_SCAN = {
"com.mycompany.app.backend.entity" };
...
}
I don't understand what is different about the first application that makes auto-wiring work so much more smoothly. Is it something I have in my pom.xml? Is it some sort of extra support provided by Vaadin?
If requested, I can try to include the POM files if that will help.
Update:
I have tried a number of suggestions, but none seem to have any effect. I added #Autowired annotations, but it makes no difference.
#Service
public class IngesterRunner {
private TaskMasterService tmService;
private TaskRelationshipService trService;
private VariantDetailService vdService;
public IngesterRunner(#Autowired TaskMasterService tmService,
#Autowired TaskRelationshipService trService, #Autowired VariantDetailService vdService) {
this.tmService = tmService;
this.trService = trService;
this.vdService = vdService;
}
...
}
#Service
#Transactional
public class TaskMasterService {
private final TaskMasterRepository repo;
public TaskMasterService(#Autowired TaskMasterRepository repo) {
this.repo = repo;
}
...
}
#Repository annotation in TaskMasterRepository.java, like
#Repository
public interface TaskMasterRepository extends JpaRepository<TaskMaster, Long> {
}

#Qualifier & #Autowired object coming as null

I am having following code below.
#Builder(toBuilder = true)
#AllArgsConstructor(access = AccessLevel.PRIVATE)
#NoArgsConstructor(access = AccessLevel.PRIVATE)
#ToString
#EqualsAndHashCode
#Configurable
public class Employee {
#Autowired
#Qualifier("findEmpByDepartment")
private Function<Long, Long> empByDepartment;
private void save() {
this.empByDepartment.getList();
}
}
and FindEmpByDepartment class below.
#Component("findEmpByDepartment")
public class FindEmpByDepartment implements Function<Long, Long> {
public void getList() {
}
....
}
My problem is I am always getting null when invoke
this.empByDepartment.getList();
line. Here this.empByDepartment is coming as null. Any idea why it is like this?
Thanks
May be you would have missed annotating any class in the flow hierarchy .
#Service, #Repository and #Controller are all specializations of #Component, so any class you want to auto-wire needs to be annotated with one of them.
IoC is like the cool kid on the block and if you are using Spring then you need to be using it all the time .
So make sure you do not have any object created with new operator in the entire flow .
#Controller
public class Controller {
#GetMapping("/example")
public String example() {
MyService my = new MyService();
my.doStuff();
}
}
#Service
public class MyService() {
#Autowired
MyRepository repo;
public void doStuff() {
repo.findByName( "steve" );
}
}
#Repository
public interface MyRepository extends CrudRepository<My, Long> {
List<My> findByName( String name );
}
This will throw a NullPointerException in the service class when it tries to access the MyRepository auto-wired Repository, not because there is anything wrong with the wiring of the Repository but because you instantiated MyService() manually with MyService my = new MyService().
For more details , you can check
https://www.moreofless.co.uk/spring-mvc-java-autowired-component-null-repository-service/

#Autowired is not working for CrudRepository

I have problems injecting a repository, there is no problem injecting a Service. Im injecting the repo in a service:
#Service
public class AuthorService {
#Autowired
private AuthorRepository repository;
public String getAll(){return "XXXXX";}
}
and the repository is:
public interface AuthorRepository extends CrudRepository<Author, Integer> {
}
And my code structure is the following:
with the main class:
#SpringBootApplication
public class AuthorBookGraphqlApplication {
public static void main(String[] args) {
SpringApplication.run(AuthorBookGraphqlApplication.class, args);
}
}
the error is thrown on start:
Field repository in com.author.book.graphql.demo.service.AuthorService required a bean of type 'com.author.book.graphql.demo.repository.AuthorRepository' that could not be found.
Update code as below
Spring will automatically import the beans into the container and inject to dependencies with these annotations.
#Component, #Controller, #Service and #Repository - Helps to define the beans so the container is aware of them and can inject them for you with #Autowired.
#Autowired - Handles only wiring part here.
#Service
public class AuthorService {
#Autowired
private AuthorRepository repository;
public String getAll(){return "XXXXX";}
}
#Repository
public interface AuthorRepository extends CrudRepository<Author, Integer> {}
Before class AuthorRepository, Let's put more annotation #Repository.

#Autowired annotation not working for one #Controller class and working for others

I have three #RestController classes, for two of them the #Autowired is injecting the bean, but for one it is not. I don't know what the issue is, as few hours ago the same code was working fine.
package com.learn.service;
package com.learn.service;
#Service
#Transactional
public class RoleService {
#Autowired
private RoleJpaRepository roleJpaRepository;
public List<Role> findAll(){
return roleJpaRepository.findAll();
}
}
the controller for Role
package com.learn.controller;
#RestController
#RequestMapping("/roles")
public class RoleController {
#Autowired
private RoleService roleService;
#RequestMapping(method = RequestMethod.GET)
private List<Role> findAll() {
System.out.println(roleService); // roleService is null here and NullPointerException is thrown from below method call.
return roleService.findAll();
}
}
Configuration class for Service
package com.learn.springConfig;
#Configuration
#ComponentScan("com.learn.service")
public class ServiceConfig {
public ServiceConfig() {
super();
}
}
the runner
#SpringBootApplication
#Import({
ContextConfig.class,
PersistenceJpaConfig.class,
ServiceConfig.class,
WebConfig.class,
SecurityConfig.class
})
public class WebservicesLearningApplication {
public static void main(String[] args) {
SpringApplication.run(WebservicesLearningApplication.class, args);
}
}
For the same configurations, the controller for User is working fine whose Service layer exists in the same package as that of Role.
package com.learn.controller;
#RestController
#RequestMapping("/users")
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(method = RequestMethod.GET)
public List<User> findAll() {
System.out.println(userService);
List<User> users = userService.findAll();
return users;
}
Service layer
package com.learn.service;
#Service
#Transactional
public class UserService {
#Autowired
private UserJpaRepository userJpaRepository;
public List<User> findAll(){
return userJpaRepository.findAll();
}
}
Accessing the localhost:8080/api/users is successful but localhost:8080/api/roles gives NullPointerException
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
at com.learn.controller.RoleController.findAll(RoleController.java:30) ~[classes/:na]............
Update1:
Web configuration class
#Configuration
#ComponentScan(basePackages = {"com.learn.controller"})
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer{
public WebConfig() {
super();
}
#Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
Optional<HttpMessageConverter<?>> convertFound = converters.stream().filter(c -> c instanceof AbstractJackson2HttpMessageConverter).findFirst();
if(convertFound.isPresent()) {
final AbstractJackson2HttpMessageConverter converter = (AbstractJackson2HttpMessageConverter) convertFound.get();
converter.getObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
converter.getObjectMapper().enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
}
}
screenshot of project structure
Update2 : I tried using the same UserService using #Autorired in a jUnit test case, and everything is working there. No nullpointer exception.
#ContextConfiguration(classes = {PersistenceJpaConfig.class, ContextConfig.class, ServiceConfig.class})
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class RoleTest {
#Autowired
private RoleService roleService ;
#Test
public void checkIfAllRolesCanBeRetrieved() {
List<Role> roles = roleService.findAll();
Assert.assertNotNull(roles);
}
}
This happened to me! in my case I had a controller using service,The service used a method of a class that did not have a #service,#controller or another annotation and I inject in service then when I use parent service error null occurred.
I hope that it will be used

Resources