Spring Boot - “创建名为 'entityManagerFactory' 的 bean 时出错” - 开始

Posted

技术标签:

【中文标题】Spring Boot - “创建名为 \'entityManagerFactory\' 的 bean 时出错” - 开始【英文标题】:Spring Boot - “Error creating bean with name 'entityManagerFactory'” - StartSpring Boot - “创建名为 'entityManagerFactory' 的 bean 时出错” - 开始 【发布时间】:2020-08-12 15:45:08 【问题描述】:

我看到了很多问题,但答案都不能满足我的问题......

我使用 Spring initialzr 生成我的项目

我尝试了 3 个 Java 版本 14、11、8。

这是我的项目结构。

GardenApplication.java。我包括了所有注释,即使 spring doc 说使用 @SpringBootApplication 就足够了。在此错误之前找不到@Repository,我包含@EnableJpaRepositories

package com.garden.garden;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan("com.garden.garden.controller", "com.garden.garden.service.impl")
@EnableJpaRepositories(basePackages = "com.garden.garden.repository")
@EntityScan(basePackages = "com.garden.garden.model")
public class GardenApplication 

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


VegetableController.java

package com.garden.garden.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.garden.garden.model.Vegetable;
import com.garden.garden.service.VegetableService;

@Controller
@RequestMapping
public class VegetableController 

    @Autowired
    private VegetableService vegetableService;

    @GetMapping("/vegetableList")
    public String list(Model model) 
        List<Vegetable> listVegetables = vegetableService.list();
        model.addAttribute("vegetables", listVegetables);
        return "index";
    


VegetableServiceImpl.java

package com.garden.garden.service.impl;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.garden.garden.model.Vegetable;
import com.garden.garden.repository.VegetableRepository;
import com.garden.garden.service.VegetableService;

@Service
public class VegetableServiceImpl implements VegetableService 

    @Autowired
    private VegetableRepository vegetableRepository;

    @Override
    public List<Vegetable> list() 
        return (List<Vegetable>) vegetableRepository.findAll();
    

    @Override
    public Optional<Vegetable> listById(int id) 
        // TODO Auto-generated method stub
        return null;
    

    @Override
    public int save(Vegetable vegetable) 
        // TODO Auto-generated method stub
        return 0;
    

    @Override
    public void delete(int id) 
        // TODO Auto-generated method stub

    


VegetableService.java

package com.garden.garden.service;

import java.util.List;
import java.util.Optional;

import com.garden.garden.model.Vegetable;

public interface VegetableService 
    public List<Vegetable> list();
    public Optional<Vegetable> listById(int id);
    public int save(Vegetable vegetable);
    public void delete(int id);

VegetableRepository.java

package com.garden.garden.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.garden.garden.model.Vegetable;

@Repository
public interface VegetableRepository extends JpaRepository<Vegetable, Integer> 


Vegetable.java

package com.garden.garden.model;

import java.math.BigDecimal;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "vegetable")
public class Vegetable 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private String family;
    private int daysOnNursery;
    private int daysToGrow;
    private int daysHarvesting;
    private java.math.BigDecimal plantsPerSquare;
    private java.math.BigDecimal price;
    private java.math.BigDecimal weight;



    public Vegetable(int id, String name, String family, int daysOnNursery, int daysToGrow, int daysHarvesting,
            BigDecimal plantsPerSquare, BigDecimal price, BigDecimal weight) 
        super();
        this.id = id;
        this.name = name;
        this.family = family;
        this.daysOnNursery = daysOnNursery;
        this.daysToGrow = daysToGrow;
        this.daysHarvesting = daysHarvesting;
        this.plantsPerSquare = plantsPerSquare;
        this.price = price;
        this.weight = weight;
    

    public int getId() 
        return id;
    

    public void setId(int id) 
        this.id = id;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getFamily() 
        return family;
    

    public void setFamily(String family) 
        this.family = family;
    

    public int getDaysOnNursery() 
        return daysOnNursery;
    

    public void setDaysOnNursery(int daysOnNursery) 
        this.daysOnNursery = daysOnNursery;
    

    public int getDaysToGrow() 
        return daysToGrow;
    

    public void setDaysToGrow(int daysToGrow) 
        this.daysToGrow = daysToGrow;
    

    public int getDaysHarvesting() 
        return daysHarvesting;
    

    public void setDaysHarvesting(int daysHarvesting) 
        this.daysHarvesting = daysHarvesting;
    

    public java.math.BigDecimal getPlantsPerSquare() 
        return plantsPerSquare;
    

    public void setPlantsPerSquare(java.math.BigDecimal plantsPerSquare) 
        this.plantsPerSquare = plantsPerSquare;
    

    public java.math.BigDecimal getPrice() 
        return price;
    

    public void setPrice(java.math.BigDecimal price) 
        this.price = price;
    

    public java.math.BigDecimal getWeight() 
        return weight;
    

    public void setWeight(java.math.BigDecimal weight) 
        this.weight = weight;
    


我也尝试解决添加这个依赖的问题:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
</dependency>

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>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.garden</groupId>
    <artifactId>garden</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>garden</name>
    <description>Market garden web application</description>

    <properties>
        <java.version>14</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

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

</project>

application.properties

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

spring.datasource.url=jdbc:mysql://localhost:3306/garden
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=create

【问题讨论】:

这通常发生在您无权访问数据库时。您能否检查一下您是否可以使用您在 application.properties 中提供的内容访问您的 MySql 数据库? 你是对的。我没有在连接 url 中包含时区。一开始我通过添加这个属性 spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect 来解决这个问题。 【参考方案1】:

请删除application.properties 中自动配置的排除项并添加休眠方言,即更新您的application.properties 如下:

spring.datasource.url=jdbc:mysql://localhost:3306/garden
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect

另外你可以将GardenApplication简化为

package com.garden.garden;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaRepositories
@EntityScan
public class GardenApplication 

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


并从你的 pom 中删除 tomcat 依赖项(它与 spring-boot-starter-web 一起传递)。 此外,在依赖项中有 lombok,您可以使用 @Data 注释 Vegetable 并删除 Getters、Setters 和构造函数。

【讨论】:

spring.autoconfigure.exclude = org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 是导致问题的原因。我添加这个是因为我在其他帖子中读到,我解决了 mysql 服务器时区的错误。 另外我不得不说,如果我添加 spring.jpa.database-platform = org.hibernate.dialect.MySQLDialect 我会收到执行 DDL type=MyISAM 的错误。不需要说明这一点,我在其他帖子中读到,如果添加此属性,则必须指定 mysql 版本:***.com/questions/43716068/…

以上是关于Spring Boot - “创建名为 'entityManagerFactory' 的 bean 时出错” - 开始的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

spring-boot-quartz, 依赖spring-boot-parent

spring-boot系列:初试spring-boot

Spring Boot:Spring Boot启动原理分析

Spring Boot:Spring Boot启动原理分析