Исключение отображения Hibernate - неизвестный объект
1. Эта проблема
В этой статье будет обсуждаться проблемаorg.hibernate.MappingException: Unknown entity и ее решения как для Hibernate, так и для сред Spring и Hibernate.
Дальнейшее чтение:
Самозагрузка Hibernate 5 с весны
Краткое и практическое руководство по интеграции Hibernate 5 с Spring.
@ Неизменный в спящем
Краткое и практическое руководство по аннотации @Immutable в Hibernate
HibernateException: нет сессии Hibernate, привязанной к потоку в Hibernate 3
Узнайте, когда возникает исключение «Нет привязки Hibernate к потоку» и как с ним бороться.
2. Аннотации@Entity отсутствуют или недействительны
Наиболее частой причиной исключения сопоставления является просто класс сущностиmissing the @Entity annotation:
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;
}
}
Другая возможность состоит в том, что он может иметьthe wrong type of @Entity annotation:
import org.hibernate.annotations.Entity;
@Entity
public class Foo implements Serializable {
...
Устаревшийorg.hibernate.annotations.Entity - это неправильный тип сущности для использования - какойwe need is the javax.persistence.Entity:
import javax.persistence.Entity;
@Entity
public class Foo implements Serializable {
...
3. MappingException с Spring
configuration of Hibernate in Spring включает загрузку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:
org.example.ex.mappingexception.persistence.model.Foo
at o.h.i.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1141)
Теперь естьtwo solutions to this problem - два способа сообщитьLocalSessionFactoryBean о классе сущностиFoo.
Мы можем указать, какойpackages to search for entity classes в пути к классам:
sessionFactory.setPackagesToScan(
new String[] { "org.example.ex.mappingexception.persistence.model" });
Или мы можем простоregister the entity classes directly в Session Factory:
sessionFactory.setAnnotatedClasses(new Class[] { Foo.class });
С любой из этих дополнительных строк конфигурации, тест теперь будет работать правильно и пройдет.
4. 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 содержитthe Hibernate configuration 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_hibernate4_exceptions
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create
Запуск этого теста приведет к тому же исключению сопоставления:
org.hibernate.MappingException:
Unknown entity: org.example.ex.mappingexception.persistence.model.Foo
at o.h.i.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1141)
Как, вероятно, уже ясно из приведенного выше примера, в конфигурации не хватаетadding the metadata of the entity class – Foo – to the configuration:
configuration.addAnnotatedClass(Foo.class);
Это исправляет тест, который теперь может сохранять сущность Foo.
5. Заключение
В этой статье показано, почему может возникнуть исключение отображения неизвестного объекта, и как устранить проблему, когда это происходит, сначала на уровне объекта, затем в Spring и Hibernate и, наконец, только в одном только Hibernate.
Реализацию всех примеров исключений можно найти вthe github project - это проект на основе Eclipse, поэтому его должно быть легко импортировать и запускать как есть.