org.hibernate.MappingException:未知实体:annotations.Users

时间:2014-04-22 08:34:50

标签: java hibernate exception entity

考虑层次结构:

enter image description here

以下类和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();
        }


    }
}

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>

当我运行main()时,输出窗口中会出现以下错误:

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

但是实体Users位于annotations包中,那么错误是什么?

21 个答案:

答案 0 :(得分:65)

Hibernate配置文件必须定义实体类:

<mapping class="annotations.Users"/>

或者您必须使用

将类显式添加到配置中
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

答案 1 :(得分:11)

当我尝试重写我的示例(从tutorialspoint)以使用注释时,我得到了相同的异常。这对我有帮助(addAnnotatedClass()):

Configuration cfg=new Configuration(); 
cfg.addAnnotatedClass(com.tutorialspoint.hibernate.entity.Employee.class);
cfg.configure();

答案 2 :(得分:7)

将以下内容添加到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>

答案 3 :(得分:5)

对于使用Spring的Java配置类的用户,可以编写以下内容:

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

答案 4 :(得分:5)

我遇到了同样的问题。

使用@javax.persistence.Entity代替org.hibernate.annotations.Entity

答案 5 :(得分:3)

如果您的实体是通过注释映射的,请将以下代码添加到您的配置中;

configuration.addAnnotatedClass(theEntityPackage.EntityClassName.class);

例如;

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

如果您的实体使用xml文件映射,请使用addClass而不是addAnnotatedClass。

作为一个例子;

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

如果您需要更多帮助,请告诉我。

答案 6 :(得分:3)

我没有发现接受的答案有助于解决我的代码中遇到的异常。虽然技术上不正确,但我也不满意其他人提出的引入冗余的建议:

  • 使用configuration.addAnnotatedClass(...)
  • 以编程方式重新添加映射的类
  • hbm.xml中创建一个hibernate_test.cfg.xml文件和资源映射,这对现有注释是多余的
  • 使用原始问题中未提及的外部依赖项
  • 扫描存在(已映射的)类的包

但是,我找到了两个我想分享的可能解决方案,这两个解决方案独立解决了我在自己的代码中遇到的异常。

我和@ron一样MappingException(使用几乎相同的HibernateUtil类):

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
}

在我的hibernate_test.cfg.xml配置文件中,我有所需的类映射:

<mapping class="myPackage.Device"/>

我的Device类已使用javax.persistence.Entity注释正确注释:

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

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

两种可能的解决方案:

首先 ,我正在使用Hibernate 5.2,对于那些使用Hibernate 5的人来说,使用Metadata对象来构建SessionFactory的解决方案应该是工作。它似乎也是native bootstrap mechanism中目前推荐的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;
}

第二次 ,虽然Configurationsemi-deprecated in Hibernate 5,但@ron没有说他正在使用哪个版本的Hibernate,所以此解决方案可以一些人也有价值。

在实例化和配置ConfigurationServiceRegistry个对象时,我发现操作顺序发生了微妙的变化,以便在我自己的代码中发挥重要作用。

原始订单(在Configuration之前创建并配置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;
}

新订单(在ServiceRegistry之前创建并配置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;
}

冒着TLDR的风险,我还要指出,对于hibernate_test.cfg.xml,我的测试表明configuration.getProperties()方法仅返回<property />元素和<mapping />元素被排除在外。这似乎与Configuration applySettings()中“属性”和“映射”这两个术语的具体用法一致。我承认这种行为可能与StandardServiceRegistryBuilder未能将映射数据生成Configuration有关。但是,在配置buildSessionFactory()对象期间应该已经解析了这个映射数据,并且在调用ServiceRegistry时可以使用它。因此,我怀疑这可能是由于Configuration传递给buildSessionFactory()对象的<b><img src='rat.png'></img></b>方法时有关资源优先级的特定于实现的详细信息。

我知道这个问题现在已有几年了,但我希望这个答案可以节省一些人在研究中花费的时间。干杯!

