Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

org.hibernate.MappingException: Unknown entity: annotations.Users

Consider the hierarchy :

enter image description here

And the following classes and xml :

HibernateUtil.java

package annotations;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;


/**
 * 
 * @author X3
 *
 */
public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();
    private static final String HIBERNATE_CFG = "hibernateAnnotations.cfg.xml";

    private static SessionFactory buildSessionFactory() 
    {
        Configuration cfg = new Configuration().addResource(HIBERNATE_CFG).configure();
        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().
                applySettings(cfg.getProperties()).buildServiceRegistry();
        SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);
        return sessionFactory;
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

Users.java

package annotations;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.sql.Timestamp;

@Entity
@Table(name = "Users")
public class Users {

    @Id
    @GeneratedValue
    @Column(name = "USER_ID")
    private long userID;

    @Column(name = "USERNAME", nullable = false, length = 100)
    private String username;

    @Column(name = "MessageTimeDate", nullable = false)
    private java.sql.Timestamp datetime;

    @Column(name = "UserMessage", nullable = false)
    private String message;



    public Users(String username , String message)
    {
        java.util.Date date = new java.util.Date();
        this.datetime = new Timestamp(date.getTime());

        this.username = username;
        this.message = message;
    }

    public long getUserID() {
        return userID;
    }

