知識庫 / Spring RSS 訂閱

Hibernate 實體映射異常 – 未知實體

Persistence,Spring
HongKong
4
03:08 PM · Dec 06 ,2025

1. 問題

本文將討論 org.hibernate.MappingException:未知實體 問題的解決方案,包括針對 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 並不是合適的實體類型——我們需要的是 jakarta.persistence.Entity

import jakarta.persistence.Entity;

@Entity
public class Foo implements Serializable {
    ...

3. 在 Spring 中使用 MappingException

使用 Spring 配置 Hibernate 涉及通過註解掃描從 SessionFactory 進行啓動,使用 LocalSessionFactoryBean

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(restDataSource());
    ...
    return sessionFactory;
}

這個簡單的 Session Factory Bean 配置缺少關鍵要素,並且嘗試使用 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)

現在,解決此問題的有兩種方法 – 兩種方式來告知LocalSessionFactoryBean關於Foo實體類的相關信息。

我們可以指定 classpath 中要搜索實體類的包

sessionFactory.setPackagesToScan(
  new String[] { "com.baeldung.ex.mappingexception.persistence.model" });

我們也可以直接將實體類註冊到Session Factory中:

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 配置屬性

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)

正如上例所示,配置中缺失的部分是將實體類的元數據——Foo——添加到配置中:

configuration.addAnnotatedClass(Foo.class);

此項修復了測試 – 現在能夠持久保存 Foo 實體。

5. 結論

本文闡述了 Unknown entity Mapping Exception 發生的原理,以及如何解決該問題,首先在實體層面,然後是與 Spring 和 Hibernate 的關聯,最後僅針對 Hibernate 本身進行解決。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.