如何修复Hibernate的未知实体异常?

huangapple go评论91阅读模式
英文:

How to fix Hibernate Unknown entity exception?

问题

我有一个用于获取会话的 HibernateSesstion 工厂类

我的实体类

来自 UserCommandsRepository 类的函数,该函数从数据库中选择一些数据

我的 hibernate.property 文件

当我尝试运行 Main.java 类时,出现错误

英文:

I have HibernateSesstion factory class for getting sesion

public class HibernateSessionFactory {

    private static SessionFactory sessionFactory = buildSessionFactory();

    protected static SessionFactory buildSessionFactory(){

        Configuration configuration = new Configuration();
        ServiceRegistry registry = new StandardServiceRegistryBuilder()
                .loadProperties("hibernate.properties").build();
        try {
            sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        }catch (Exception e){
            StandardServiceRegistryBuilder.destroy(registry);
            e.printStackTrace();
        }
        return sessionFactory;
    }

    public static SessionFactory getSessionFactory(){
        if (sessionFactory.isClosed()){
            buildSessionFactory();
        }
        return sessionFactory;
    }

My entity class

@Entity()
@Table(name = "user_commands")
public class UserCommands implements Serializable {

    @Id
    @Column(name = "chat_id")
    private Long chatId;
    @Column(name = "last_command")
    private String lastCommand;

    public Long getChatId() {
        return chatId;
    }

    public void setChatId(Long chatId) {
        this.chatId = chatId;
    }

    public String getLastCommand() {
        return lastCommand;
    }

    public void setLastCommand(String lastCommand) {
        this.lastCommand = lastCommand;
    }
}

And my function from class UserCommandsRepository which select some data

String sql = "update user_commands set last_command = :lastCommand where chat_id = :chatId";
Session session = HibernateSessionFactory.getSessionFactory().openSession();
session.beginTransaction();
session.saveOrUpdate(userCommands);
session.getTransaction().commit();
session.close();

My hibernate.property file

hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://URL
hibernate.connection.username=USERNAME
hibernate.connection.password=PASSWORD
hibernate.show_sql=true
hibernate.hbm2ddl=update

When I am trying to run my Main.java class, it's failing with error

Exception in thread "main" org.hibernate.MappingException: Unknown entity: entity.UserCommands
	at org.hibernate.metamodel.internal.MetamodelImpl.entityPersister(MetamodelImpl.java:704)
	at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1609)
	at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:293)
	at org.hibernate.event.internal.EntityState.getEntityState(EntityState.java:59)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:85)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:75)
	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
	at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:617)
	at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:610)
	at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:605)
	at repository.UserCommandsRepository.updateLastUserCommand(UserCommandsRepository.java:13)
	at highwayMotorsTelergramBot.Main.main(Main.java:26)

答案1

得分: 0

你永远不需要告诉 Hibernate 关于你的实体模型。有几种方法可以做到这一点。你可以通过 XML、Configuration 对象或 Session 对象来实现。

查阅此链接获取更多信息:https://stackoverflow.com/questions/23214454/org-hibernate-mappingexception-unknown-entity-annotations-users

英文:

You never tell Hibernate about your entity models. There are several ways to do this. You can do this via XML, the Configuration object or the Session object.

Check this for more https://stackoverflow.com/questions/23214454/org-hibernate-mappingexception-unknown-entity-annotations-users

答案2

得分: 0

文档中所述,Configuration 类被半废弃:

> Configuration 类已被半废弃,但仍可在有限的形式下使用,以消除这些缺点。 "在底层",Configuration 使用新的引导代码,因此在自动发现方面,此处可用的内容也在那里可用。

  1. 您可以按以下方式使用新的native bootstrapping api
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
    .loadProperties("hibernate.properties")
    .build();
MetadataSources metadata = new MetadataSources(serviceRegistry);
metadata.addAnnotatedClass(UserCommands.class);
// ...
Metadata meta = metadata.buildMetadata();
SessionFactory sessionFactory = meta.buildSessionFactory();
  1. 您可以按以下方式使用jpa bootstrapping
