Search code examples
javaentitymanagermicronaut

How to use entitymanager with Micronaut?


I'm new in Micronaut framework and I'm trying to use entitymanager to create my repository. I created my repository like this

public interface EmployeeRepository {
    Employee save(@NotNull Employee employee);
    Employee update(@NotNull Employee employee);
    List<Employee> findAll();
    Optional<Employee> findById(@NotNull Long id);
}

and I used this class to implement the interface and to inject entitymanager

@Singleton
public class EmployeeRepositoryImpl implements EmployeeRepository{
    @PersistenceContext
    private EntityManager entityManager;

    public EmployeeRepositoryImpl(@CurrentSession EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    @Transactional
    public Employee save(@NotNull Employee employee) {
        entityManager.persist(employee);
        return employee;
    }

    @Override
    @Transactional
    public Employee update(@NotNull Employee employee) {
        return entityManager.merge(employee);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Employee> findAll() {
        String qlString = "SELECT * FROM Employee";
        TypedQuery<Employee> query = entityManager.createQuery(qlString, Employee.class);
        return query.getResultList();
    }

    @Override
    @Transactional(readOnly = true)
    public Optional<Employee> findById(@NotNull Long id) {
        return Optional.ofNullable(entityManager.find(Employee.class, id));
    }
}

The problem is that I have always this error :

Message: No bean of type [javax.persistence.EntityManager] exists. Ensure the class is declared a bean and if you are using Java or Kotlin make sure you have enabled annotation processing.
Path Taken: new $EmployeeControllerDefinition$Intercepted([EmployeeRepositoryImpl employeeRepository],BeanContext beanContext,Interceptor[] interceptors) --> new $EmployeeRepositoryImplDefinition$Intercepted([EntityManager entityManager],BeanContext beanContext,Interceptor[] interceptors)
io.micronaut.context.exceptions.DependencyInjectionException: Failed to inject value for parameter [entityManager] of class: com.milamed.dao.$EmployeeRepositoryImplDefinition$Intercepted

PS: I have enabled the annotation processing


Solution

  • You haven't provided enough about your project to know for sure what is missing but I have created a working example for you at https://github.com/jeffbrown/mohamedmiledijpa.

    https://github.com/jeffbrown/mohamedmiledijpa/blob/master/src/main/java/mohamedmiledijpa/Employee.java

    package mohamedmiledijpa;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    @Entity
    public class Employee {
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    }
    

    https://github.com/jeffbrown/mohamedmiledijpa/blob/master/src/main/java/mohamedmiledijpa/EmployeeRepository.java

    package mohamedmiledijpa;
    
    import javax.validation.constraints.NotNull;
    import java.util.List;
    import java.util.Optional;
    
    public interface EmployeeRepository {
        Employee save(@NotNull Employee employee);
        Employee update(@NotNull Employee employee);
        List<Employee> findAll();
        Optional<Employee> findById(@NotNull Long id);
    }
    

    https://github.com/jeffbrown/mohamedmiledijpa/blob/master/src/main/java/mohamedmiledijpa/EmployeeRepositoryImpl.java

    package mohamedmiledijpa;
    
    import io.micronaut.configuration.hibernate.jpa.scope.CurrentSession;
    import io.micronaut.spring.tx.annotation.Transactional;
    
    import javax.inject.Singleton;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.TypedQuery;
    import javax.validation.constraints.NotNull;
    import java.util.List;
    import java.util.Optional;
    
    @Singleton
    public class EmployeeRepositoryImpl implements EmployeeRepository{
        @PersistenceContext
        private EntityManager entityManager;
    
        public EmployeeRepositoryImpl(@CurrentSession EntityManager entityManager) {
            this.entityManager = entityManager;
        }
    
        @Override
        @Transactional
        public Employee save(@NotNull Employee employee) {
            entityManager.persist(employee);
            return employee;
        }
    
        @Override
        @Transactional
        public Employee update(@NotNull Employee employee) {
            return entityManager.merge(employee);
        }
    
        @Override
        @Transactional(readOnly = true)
        public List<Employee> findAll() {
            String qlString = "SELECT e FROM Employee e";
            TypedQuery<Employee> query = entityManager.createQuery(qlString, Employee.class);
            return query.getResultList();
        }
    
        @Override
        @Transactional(readOnly = true)
        public Optional<Employee> findById(@NotNull Long id) {
            return Optional.ofNullable(entityManager.find(Employee.class, id));
        }
    }
    

    https://github.com/jeffbrown/mohamedmiledijpa/blob/master/src/main/java/mohamedmiledijpa/EmployeeController.java

    package mohamedmiledijpa;
    
    import io.micronaut.http.annotation.Body;
    import io.micronaut.http.annotation.Controller;
    import io.micronaut.http.annotation.Get;
    import io.micronaut.http.annotation.Post;
    
    import java.util.List;
    
    @Controller("/employee")
    public class EmployeeController {
    
        private EmployeeRepository employeeRepository;
    
        public EmployeeController(EmployeeRepository employeeRepository) {
            this.employeeRepository = employeeRepository;
        }
    
        @Get("/")
        public List<Employee> list() {
            return employeeRepository.findAll();
        }
    
        @Post("/")
        public Employee create(@Body Employee employee) {
            return employeeRepository.save(employee);
        }
    }
    

    https://github.com/jeffbrown/mohamedmiledijpa/blob/f6500d3fb24190ed59ca64dcc28a02f8069fedfd/build.gradle#L29

    compile "io.micronaut.configuration:micronaut-hibernate-jpa"
    

    That all appears to work:

    ~ $ curl http://localhost:8080/employee
    []
    ~ $ 
    ~ $ curl -d '{"name":"Jake"}' -H "Content-Type: application/json" -X POST  http://localhost:8080/employee
    {"id":1,"name":"Jake"}
    ~ $ 
    ~ $ curl -d '{"name":"Zack"}' -H "Content-Type: application/json" -X POST  http://localhost:8080/employee
    {"id":2,"name":"Zack"}
    ~ $ 
    ~ $ curl http://localhost:8080/employee
    [{"id":1,"name":"Jake"},{"id":2,"name":"Zack"}]