    public void setUserID(long userID) {
        this.userID = userID;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public java.sql.Timestamp getDatetime() {
        return datetime;
    }

    public void setDatetime(java.sql.Timestamp datetime) {
        this.datetime = datetime;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

Main.java

package annotations;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class Main {

    public static void main(String[] args) {

        try
        {
               SessionFactory sf = HibernateUtil.getSessionFactory();
               Session session = sf.openSession();
               session.beginTransaction();

               Users user1 = new Users("Jack" , "Hello");
               session.save(user1);
               session.getTransaction().commit();
               session.close();
        }

        catch (Exception e)
        {
            System.out.println(e.toString());
            e.getStackTrace();
        }


    }
}

And hibernateAnnotations.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/CHAT_DB</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.pool_size">1</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
        <mapping class="annotations.Users"></mapping>       
    </session-factory>
</hibernate-configuration>

When I run main(), the following error appears in output window :

org.hibernate.MappingException: Unknown entity: annotations.Users

But the entity Users is in annotations package , so what's wrong ?

like image 362
JAN Avatar asked Apr 22 '14 08:04

JAN


6 Answers

The Hibernate configuration file must define the entity classes:

<mapping class="annotations.Users"/>

Or you must explicitly add the class to the configuration using

configuration.addClass(annotations.Users.class)
// Read mappings as a application resourceName
 // addResource is for add hbml.xml files in case of declarative approach
configuration.addResource("myFile.hbm.xml");  // not hibernateAnnotations.cfg.xml
like image 133
Asif Bhutto Avatar answered Nov 19 '22 03:11

Asif Bhutto


When I was trying to rewrite my example (from tutorialspoint) to use annotations, I got the same exception. This helped me (addAnnotatedClass()):

Configuration cfg=new Configuration(); 
cfg.addAnnotatedClass(com.tutorialspoint.hibernate.entity.Employee.class);
cfg.configure();
like image 28
user5728489 Avatar answered Nov 19 '22 04:11

user5728489


I did not find the accepted answer helpful in resolving the exception encountered in my code. And while not technically incorrect, I was also not satisfied with others' suggestions to introduce redundancy:

  • programmatically re-add the mapped class using configuration.addAnnotatedClass(...)
  • create a hbm.xml file and resource mapping in hibernate_test.cfg.xml that were redundant to the existing annotations
  • scan the package where the (already mapped) class exists using external dependencies not mentioned in the original question

However, I found 2 possible solutions that I wanted to share, both of which independently resolved the exception I encountered in my own code.

I was having the same MappingException as @ron (using a very nearly identical HibernateUtil class):

public final class HibernateUtil {

    private static SessionFactory sessionFactory = null;
    private static ServiceRegistry serviceRegistry = null;

    private HibernateUtil() {}

    public static synchronized SessionFactory getSessionFactory() {
        if ( sessionFactory == null ) {
            Configuration configuration = new Configuration().configure("hibernate_test.cfg.xml");
            serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties())
                    .build();
            sessionFactory = configuration.buildSessionFactory( serviceRegistry );
        }
        return sessionFactory;
    }
// exception handling and closeSessionFactory() omitted for brevity
}

Within my hibernate_test.cfg.xml configuration file, I have the required class mapping:

<mapping class="myPackage.Device"/>

And my Device class is properly annotated with the javax.persistence.Entity annotation:

package myPackage.core;
import javax.persistence.*;

@Entity
@Table( name = "devices" )
public class Device {
    //body omitted for brevity
}

Two Possible Solutions:

First, I am using Hibernate 5.2, and for those using Hibernate 5 this solution using a Metadata object to build a SessionFactory should work. It also appears to be the currently recommended native bootstrap mechanism in the Hibernate Getting Started Guide :

public static synchronized SessionFactory getSessionFactory() {
    if ( sessionFactory == null ) {

        // exception handling omitted for brevity

        serviceRegistry = new StandardServiceRegistryBuilder()
                .configure("hibernate_test.cfg.xml")
                .build();

        sessionFactory = new MetadataSources( serviceRegistry )
                    .buildMetadata()
                    .buildSessionFactory();
    }
    return sessionFactory;
}

Second, while Configuration is semi-deprecated in Hibernate 5, @ron didn't say which version of Hibernate he was using, so this solution could also be of value to some.

I found a very subtle change in the order of operations when instantiating and configuring Configuration and ServiceRegistry objects to make all the difference in my own code.

Original order (Configuration created and configured prior to ServiceRegistry):

public static synchronized SessionFactory getSessionFactory() {
    if ( sessionFactory == null ) {

        // exception handling omitted for brevity

        Configuration configuration = new Configuration().configure("hibernate_test.cfg.xml");

        serviceRegistry = new StandardServiceRegistryBuilder()
                .applySettings( configuration.getProperties() )
                .build();

        sessionFactory = configuration.buildSessionFactory( serviceRegistry );
    }
    return sessionFactory;
}

New order (ServiceRegistry created and configured prior to Configuration):

public static synchronized SessionFactory getSessionFactory() {
    if ( sessionFactory == null ) {

        // exception handling omitted for brevity

        serviceRegistry = new StandardServiceRegistryBuilder()
                .configure("hibernate_test.cfg.xml")
                .build();

        sessionFactory = new Configuration().buildSessionFactory( serviceRegistry );
    }
    return sessionFactory;
}

At the risk of TLDR, I will also point out that with respect to hibernate_test.cfg.xml my testing suggests that the configuration.getProperties() method only returns <property /> elements, and <mapping /> elements are excluded. This appears consistent with the specific use of the terms 'property' and 'mapping' within the API documentation for Configuration. I will concede that this behaviour may have something to do with the failure of applySettings() to yield the mapping data to the StandardServiceRegistryBuilder. However, this mapping data should already have been parsed during configuration of the Configuration object and available to it when buildSessionFactory() is called. Therefore, I suspect this may be due to implementation-specific details regarding resource precedence when a ServiceRegistry is passed to a Configuration object's buildSessionFactory() method.

I know this question is several years old now, but I hope this answer saves somebody the hours of research I spent in deriving it. Cheers!

like image 12
Philip Wrage Avatar answered Nov 19 '22 03:11

Philip Wrage


Add the following to your xml:

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
        <list>
            <value>annotations</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="transactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
like image 7
user2247545 Avatar answered Nov 19 '22 04:11

user2247545


For those using Spring's Java configuration classes, you might write the following:

@Autowired
@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {
    LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
    sessionBuilder.addProperties(getHibernateProperties());
    sessionBuilder.addAnnotatedClasses(Foo.class);
    sessionBuilder.addAnnotatedClasses(Bar.class);
    sessionBuilder.addAnnotatedClasses(Bat.class);
    return sessionBuilder.buildSessionFactory();
}
like image 5
Marvo Avatar answered Nov 19 '22 02:11

Marvo


I was having same problem.

Use @javax.persistence.Entity instead of org.hibernate.annotations.Entity

like image 5
Shobhit Srivastava Avatar answered Nov 19 '22 02:11

Shobhit Srivastava