求助:org.hibernate.UnknownEntityTypeException无法定位Product实体
解决Hibernate UnknownEntityTypeException:无法定位Product实体
问题描述
运行Hibernate测试代码时抛出异常:
org.hibernate.UnknownEntityTypeException: Unable to locate entity descriptor: com.mywebapp.model.Product
原代码与配置
Product.java
@Entity @Table(name = "product") public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "product_name", nullable = false) private String productName; @Column(name = "sale_price") private double salePrice; @ManyToOne @JoinColumn private Order order; public Product(String productName, double salePrice) { this.productName = productName; this.salePrice = salePrice; } public Product() { //Default constructor } public Long getId() { return id; } public String getProductName() { return productName; } public void setProductName(String name) { this.productName = name; } public double getProductSalePrice() { return salePrice; } public void setProductSalePrice(double salePrice) { this.salePrice = salePrice; } }
HibernateTests.java(原代码)
@SpringBootTest//测试中实体扫描无法找到实体 public class HibernateTests { public static void main(String[] args) { final StandardServiceRegistry registry = new StandardServiceRegistryBuilder(). configure() .build(); SessionFactory sessionFactory = new Configuration() .configure("hibernate.cfg.xml") .buildSessionFactory(); Session session =sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Product product = new Product(); product.setProductName("SomeProduct1"); product.setProductSalePrice(1290.78); if (Objects.isNull(session.find(Product.class, product.getId()))) { session.persist(product); } else { session.merge(product); } transaction.commit(); session.close(); sessionFactory.close(); } }
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.1.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.bitconex</groupId> <artifactId>MyWebApp</artifactId> <version>0.0.1-SNAPSHOT</version> <name>MyWebApp</name> <description>MyWebApp</description> <properties> <java.version>17</java.version> <start-class>src/main/java/com/bitconex/mywebapp/MyWebAppApplication.java</start-class> </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>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.2.7.Final</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</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> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>5.3.0</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator-core</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.6.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${project.parent.version}</version> </plugin> </plugins> </build> </project>
application.properties(原配置)
#H2 Database Configuration spring.datasource.url=jdbc:postgresql://localhost:5432/CatalogProDB spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.username=postgres spring.datasource.password=password #Hibernate Configuration for PostgreSQL spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.show_sql=true server.port=8081
问题原因
- 测试类混用原生Hibernate API与Spring Boot环境:标注
@SpringBootTest的类中使用原生Hibernate的Configuration和SessionFactory构建方式,绕过了Spring Boot的JPA自动配置,导致实体扫描机制失效。 - 实体包路径未被扫描:
Product类所在的com.mywebapp.model包不在Spring Boot主类(com.bitconex.mywebapp)的默认扫描范围内,Spring无法识别该实体。 - 重复依赖冲突:
spring-boot-starter-data-jpa已包含兼容版本的Hibernate核心依赖,手动添加hibernate-core可能引发版本冲突。
解决方案
1. 修正测试类,使用Spring Boot的JPA支持
删除原生Hibernate的SessionFactory构建代码,注入Spring管理的EntityManager:
@SpringBootTest @Transactional public class HibernateTests { @PersistenceContext private EntityManager entityManager; @Test public void testProductPersistence() { Product product = new Product(); product.setProductName("SomeProduct1"); product.setProductSalePrice(1290.78); // 持久化实体 entityManager.persist(product); entityManager.flush(); // 验证实体是否存在 Product savedProduct = entityManager.find(Product.class, product.getId()); Assertions.assertNotNull(savedProduct); Assertions.assertEquals("SomeProduct1", savedProduct.getProductName()); } }
2. 确保实体包被Spring扫描
在Spring Boot主类上添加@EntityScan指定实体包路径:
@SpringBootApplication @EntityScan("com.mywebapp.model") // 扫描指定包下的实体类 public class MyWebAppApplication { public static void main(String[] args) { SpringApplication.run(MyWebAppApplication.class, args); } }
3. 清理重复依赖
删除pom.xml中的hibernate-core依赖,保留spring-boot-starter-data-jpa即可:
<!-- 移除该依赖 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.2.7.Final</version> </dependency>
4. 移除不必要的数据库驱动
当前使用PostgreSQL,可移除H2和MySQL驱动依赖:
<!-- 移除H2驱动 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <!-- 移除MySQL驱动 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency>
补充说明
如果一定要使用原生Hibernate API,需在hibernate.cfg.xml中显式注册实体类:
<hibernate-configuration> <session-factory> <!-- 其他配置 --> <mapping class="com.mywebapp.model.Product"/> </session-factory> </hibernate-configuration>
但Spring Boot项目中推荐使用Spring提供的JPA集成,更符合生态最佳实践。
内容的提问来源于stack exchange,提问作者user22566443
相关产品推荐
相关产品推荐

