You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot应用启动失败:找不到entityManagerFactory Bean求助

Spring Boot Todo项目启动报错:无法找到entityManagerFactory Bean

启动Spring Boot Todo项目时遇到错误,提示找不到名为entityManagerFactory的Bean。

错误信息


APPLICATION FAILED TO START


Description:
Parameter 0 of constructor in com.todo.demo.service.TaskService required a bean named 'entityManagerFactory' that could not be found.
Action:
Consider defining a bean named 'entityManagerFactory' in your configuration.

相关代码

实体类Task

package com.todo.demo;

import java.time.LocalDate;
import jakarta.persistence.*;
@Entity
@Table(name = "tasks")
/**
 * @Author Noah Rouse
 * @email: noahrouse36@gmail.com
 * @description: this class is designed to store and represent tasks in a todo list
 */
public class Task {
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column
   private long id;
   @Column(name = "description", nullable = false)
   private String description;
   @Column(name = "completed")
   private boolean completed;
   @Column(name = "priority")
   private String priority;
   @Column(name = "due_date")
   private LocalDate dueDate;
   @Column(name = "created")
   private LocalDate created;
   @Column(name = "last_updated")
   private LocalDate lastUpdated;

   public Task () {}

   public Task (final Long id, final String description, final String priority,
         final LocalDate dueDate) {
      this.id = id;
      this.completed = false;
      this.description = description;
      this.priority = priority;
      this.dueDate = dueDate;
      this.created = LocalDate.now();
      this.lastUpdated = created;
   }

   /**
    * @return task id
    */
   public long id () {
      return this.id;      
   }

   /**
    * @return description
    */
   public String description () {
      return this.description;
   }

   /**
    * set task description to new description and changes last updated value
    * @return updated description
    */
   public String description (final String description) {
      this.description = description;
      this.lastUpdated = LocalDate.now();
      return this.description;
   }

   /**
    * @return if the task is completed
    */
   public boolean completed () {
      return this.completed;
   }

   /**
    * Set completed to true or false
    * @return updated completed status
    */
   public boolean completed (final boolean completed) {
      this.completed = completed;
      this.lastUpdated = LocalDate.now();
      return this.completed;
   }

   /**
    * @return priority of task
    */
   public String priority () {
      return this.priority;
   }

   /**
    * sets task to new priority
    * @return new priority
    */
   public String priority (final String priority) {
      this.priority = priority;
      this.lastUpdated = LocalDate.now();
      return this.priority;
   }


   /**
    * @return current task due date
    */
   public LocalDate dueDate () {
      return this.dueDate;
   }

   /**
    * change due date to new local date
    * @return new due date
    */
   public LocalDate dueDate (final LocalDate dueDate) {
      this.dueDate = dueDate;
      this.lastUpdated = LocalDate.now();
      return this.dueDate;
   }

   /**
    * @return when the task was last updated
    */
   public LocalDate lastUpdated () {
      return this.lastUpdated;
   }
}

服务类TaskService

package com.todo.demo.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.todo.demo.Task;
import com.todo.demo.repository.TaskRepository;


import java.time.LocalDate;
import java.util.Optional;
@Service
@Transactional
public class TaskService {
   public class TaskNotFoundException extends Exception {

   }
   private final TaskRepository taskRepos;

   public TaskService (final TaskRepository taskRepository) {
      taskRepos = taskRepository;
   }

   public void updateTaskDescription (final long taskId, final String description)
         throws TaskNotFoundException {
      final Optional<Task> potentialTask = taskRepos.findById(taskId);

      if (potentialTask.isPresent()) {
         final Task task = potentialTask.get();
         task.description(description);
         taskRepos.save(task);
      } else {
         throw new TaskNotFoundException();
      }
   }

   public void updateTaskCompletion (final long taskId, final boolean completed)
         throws TaskNotFoundException {
      final Optional<Task> potentialTask = taskRepos.findById(taskId);
      
      if (potentialTask.isPresent()) {
         final Task task = potentialTask.get();
         task.completed(completed);
         taskRepos.save(task);
      } else {
         throw new TaskNotFoundException();
      }
   }

   public void updateTaskPriority (final long taskId, final String priority)
         throws TaskNotFoundException {
      final Optional<Task> potentialTask = taskRepos.findById(taskId);

      if (potentialTask.isPresent()) {
         final Task task = potentialTask.get();
         task.priority(priority);
         taskRepos.save(task);
      } else {
         throw new TaskNotFoundException();
      }
   }

   public void updateTaskDueDate (final long taskId, final LocalDate dueDate)
         throws TaskNotFoundException {
      final Optional<Task> potentialTask = taskRepos.findById(taskId);

      if (potentialTask.isPresent()) {
         final Task task = potentialTask.get();
         task.dueDate(dueDate);
         taskRepos.save(task);
      } else {
         throw new TaskNotFoundException();
      }
   }
}

pom.xml文件

<?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>3.3.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.todo</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>21</java.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.1.214</version>
        </dependency>



        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>3.3.5</version>
        </dependency>


        <dependency>
            <groupId>jakarta.persistence</groupId>
            <artifactId>jakarta.persistence-api</artifactId>
            <version>3.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.properties文件

spring.application.name=demo

spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.h2.console.enabled=true

问题原因及解决方案

原因

手动引入了spring-data-jpa和jakarta.persistence-api零散依赖,但未使用Spring Boot官方的spring-boot-starter-data-jpa。该starter会自动配置entityManagerFactory、EntityManager等核心JPA Bean,零散依赖会导致自动配置逻辑失效,缺少必要Bean。另外h2依赖未设置runtime scope,不符合Spring Boot最佳实践。

解决步骤

  1. 替换零散JPA依赖为Spring Boot JPA Starter
    删除pom.xml中以下依赖:

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>3.3.5</version>
    </dependency>
    
    <dependency>
        <groupId>jakarta.persistence</groupId>
        <artifactId>jakarta.persistence-api</artifactId>
        <version>3.2.0</version>
    </dependency>
    

    添加官方JPA Starter:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
  2. 调整H2依赖的Scope
    修改h2依赖,添加runtime scope:

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    
  3. 确认主启动类包扫描范围
    确保主启动类(如DemoApplication)位于com.todo.demo包下,或添加@SpringBootApplication(scanBasePackages = "com.todo.demo")注解,保证能扫描到Repository、Service等组件。

  4. 验证TaskRepository配置
    确保TaskRepository接口继承JpaRepository<Task, Long>,Spring Boot会自动识别该接口并创建Bean。

完成以上修改后,执行mvn clean install重新构建项目,启动后entityManagerFactory Bean会被自动配置,报错即可解决。

内容的提问来源于stack exchange,提问作者Noah Rouse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 10:47:32