HibernatePersistenceProvider provider = new HibernatePersistenceProvider();
EntityManagerFactory emFactory = provider.createEntityManagerFactory("CRM", null);

EntityManager em = emFactory.createEntityManager();
// ...

这假设您的类路径中有META-INF文件夹,并且该文件夹包含类似以下内容的persistence.xml文件:

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">

    <persistence-unit name="CRM">
        <description>Persistence unit for Hibernate User Guide</description>
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>


        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://URL" />
            <property name="javax.persistence.jdbc.user" value="USERNAME" />
            <property name="javax.persistence.jdbc.password" value="PASSWORD" />
            
            <property name="hibernate.default_schema" value="TEST_SCHEMA" />
            
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.use_sql_comments" value="true" />
        </properties>
    </persistence-unit>
</persistence>

在这种情况下,如果您的实体与persistence.xml文件位于同一个JAR文件中,您不需要手动列出所有实体,Hibernate会自动识别它们。

英文:

As it stated in the documentation the Configuration is semi-deprecated:

> Configuration is semi-deprecated but still available for use, in a limited form that eliminates these drawbacks. "Under the covers", Configuration uses the new bootstrapping code, so the things available there are also available here in terms of auto-discovery.

  1. You can use new native bootstrapping api in the following way:
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
    .loadProperties(&quot;hibernate.properties&quot;)
    .build();
MetadataSources metadata = new MetadataSources(serviceRegistry);
metadata.addAnnotatedClass(UserCommands.class);
// ...
Metadata meta = metadata.buildMetadata();
SessionFactory sessionFactory = meta.buildSessionFactory();
  1. You can use jpa bootstrapping in the following way:
HibernatePersistenceProvider provider = new HibernatePersistenceProvider();
EntityManagerFactory emFactory = provider.createEntityManagerFactory(&quot;CRM&quot;, null);

EntityManager em = emFactory.createEntityManager();
// ...

This assumes that you have META-INF folder in your class path and this folder contains the persistence.xml file like the following:

&lt;persistence xmlns=&quot;http://xmlns.jcp.org/xml/ns/persistence&quot;
             xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
             xsi:schemaLocation=&quot;http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd&quot;
             version=&quot;2.1&quot;&gt;

    &lt;persistence-unit name=&quot;CRM&quot;&gt;
        &lt;description&gt;Persistence unit for Hibernate User Guide&lt;/description&gt;
        &lt;provider&gt;org.hibernate.jpa.HibernatePersistenceProvider&lt;/provider&gt;


        &lt;properties&gt;
            &lt;property name=&quot;javax.persistence.jdbc.driver&quot; value=&quot;com.mysql.jdbc.Driver&quot; /&gt;
            &lt;property name=&quot;javax.persistence.jdbc.url&quot; value=&quot;jdbc:mysql://URL&quot; /&gt;
            &lt;property name=&quot;javax.persistence.jdbc.user&quot; value=&quot;USERNAME&quot; /&gt;
            &lt;property name=&quot;javax.persistence.jdbc.password&quot; value=&quot;PASSWORD&quot; /&gt;
            
            &lt;property name=&quot;hibernate.default_schema&quot; value=&quot;TEST_SCHEMA&quot; /&gt;
            
            &lt;property name=&quot;hibernate.dialect&quot; value=&quot;org.hibernate.dialect.MySQLDialect&quot; /&gt;
            
            &lt;property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot; /&gt;
            &lt;property name=&quot;hibernate.format_sql&quot; value=&quot;true&quot; /&gt;
            &lt;property name=&quot;hibernate.use_sql_comments&quot; value=&quot;true&quot; /&gt;
        &lt;/properties&gt;
    &lt;/persistence-unit&gt;
&lt;/persistence&gt;

In this case you should not manually list all your entities hibernate will pick up them automatically if they lies in the same jar with persistence.xml file.

huangapple
  • 本文由 发表于 2020年10月21日 02:23:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/64451218.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定