0

I am stuck with this problem. When I try to run my spring boot app I get this message:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.todolist.service.TaskService required a bean named 'entityManagerFactory' that could not be found.


Action:

Consider defining a bean named 'entityManagerFactory' in your configuration. 

I am using Spring Data JPA and if I understand it correctly, the entityManager is automatically implemented to my project when I use for example JpaRepository interface. Am I missing something? Should I define a bean for entityManager even though I am using JpaRepository? I tried changing it to CrudRepository, added dependencies for hibernate entity manager etc., tried to specify base packages to annotations in my main app class, tried to find solution online but nothing seems to be the right one.

Here is my repository interface:

@Repository
public interface TaskRepository extends JpaRepository<Task, UUID> {

}

Service that is using this repository:

@Service
public class TaskService {

    private final TaskRepository taskRepository;
    private final ModelMapper modelMapper;
    private final TaskMapper taskMapper;

    public TaskService(TaskRepository taskRepository, ModelMapper modelMapper, TaskMapper taskMapper) {
        this.taskRepository = taskRepository;
        this.modelMapper = modelMapper;
        this.taskMapper = taskMapper;
    }


    @Transactional
    public TaskDTO addTask(CreateTaskDTO createTaskDTO) {
        Task task = taskMapper.mapToEntity(createTaskDTO);
        taskRepository.save(task);
        return taskMapper.mapToDto(task);
    }

    @Transactional
    public List<TaskDTO> fetchAll() {
        List<Task> all = taskRepository.findAll();
        return taskMapper.mapToDto(all);
    }

    @Transactional
    public TaskDTO findById(UUID id) {
        Optional<Task> task = taskRepository.findById(id);
        return task.map(taskMapper::mapToDto).orElse(null);
    }

}
@Component
public class TaskMapper {

    public TaskDTO mapToDto(Task task) {
        TaskDTO taskDTO = new TaskDTO();
        taskDTO.setCategory(task.getCategory());
        taskDTO.setDeadline(task.getDeadline());
        taskDTO.setDescription(task.getDescription());
        taskDTO.setId(task.getId());
        taskDTO.setPriority(task.getPriority());
        return taskDTO;
    }

    public List<TaskDTO> mapToDto(List<Task> taskList) {
        if (Optional.ofNullable(taskList).isEmpty()) {
            return new ArrayList<>();
        } else {
            return taskList.stream()
                    .map(this::mapToDto)
                    .collect(Collectors.toList());
        }
    }
    
    public Task mapToEntity(CreateTaskDTO createTaskDTO) {
        Task task = new Task();
        task.setCategory(createTaskDTO.getCategory());
        task.setDeadline(createTaskDTO.getDeadline());
        task.setDescription(createTaskDTO.getDescription());
        task.setPriority(createTaskDTO.getPriority());
        return task;
    }
}

Entity class:

@Entity
@NoArgsConstructor
@Getter
@Setter
@Table(name = Task.TABLE_NAME)
public class Task {

    public static final String TABLE_NAME = "task";
    public static final String COLUMN_PREFIX = "t_";

    public Task(String description, Category category, int priority, LocalDate deadline) {
        this.id = id;
        this.description = description;
        this.category = category;
        this.priority = priority;
        this.deadline = deadline;
    }

    @Id
    @GeneratedValue
    @Type(type = "uuid-char")
    private UUID id;

    @Size(min = 4, max = 20, message = "{task.validation.description}")
    @NotNull(message = "{task.validation.null}")
    @Column(name = COLUMN_PREFIX + "id")
    private String description;

    @NotNull(message = "{task.validation.null}")
    @Column(name = COLUMN_PREFIX + "category")
    private Category category;

    @Min(value = 1, message = "{task.validation.priority}")
    @Max(value = 5, message = "{task.validation.priority}")
    @Column(name = COLUMN_PREFIX + "priority")
    private int priority;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Column(name = COLUMN_PREFIX + "deadline")
    private LocalDate deadline;
}

Dtos:

@Data
public class CreateTaskDTO {

    private String description;
    private Category category;
    private int priority;
    private LocalDate deadline;
}


@Data
@NoArgsConstructor
public class TaskDTO {

    private UUID id;
    private String description;
    private Category category;
    private int priority;
    private LocalDate deadline;
}

Class for injecting beans:

@Configuration
public class Beans {

    @Bean
    public ModelMapper modelMapper() {
        return new ModelMapper();
    }
}

pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>todolist</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>todolist</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.22.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>4.5.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.4.5</version>
        </dependency>
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>3.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>testcontainers</artifactId>
            <version>1.16.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>1.16.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>mysql</artifactId>
            <version>1.16.3</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.1</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

App class:

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }, scanBasePackages = "com.todolist")
@EntityScan
@EnableJpaRepositories
public class TodolistApplication {

    public static void main(String[] args) {
        SpringApplication.run(TodolistApplication.class, args);
    }

}
Szermiona
  • 1
  • 1
  • Have you tried to annotate with @Autowired your TaskRepository in your Service? – Talenel Jul 05 '22 at 09:31
  • Yes, I tried it. Nothing changed. Intellij told me it is not a good idea to Autowire it so I changed it back – Szermiona Jul 05 '22 at 09:36
  • And not-exclude the DataSourceAutoConfiguration.class in your main class? I found this: https://stackoverflow.com/questions/48416927/spring-boot-required-a-bean-named-entitymanagerfactory-that-could-not-be-foun – Talenel Jul 05 '22 at 09:40
  • Remove `@EntityScan` and `@EnableJpaRepositories`. Move your `TodolistApplication` to `com.todolist` **and** remove the exclusion. If there is no `DataSource` there is no `EntityManagerFactory` and no JPA. – M. Deinum Jul 05 '22 at 09:44
  • Thanks @M.Deinum! It works! I am new to spring and while looking for solutions I got all confused and mixed it all. Now I feel stupid for being stuck because of such mistake :) – Szermiona Jul 05 '22 at 09:54

2 Answers2

-2

Add this dependency to pom.xml

org.hibernate hibernate-entitymanager 5.2.3.Final

Collins
  • 11
  • 2
  • 1
    Don't. That is already included in `spring-boot-starter-data-jpa` including an older version will only make things greater. – M. Deinum Jul 05 '22 at 09:43
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 05 '22 at 13:53
-2

You forgot to add @Autowire on the top of the Constructor in TaskService class

@Autowire
public TaskService(TaskRepository taskRepository, ModelMapper modelMapper, TaskMapper taskMapper) {
        this.taskRepository = taskRepository;
        this.modelMapper = modelMapper;
        this.taskMapper = taskMapper;
    }
  • That `@Autowired` on a class with a single constructor hasn't been needed since Spring 4.3 (which is about 5 versions ago)... – M. Deinum Jul 05 '22 at 18:25