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;
    }
}

もう1つの可能性は、間違ったタイプの@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. MappingException

Spring でのHibernateの構成には、 LocalSessionFactoryBean を介して、アノテーションスキャンからSessionFactoryをブートストラップすることが含まれます。

@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:不明なエンティティ:です。

org.hibernate.MappingException: Unknown entity: 
com.baeldung.ex.mappingexception.persistence.model.Foo
    at o.h.i.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1141)

現在、この問題には2つの解決策がありますLocalSessionFactoryBeanFooエンティティクラスについて伝える2つの方法です。

クラスパスでエンティティクラスを検索するパッケージを指定できます。

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

または、エンティティクラスを直接セッションファクトリに登録することもできます。

sessionFactory.setAnnotatedClasses(new Class[] { Foo.class });

これらの追加の構成行のいずれかを使用すると、テストが正しく実行され、合格します。

4. MappingExceptionHibernateを使用

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_hibernate4_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. 結論

この記事では、不明なエンティティのマッピング例外が発生する理由と、発生した場合に問題を修正する方法を説明しました。最初はエンティティレベルで、次にSpringとHibernateを使用し、最後にHibernateのみを使用します。

すべての例外の例の実装は、 githubプロジェクトにあります。これはEclipseベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。