Рубрики
Без рубрики

Hibernate Mapping Exception – Неизвестная сущность

Hibernate MappingException – Неизвестная сущность – причины и решения.

Автор оригинала: Eugen Paraschiv.

1. Проблема

В этой статье мы обсудим org.hibernate.MappingException : Unknown entity проблема и решения, как для Hibernate, так и для среды Spring и Hibernate.

Дальнейшее чтение:

Bootstrapping Hibernate 5 с пружиной

@Неизменяемый в спящем режиме

HibernateException: Нет сеанса Hibernate, привязанного к потоку в Hibernate 3

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.аннотации.Entity – это неправильный тип сущности для использования – то, что нам нужно, это javax.persistence.Сущность :

import javax.persistence.Entity;

@Entity
public class Foo implements Serializable {
    ...

3. MappingException С Пружиной

Конфигурация Hibernate in Spring включает в себя загрузку SessionFactory из сканирования аннотаций через LocalSessionFactoryBean :

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

В этой простой конфигурации компонента 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)

Теперь есть два решения этой проблемы – два способа рассказать LocalSessionFactoryBean о классе сущностей Foo .

Мы можем указать, какие пакеты искать для классов сущностей в пути к классам:

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

Или мы можем просто зарегистрировать классы сущностей непосредственно на фабрике сеансов:

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

С любой из этих дополнительных строк конфигурации тест теперь будет работать правильно и пройдет.

4. MappingException С Hibernate

Давайте теперь посмотрим на ошибку при использовании just 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, поэтому его должно быть легко импортировать и запускать как есть.