Question

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 ?

Était-ce utile?

La solution

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

Autres conseils

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();

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!

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>

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

I was having same problem.

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

If your entity is mapped through annotations, add the following code to your configuration;

configuration.addAnnotatedClass(theEntityPackage.EntityClassName.class);

For example;

configuration.addAnnotatedClass(com.foo.foo1.Products.class);

if your entity is mapped with xml file, use addClass instead of addAnnotatedClass.

As an example;

configuration.addClass(com.foo.foo1.Products.class);

Ping me if you need more help.

I was facing the same issue and I searched for almost 2 hours and tried with different possible ways like replacing old hibernate JARs and changing the DB table schema. But finally got the solution as below:

SessionFactory factory = new Configuration().configure().buildSessionFactory(); //This line to be replaced with below commented line

Replace above for

//Configuration config = new Configuration().configure();
//ServiceRegistry servReg = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
//SessionFactory factory = config.buildSessionFactory(servReg);

It will then work fine..

Instead of using HibernateUtil.java, to create sessionfactory object, you should use this:

SessionFactory sessionFactory=new AnnotationConfiguration().configure().buildSessionFactory();

Because in order to avoid the exception, you'll have to declare the class object in HibernateUtil.java file as configuration.addAnnotatedClass(Student_Info.class); which looks dumb because we have provided the entry already in hibernate.cfg.xml file.

To use the AnnotationConfiguration class you'll have to add a jar to your project build path: http://www.java2s.com/Code/Jar/h/Downloadhibernate353jar.htm

I was having similar issue and adding

 sessionFactory.setAnnotatedClasses(User.class);

this line helped but before that I was having

sessionFactory.setPackagesToScan(new String[] { "com.rg.spring.model" });

I am not sure why that one is not working.User class is under com.rg.spring.model Please let me know how to get it working via packagesToScan method.

Define the Entity class in Hibernate.cfg.xml

<mapping class="com.supernt.Department"/>

While creating the sessionFactory object Load the Configuration file Like

SessionFactory factory = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();
 public static void main(String[] args) {
      try{
        // factory = new Configuration().configure().buildSessionFactory();
         factory = new AnnotationConfiguration().
                   configure().
                   //addPackage("com.xyz") //add package if used.
                   addAnnotatedClass(Employee.class).
                   buildSessionFactory();
      }catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }//you can write like this in your test class inside main method.this way you will be able to do the things using annotaions only

Add the following code to hibernate.cfg.xml

  <property name="hibernate.c3p0.min_size">5</property>
  <property name="hibernate.c3p0.max_size">20</property>
  <property name="hibernate.c3p0.timeout">300</property>
  <property name="hibernate.c3p0.max_statements">50</property>
  <property name="hibernate.c3p0.idle_test_period">3000</property>

Check the package name is given in the property packagesToScan in the dispatcher-servlet.xml

<bean id="sessionFactory"             class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <property name="packagesToScan" value="**entity package name here**"></property> 
        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>  
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>  
            </props>  
        </property>  
    </bean>

Use EntityScanner if you can bear external dependency.It will inject your all entity classes seamlessly even from multiple packages. Just add following line after configuration setup.

Configuration configuration = new Configuration().configure();    
EntityScanner.scanPackages("com.fz.epms.db.model.entity").addTo(configuration);
// And following depencency if you are using Maven
<dependency>
        <groupId>com.github.v-ladynev</groupId>
        <artifactId>fluent-hibernate-core</artifactId>
        <version>0.3.1</version>
</dependency>

This way you don't need to declare all entities in hibernate mapping file.

If you are using 5.0x version,configuration with standard service registry is deprecated.

Instead you should bootstrap it with Metadata: In your HibernateUtil class, you should add

private static SessionFactory buildSessionFactory() {
    try {           
        StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
            .configure( "hibernate.cfg.xml" )
            .build();

        Metadata metadata = new MetadataSources( standardRegistry )
            .getMetadataBuilder()
            .build();

        return metadata.getSessionFactoryBuilder().build();
    } catch(...) {
        ...
    }
}

In my case it resolves by adding configuration.addAnnotatedClass(com.myApp.model.Example.class); after Configuration configuration = new Configuration().configure(HibernateUtil.class.getResource("/hibernate.cfg.xml")); in hibernateUtill class. It Read a mapping from the class annotation metadata . Read more about addAnnotatedClass() from here.

Initially I trying with the below code which didn't work for me

MetadataSources metadataSources = new MetadataSources(serviceRegistry);
Metadata metadata = metadataSources.getMetadataBuilder().build();
SessionFactory sessionFactory= metadata.getSessionFactoryBuilder().build();