答案 7 :(得分:3)

我遇到了同样的问题,我搜索了将近2个小时,尝试了不同的方法,例如替换旧的hibernate JAR和更改数据库表架构。但最终得到了如下解决方案:

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

替换上面的

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

然后它会正常工作..

答案 8 :(得分:1)

不是使用HibernateUtil.java来创建sessionfactory对象,而应该使用它:

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

因为为了避免异常,你必须将HibernateUtil.java文件中的类对象声明为configuration.addAnnotatedClass(Student_Info.class);看起来很愚蠢,因为我们已经在hibernate.cfg.xml文件中提供了这个条目。 / p>

要使用AnnotationConfiguration类,您必须在项目构建路径中添加jar: http://www.java2s.com/Code/Jar/h/Downloadhibernate353jar.htm

答案 9 :(得分:1)

我遇到了类似问题并添加了

test['percentage'].count().where(test['percentage'].sum()<=50,0)

此行有所帮助但在此之前我正在

 sessionFactory.setAnnotatedClasses(User.class);

我不确定为什么那个不工作。用户类在com.rg.spring.model下 请通过packagesToScan方法告诉我如何使其正常工作。

答案 10 :(得分:0)

 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

答案 11 :(得分:0)

将以下代码添加到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>

答案 12 :(得分:0)

检查包名称是否在dispatcher-servlet.xml中的属性packagesToScan 中给出

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

答案 13 :(得分:0)

如果您可以承受外部依赖,请使用 EntityScanner 。它将从多个包中无缝地注入您的所有实体类。只需在配置设置后添加以下行。

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>

这样您就不需要在hibernate映射文件中声明所有实体。

答案 14 :(得分:0)

如果您使用的是5.0x版本,则不赞成使用配置标准服务注册表。

相反,您应该使用元数据进行引导: 在您的HibernateUtil类中,您应该添加

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(...) {
        ...
    }
}

答案 15 :(得分:0)

对于我来说,它是通过在hibernateUtill类的configuration.addAnnotatedClass(com.myApp.model.Example.class);之后添加Configuration configuration = new Configuration().configure(HibernateUtil.class.getResource("/hibernate.cfg.xml"));来解决的。 它从类注释元数据中读取映射。 从here中了解有关addAnnotatedClass()的更多信息。

答案 16 :(得分:0)

最初,我尝试使用以下对我不起作用的代码

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

对我来说,以下配置有效。我从代码本身并使用hibernate 5+版本提供了所有hibernate属性。我正在尝试连接到Postgressql数据库。

进口:

 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;

代码:

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

最新更新: 使用 Reflections 软件包作为依赖项,对我来说,还有一个选项起作用。我在mysql和postgress上都尝试过,并且效果很好。

有关反射的一些信息: Reflections库用作类路径扫描器。它索引扫描的元数据,并允许我们在运行时查询它。它还可以保存此信息,因此我们可以在项目进行过程中的任何时候收集和使用它,而无需再次重新扫描类路径

如果您使用的是maven:

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

代码:

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

答案 17 :(得分:0)

我遇到了同样的错误,唯一对我有用的是将 hibernate.cfg.xml 的位置更改为 src/main/resources

答案 18 :(得分:0)

我通过在 .xml 配置属性 name="packagesToScan" 中添加 value="SCANN_YOUR_PACKAGE.controller.entity" 来修复此错误,以显示 Hibernate 的实体包在哪里。

<!--  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>  

答案 19 :(得分:-1)

由于mapping class="annotations.Users"中的条目hibernate.cfg.xml删除了该行,因此会出现问题。

我有同样的问题。当我删除上面的行时,它对我来说工作正常。

答案 20 :(得分:-1)

Hibernate.cfg.xml中定义Entity

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

创建sessionFactory对象时加载配置文件,如

SessionFactory factory = new AnnotationConfiguration().configure("hibernate.cfg.xml").buildSessionFactory();