Eccezione mappatura ibernazione - Entità sconosciuta

Persistenza in alto

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO

1. Il problema

Questo articolo discuterà org.hibernate.MappingException : problema di entità sconosciuta e soluzioni, sia per Hibernate che per un ambiente Spring e Hibernate.

2. Annotazione @Entity mancante o non valida

La causa più comune per l'eccezione mappatura è semplicemente una classe di entità manca il @Entity annotazioni :

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; } }

Un'altra possibilità è che potrebbe avere il tipo sbagliato di annotazione @Entity :

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

Il deprecato org.hibernate.annotations.Entity è il tipo sbagliato di entità da usare: ciò di cui abbiamo bisogno è javax.persistence.Entity :

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

3. MappingException con la primavera

La configurazione di Hibernate in Spring prevede il bootstrap di SessionFactory dalla scansione delle annotazioni, tramite LocalSessionFactoryBean :

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

Questa semplice configurazione di Session Factory Bean manca di un ingrediente chiave e un test che tenta di utilizzare SessionFactory fallirà:

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

L'eccezione è, come previsto, 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)

Ora, ci sono due soluzioni a questo problema : due modi per dire a LocalSessionFactoryBean della classe di entità Foo .

Possiamo specificare quali pacchetti cercare per classi di entità nel classpath:

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

Oppure possiamo semplicemente registrare le classi di entità direttamente in Session Factory:

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

Con una di queste righe di configurazione aggiuntive, il test verrà eseguito correttamente e verrà superato.

4. MappingException con Hibernate

Vediamo ora l'errore quando si utilizza solo 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; } }

Il file hibernate-mysql.properties contiene le proprietà di configurazione di 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'esecuzione di questo test comporterà la stessa eccezione di mappatura:

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

Come probabilmente è già chiaro dall'esempio sopra, ciò che manca alla configurazione è l' aggiunta dei metadati della classe di entità - Foo - alla configurazione :

configuration.addAnnotatedClass(Foo.class);

Questo risolve il test, che ora è in grado di persistere nell'entità Foo.

5. conclusione

Questo articolo ha illustrato perché può verificarsi l'eccezione di mappatura dell'entità sconosciuta e come risolvere il problema quando si verifica, prima a livello di entità, poi con Spring e Hibernate e infine, solo con Hibernate da solo.

L'implementazione di tutti gli esempi di eccezioni può essere trovata nel progetto github: questo è un progetto basato su Eclipse, quindi dovrebbe essere facile da importare ed eseguire così com'è.

Fondo di persistenza

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO