Hibernate-Mapping-Ausnahme - Unbekannte Entität

Hibernate-Mapping-Ausnahme - Unbekannte Entität

1. Das Problem

In diesem Artikel werden das Problem und die Lösungen vonorg.hibernate.MappingException: Unknown entityowohl für den Ruhezustand als auch für eine Spring- und Hibernate-Umgebung erläutert.

Weitere Lektüre:

Bootstrapping Hibernate 5 mit Spring

Eine schnelle und praktische Anleitung zur Integration von Hibernate 5 in Spring.

Read more

@ Im Ruhezustand unveränderlich

Eine schnelle und praktische Anleitung zu @Immutable Annotation in Hibernate

Read more

HibernateException: Keine Sitzung im Ruhezustand, die an den Thread in Ruhezustand 3 gebunden ist

Erfahren Sie, wann die Ausnahme "Keine Sitzung im Ruhezustand an Thread gebunden" ausgelöst wird, und wie Sie damit umgehen können.

Read more

2. Fehlende oder ungültige@Entity Anmerkung

Die häufigste Ursache für die Zuordnungsausnahme ist einfach eine Entitätsklassemissing 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;
    }
}

Eine andere Möglichkeit ist, dass esthe wrong type of @Entity annotation haben kann:

import org.hibernate.annotations.Entity;

@Entity
public class Foo implements Serializable {
    ...

Die veraltetenorg.hibernate.annotations.Entity sind der falsche Entitätstyp - welchewe need is the javax.persistence.Entity:

import javax.persistence.Entity;

@Entity
public class Foo implements Serializable {
    ...

3. MappingException mit Feder

Beiconfiguration of Hibernate in Spring werden dieSessionFactory vom Anmerkungsscan über einLocalSessionFactoryBean gebootet:

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

In dieser einfachen Konfiguration der Session Factory Bean fehlt eine wichtige Zutat, und ein Test, bei dem versucht wird,SessionFactoryzu verwenden, schlägt fehl:

...
@Autowired
private SessionFactory sessionFactory;

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

Die Ausnahme ist erwartungsgemäß -MappingException: Unknown entity:

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

Jetzt gibt estwo solutions to this problem - zwei Möglichkeiten, umLocalSessionFactoryBean über die EntitätsklasseFoozu informieren.

Wir können angeben, welchepackages to search for entity classes im Klassenpfad sind:

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

Oder wir können einfachregister the entity classes directly in die Session Factory:

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

Mit einer dieser zusätzlichen Konfigurationszeilen wird der Test nun korrekt ausgeführt und bestanden.

4. MappingException mit Ruhezustand

Lassen Sie uns nun den Fehler sehen, wenn Sie nur den Ruhezustand verwenden:

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

Die Dateihibernate-mysql.properties enthältthe 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

Das Ausführen dieses Tests führt zu der gleichen Zuordnungsausnahme:

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

Wie aus dem obigen Beispiel wahrscheinlich bereits hervorgeht, fehlt in der Konfigurationadding the metadata of the entity class – Foo – to the configuration:

configuration.addAnnotatedClass(Foo.class);

Dies behebt den Test, der nun in der Lage ist, die Foo-Entität zu erhalten.

5. Fazit

In diesem Artikel wurde erläutert, warum die Unbekannte Entitätszuordnungsausnahme auftreten kann und wie das Problem behoben werden kann, wenn dies zuerst auf Entitätsebene, dann mit Spring und Ruhezustand und schließlich nur mit Ruhezustand erfolgt.

Die Implementierung aller Ausnahmebeispiele finden Sie inthe github project - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.