Consider the hierarchy :
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 ?
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
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:
configuration.addAnnotatedClass(...)
hbm.xml
file and resource mapping in hibernate_test.cfg.xml
that were redundant to the existing annotationsHowever, 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 you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With