Изключение за картографиране на хибернация - неизвестен обект

Устойчивост отгоре

Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:

>> ПРЕГЛЕД НА КУРСА

1. Проблемът

Тази статия ще обсъди org.hibernate.MappingException : Неизвестен проблем и решения на обекта , както за хибернация, така и за пролетна и хибернация среда.

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 е грешен тип на предприятието да използва - това, което имаме нужда е javax.persistence.Entity :

import javax.persistence.Entity; @Entity public class Foo implements Serializable { ...

3. MappingException с пролет

Конфигурацията на 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: Неизвестен обект :

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 с хибернация

Нека сега видим грешката при използване само на хибернация:

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, така че трябва да е лесно да се импортира и да се изпълнява както е.

Устойчивост отдолу

Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:

>> ПРЕГЛЕД НА КУРСА