1. 问题概述
本文将探讨 Hibernate 中常见的 org.hibernate.MappingException: Unknown entity
异常问题及其解决方案,涵盖原生 Hibernate 环境和 Spring 整合 Hibernate 的场景。
2. 缺失或错误的 @Entity 注解
导致映射异常的最常见原因是实体类 缺少 @Entity 注解:
public class Foo implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
public Foo() {
super();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
另一种可能是使用了 错误的 @Entity 注解类型:
import org.hibernate.annotations.Entity;
@Entity
public class Foo implements Serializable {
...
❌ 已废弃的 org.hibernate.annotations.Entity
是错误选择
✅ 正确应使用 javax.persistence.Entity
:
import javax.persistence.Entity;
@Entity
public class Foo implements Serializable {
...
3. Spring 环境下的 MappingException
在 Spring 中配置 Hibernate 时,通常通过 LocalSessionFactoryBean
进行注解扫描来启动 SessionFactory
:
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(restDataSource());
...
return sessionFactory;
}
这种基础配置会缺少关键设置,导致使用 SessionFactory
的测试失败:
...
@Autowired
private SessionFactory sessionFactory;
@Test(expected = MappingException.class)
@Transactional
public void givenEntityIsPersisted_thenException() {
sessionFactory.getCurrentSession().saveOrUpdate(new Foo());
}
抛出预期的 MappingException: Unknown entity
:
org.hibernate.MappingException: Unknown entity:
com.baeldung.ex.mappingexception.persistence.model.Foo
at o.h.i.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1141)
⚠️ 两种解决方案:
指定实体类扫描包路径:
sessionFactory.setPackagesToScan( new String[] { "com.baeldung.ex.mappingexception.persistence.model" });
直接注册实体类:
sessionFactory.setAnnotatedClasses(new Class[] { Foo.class });
添加任一配置后,测试即可正常运行。
4. 原生 Hibernate 环境的 MappingException
在纯 Hibernate 环境中复现该问题:
public class Cause4MappingExceptionIntegrationTest {
@Test
public void givenEntityIsPersisted_thenException() throws IOException {
SessionFactory sessionFactory = configureSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.saveOrUpdate(new Foo());
session.getTransaction().commit();
}
private SessionFactory configureSessionFactory() throws IOException {
Configuration configuration = new Configuration();
InputStream inputStream = this.getClass().getClassLoader().
getResourceAsStream("hibernate-mysql.properties");
Properties hibernateProperties = new Properties();
hibernateProperties.load(inputStream);
configuration.setProperties(hibernateProperties);
// configuration.addAnnotatedClass(Foo.class); // 关键配置被注释
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().
applySettings(configuration.getProperties()).buildServiceRegistry();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
}
hibernate-mysql.properties
配置文件内容:
hibernate.connection.username=tutorialuser
hibernate.connection.password=tutorialmy5ql
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.connection.url=jdbc:mysql://localhost:3306/spring_hibernate5_exceptions
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create
执行测试同样抛出映射异常:
org.hibernate.MappingException:
Unknown entity: com.baeldung.ex.mappingexception.persistence.model.Foo
at o.h.i.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1141)
解决方案:在配置中显式添加实体类元数据:
configuration.addAnnotatedClass(Foo.class);
添加后实体即可正常持久化。
5. 总结
本文分析了 Unknown entity
映射异常的三大典型场景:
- 实体类注解缺失或错误
- Spring 整合时的配置遗漏
- 原生 Hibernate 的元数据配置缺失
所有示例代码可在 GitHub 项目 中获取,该项目基于 Eclipse 构建,可直接导入运行。