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