For me below configuration worked. All the hibernate properties i provided from the code itself and using hibernate version 5+. I'm trying to connect to the Postgressql db.

imports:

 import org.hibernate.Session;
 import org.hibernate.SessionFactory;
 import org.hibernate.Transaction;
 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 import org.hibernate.cfg.Configuration;
 import org.hibernate.cfg.Environment;
 import org.hibernate.service.ServiceRegistry;

code:

    Configuration configuration = new Configuration();
    configuration.setProperty("hibernate.current_session_context_class", "thread");
    configuration.setProperty(Environment.DRIVER, "org.postgresql.Driver");
    configuration.setProperty(Environment.URL, lmsParams.getDbProperties().getDbURL());
    configuration.setProperty(Environment.USER, lmsParams.getDbProperties().getUsername());
    configuration.setProperty(Environment.PASS, lmsParams.getDbProperties().getPassword());

    configuration.setProperty("hibernate.connection.release_mode", "auto");
    configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
    configuration.setProperty("hibernate.show_sql", "true");
    configuration.setProperty(Environment.HBM2DDL_AUTO, "create");
    configuration.addAnnotatedClass(LMSSourceTable.class);
    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
            .applySettings(configuration.getProperties())
            .build();
    SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);

Latest Update: One more option worked for me using the Reflections package as a dependency. This i tried with both mysql and postgress and it works fine.

Some info about Reflections: The Reflections library works as a classpath scanner. It indexes the scanned metadata and allows us to query it at runtime. It can also save this information, so we can collect and use it at any point during our project, without having to re-scan the classpath again

if you are using maven:

<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>

code:

 MetadataSources metadataSources = new 
 MetadataSources(serviceRegistry);
 Reflections entityPackageReflections = new Reflections("com.company.abc.package.name");
    entityPackageReflections.getTypesAnnotatedWith(Entity.class).forEach(metadataSources::addAnnotatedClass);
    Metadata metadata = metadataSources.getMetadataBuilder().build();
    SessionFactory sessionFactory=  metadata.getSessionFactoryBuilder().build();

I had the same error and the only thing that worked for me was to change the location of hibernate.cfg.xml to src/main/resources

I fix this error by add in the .xml configuration property name="packagesToScan" with value="SCANN_YOUR_PACKAGE.controller.entity" to show a Hibernate where is the package of entity's.

<!--  Configu Hibernate session factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="packagesToScan" value="SCANN_YOUR_PACKAGE.controller.entity" />
        <property name="hibernateProperties">
           <props>
              <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
              <prop key="hibernate.show_sql">true</prop>
           </props>
        </property>
   </bean>  

@Entity is deprecated then **error shows Exception in thread "main" org.springframework.orm.hibernate5.HibernateSystemException: Unknown entity: com.spring.orm.entities.Student; nested exception is org.hibernate.MappingException: Unknown entity: com.spring.orm.entities.Student **

My Code is

package com.spring.orm.entities;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Entity;

@Entity
@Table(name = "student_details")
public class Student {

    @Id
    @Column(name = "student_id")
    private int studentId;
    @Column(name = "student_name")
    private String studentName;
    @Column(name = "student_city")
    private String studentCity;

    public Student(int studentId, String studentName, String studentCity) {
        super();
        this.studentId = studentId;
        this.studentName = studentName;
        this.studentCity = studentCity;
    }

    public Student() {

    }

    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getStudentCity() {
        return studentCity;
    }

    public void setStudentCity(String studentCity) {
        this.studentCity = studentCity;
    }

}

You can use @javax.persistence.Entity in place of @Entity

    package com.spring.orm.entities;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Entity;

@javax.persistence.Entity
@Table(name = "student_details")
public class Student {

    @Id
    @Column(name = "student_id")
    private int studentId;
    @Column(name = "student_name")
    private String studentName;
    @Column(name = "student_city")
    private String studentCity;

    public Student(int studentId, String studentName, String studentCity) {
        super();
        this.studentId = studentId;
        this.studentName = studentName;
        this.studentCity = studentCity;
    }

    public Student() {

    }

    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public String getStudentCity() {
        return studentCity;
    }

    public void setStudentCity(String studentCity) {
        this.studentCity = studentCity;
    }

}

For more details you can see on my youtube channel https://youtu.be/uwLU65E4q3Y

The exception occurs because hibernate can locate mapping file (someEntity.hbm.xml)

One of the solution is to add hbm xml file to configuration while generating session factory.

configuration.addResource("someEntity.hbm.xml");

Problem occurs because of the entry mapping class="annotations.Users" in hibernate.cfg.xml remove that line then it will be work.

I had the same issue. When I removed the above line then it was working fine for me.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top