Exception de mappage Hibernate - Entité inconnue

Haut de persistance

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Le problème

Cet article va discuter de l' exception org.hibernate.MappingException : problème d' entité inconnue et solutions, à la fois pour Hibernate ainsi que pour un environnement Spring et Hibernate.

2. Annotation @Entity manquante ou non valide

La cause la plus courante de l'exception de mappage est simplement une classe d'entité manquant l' annotation @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; } }

Une autre possibilité est qu'il peut avoir le mauvais type d' annotation @Entity :

import org.hibernate.annotations.Entity; @Entity public class Foo implements Serializable { ...

L' org.hibernate.annotations.Entity, obsolète, n'est pas le bon type d'entité à utiliser - ce dont nous avons besoin est javax.persistence.Entity :

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

3. MappingException avec Spring

La configuration d'Hibernate dans Spring implique d'amorcer la SessionFactory à partir de l'analyse des annotations, via un LocalSessionFactoryBean :

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

Il manque un ingrédient clé à cette configuration simple du Session Factory Bean, et un test essayant d'utiliser SessionFactory échouera:

... @Autowired private SessionFactory sessionFactory; @Test(expected = MappingException.class) @Transactional public void givenEntityIsPersisted_thenException() { sessionFactory.getCurrentSession().saveOrUpdate(new Foo()); }

L'exception est, comme prévu - l' entité MappingException: Unknown :

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

Maintenant, il existe deux solutions à ce problème - deux manières de dire au LocalSessionFactoryBean la classe d'entité Foo .

Nous pouvons spécifier quels packages rechercher des classes d'entités dans le chemin de classe :

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

Ou nous pouvons simplement enregistrer les classes d'entités directement dans Session Factory:

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

Avec l'une ou l'autre de ces lignes de configuration supplémentaires, le test s'exécute désormais correctement et réussit.

4. MappingException avec Hibernate

Voyons maintenant l'erreur lorsque vous utilisez uniquement 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; } }

Le fichier hibernate-mysql.properties contient les propriétés de configuration 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

L'exécution de ce test entraînera la même exception de mappage:

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

Comme il ressort probablement déjà de l'exemple ci-dessus, ce qui manque à la configuration est l' ajout des métadonnées de la classe d'entité - Foo - à la configuration :

configuration.addAnnotatedClass(Foo.class);

Cela corrige le test - qui est maintenant capable de conserver l'entité Foo.

5. Conclusion

Cet article a illustré pourquoi l'exception de mappage d'entité inconnue peut se produire et comment résoudre le problème lorsqu'elle se produit, d'abord au niveau de l'entité, puis avec Spring et Hibernate et enfin, uniquement avec Hibernate.

L'implémentation de tous les exemples d'exceptions peut être trouvée dans le projet github - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.

Fond de persistance

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS