java - 将我的模型定义为实体后应用程序无法启动

java - Application fails to start after defining my models as entities

我是 Spring Boot 的新手,想构建一个送餐服务 API。该应用程序运行得非常好,但是当我创建实体以添加数据库功能时,该应用程序停止了 运行ning。我尝试调试代码,但不确定问题出在哪里。 这是我尝试 运行 应用程序后的日志。

    2022-04-28 11:11:15.381  INFO 18796 --- [           main] c.s.f.FoodDeliveryApplication            : No active profile set, falling back to 1 default profile: "default"
2022-04-28 11:11:16.197  INFO 18796 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.      
2022-04-28 11:11:16.220  INFO 18796 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 10 ms. Found 0 JPA repository interfaces.
2022-04-28 11:11:17.163  INFO 18796 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-04-28 11:11:17.176  INFO 18796 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-04-28 11:11:17.177  INFO 18796 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.62]
2022-04-28 11:11:17.356  INFO 18796 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-04-28 11:11:17.357  INFO 18796 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1901 ms  
2022-04-28 11:11:17.424  INFO 18796 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-04-28 11:11:17.666  INFO 18796 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-04-28 11:11:17.682  INFO 18796 --- [           main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
2022-04-28 11:11:17.977  INFO 18796 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]        
2022-04-28 11:11:18.038  INFO 18796 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.6.8.Final
2022-04-28 11:11:18.267  INFO 18796 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-04-28 11:11:18.461  INFO 18796 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect        
2022-04-28 11:11:18.827 ERROR 18796 --- [           main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: 
default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: order, 
for columns: [org.hibernate.mapping.Column(ordered_items)]
2022-04-28 11:11:18.828  WARN 18796 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling 
refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: order, for columns: [org.hibernate.mapping.Column(ordered_items)]
2022-04-28 11:11:18.828  INFO 18796 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2022-04-28 11:11:18.832  INFO 18796 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2022-04-28 11:11:18.834  INFO 18796 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2022-04-28 11:11:18.859  INFO 18796 --- [           main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-04-28 11:11:18.897 ERROR 18796 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: order, for columns: [org.hibernate.mapping.Column(ordered_items)]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.19.jar:5.3.19]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.19.jar:5.3.19]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.19.jar:5.3.19]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:335) ~[spring-beans-5.3.19.jar:5.3.19]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.19.jar:5.3.19]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.19.jar:5.3.19]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.19.jar:5.3.19]
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.19.jar:5.3.19]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.19.jar:5.3.19]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.19.jar:5.3.19]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.7.jar:2.6.7]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.7.jar:2.6.7]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.7.jar:2.6.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.7.jar:2.6.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.7.jar:2.6.7]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.7.jar:2.6.7]
        at com.springboot.fooddelivery.FoodDeliveryApplication.main(FoodDeliveryApplication.java:10) ~[classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: order, for columns: [org.hibernate.mapping.Column(ordered_items)]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-5.3.19.jar:5.3.19]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.19.jar:5.3.19] 
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.19.jar:5.3.19]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.19.jar:5.3.19]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.19.jar:5.3.19]
        ... 16 common frames omitted
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: order, for columns: [org.hibernate.mapping.Column(ordered_items)]  
        at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:515) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:482) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.hibernate.mapping.Property.isValid(Property.java:231) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:627) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.hibernate.mapping.RootClass.validate(RootClass.java:267) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:359) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:314) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498) ~[hibernate-core-5.6.8.Final.jar:5.6.8.Final]
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.19.jar:5.3.19]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.19.jar:5.3.19]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.19.jar:5.3.19]
        ... 20 common frames omitted

这些是我创建的 2 个实体 Dish.java

package com.springboot.fooddelivery.Models;

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

@Entity
public class Dish {
   
    @Id
   @GeneratedValue
    private int DishId;

    private String DishName;
    private String DishCategory;
    private double DishPrice;
    private String DishDesc;

    

    public Dish() {
        super();
    }

    public Dish(int DishId, String DishName, String DishCategory, double DishPrice, String DishDesc) {
        this.DishId = DishId;
        this.DishName = DishName;
        this.DishCategory = DishCategory;
        this.DishPrice = DishPrice;
        this.DishDesc = DishDesc;
    }


    public int getDishId() {
        return DishId;
    }

    public void setDishId(int DishId) {
        this.DishId = DishId;
    }

    public String getDishName() {
        return DishName;
    }

    public void setDishName(String DishName) {
        this.DishName = DishName;
    }
    
    public String getDishCategory() {
        return DishCategory;
    }

    public void setDishCategory(String DishCategory) {
        this.DishCategory = DishCategory;
    }
    
    public double getDishPrice() {
        return DishPrice;
    }

    public void setDishPrice(double DishPrice) {
        this.DishPrice = DishPrice;
    }
    
    public String getDishDesc() {
        return DishDesc;
    }

    public void setDishDesc(String DishDesc) {
        this.DishDesc = DishDesc;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + DishId;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Dish other = (Dish) obj;
        if (DishId != other.DishId) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return String.format("Dish[DishId=%s, DishName=%s, DishCategory=%s, DishPrice=%s, DishDesc=%s]",
         DishId, DishName, DishCategory, DishPrice, DishDesc);
    }
}

Order.java

package com.springboot.fooddelivery.Models;

import java.util.List;

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

@Entity
public class Order {
    
    @Id
    @GeneratedValue
    private int orderId;

    private List<Dish> orderedItems;
    private float orderTotal;
    private String deliveryAddress;


    public Order() {
        super();
    }
    
    public Order(int orderId, List<Dish> orderedItems, float orderTotal, String deliveryAddress) {
        this.orderId = orderId;
        this.orderedItems = orderedItems;
        this.orderTotal = orderTotal;
        this.deliveryAddress = deliveryAddress;
    }


    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }
    
    public List<Dish> getOrderedItems() {
        return orderedItems;
    }

    public void setOrderedItems(List<Dish> orderedItems) {
        this.orderedItems = orderedItems;
    }
    
    public float getOrderTotal() {
        return orderTotal;
    }

    public void setOrderTotal(float orderTotal) {
        this.orderTotal = orderTotal;
    }
    
    
    public String getDeliveryAddress() {
        return deliveryAddress;
    }

    public void setDeliveryAddress(String deliveryAddress) {
        this.deliveryAddress = deliveryAddress;
    }

     
    @Override
    public int hashCode() {
        final int prime = 43;
        int result = 1;
        result = prime * result + orderId;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Order other = (Order) obj;
        if (orderId != other.orderId) {
            return false;
        }
        return true;
    }
}

这是我的 application.properties 文件

spring.datasource.url=jdbc:h2:mem:testdb
spring.data.jpa.repositories.bootstrap-mode=default
spring.h2.console.enabled=true
spring.jpa.show-sql=true

logging.level.org.springframework.web=INFO

这是我的 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.6.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.springboot</groupId>
    <artifactId>food-delivery</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>food-delivery</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>18</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-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
    </dependencies>

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

</project>

您应该解决以下两个问题

1.私有 List<Dish> orderedItems 未映射

从你的日志来看很清楚org.hibernate.MappingException: Could not determine type for: java.util.List

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Dish> orderedItems = new ArrayList<>();

更多信息 - https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/

2。您使用 order 作为您的实体名称,实际上,order 是一个 SQL 保留字

@Entity(name = "MyOrder")
public class Order {
//TODO
}

更多信息 - https://www.drupal.org/docs/develop/coding-standards/list-of-sql-reserved-wordsJPA/Hibernate can't create Entity called Order