【问题标题】:Error while trying to use Hibernate to perform SELECT operation尝试使用 Hibernate 执行 SELECT 操作时出错
【发布时间】:2012-03-04 17:07:05
【问题描述】:

我是休眠新手,在尝试使用休眠从表中选择数据时遇到错误, 我为此尝试了两种方法并遇到以下错误。

方法 1

   private static void queryPerson(Session session) {

    String SQL_QUERY ="Select person.ID as ID,person.NAME as NAME ,person.SURNAME AS SURNAME,person.ADDRESS  as ADDRESS From person";
         Query query = session.createQuery(SQL_QUERY);
         for(Iterator it=query.iterate();it.hasNext();){
         Object[] row = (Object[]) it.next();
         System.out.println("ID: " + row[0]);
         System.out.println("Name: " + row[1]);
         System.out.println("Amount: " + row[2]);
         session.getTransaction().commit();
         }

这会引发以下错误:

 Exception in thread "main" org.hibernate.hql.ast.QuerySyntaxException: person is not mapped [Select person.ID as ID,person.NAME as NAME ,person.SURNAME AS SURNAME,person.ADDRESS  as ADDRESS From person]
at org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:180)
at org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:111)
at org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:93)
at org.hibernate.hql.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:327)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3441)

方法二:

  private static void queryPerson(Session session) {
  Query query = session.createQuery("from Person");                 
    List <Person>list = query.list();
    java.util.Iterator<Person> iter = list.iterator();
    while (iter.hasNext()) {

        Person person = iter.next();
        System.out.println("Person: \"" + person.getName() +"\", " + person.getSurname() +"\", " +person.getAddress());
  session.getTransaction().commit();

    }

抛出以下错误:

Caused by: org.postgresql.util.PSQLException: ERROR: column person0_.id does not exist
Position: 8
at    org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
at   org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)

如果有人能指出我哪里出错了,那就太好了。 谢谢! 编辑: 人.hbm.xml

<class name="com.sample.Person" table="Person">

    <id name="id" column="ID">
        <generator class="native" />
    </id>

    <property name="name">
        <column name="NAME" length="16" not-null="false" />
    </property>

    <property name="surname">
        <column name="SURNAME" length="16" not-null="false" />
    </property>

    <property name="address">
        <column name="ADDRESS" length="16" not-null="false" />
    </property>

</class>

hibernate.cfg.xml

    <!-- hibernate dialect -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>


    <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
    <property name="hibernate.connection.url">jdbc:postgresql://localhost/testDB</property>
    <property name="hibernate.connection.username">postgres</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.show_sql">true</property> 
    <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

    <!-- Automatic schema creation (begin) === -->
    <property name="hibernate.hbm2ddl.auto">validate</property>


    <!-- Simple memory-only cache -->
    <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- ############################################ -->
    <!-- # mapping files with external dependencies # -->
    <!-- ############################################ -->

    <mapping resource="com/sample/Person.hbm.xml" />

</session-factory>

编辑:这是我使用的 Person 类:

 package com.sample;

 public class Person {
  Long id;
   String name;
   String surname;
   String address;

public Long getId() {
    return id;
}
private void setId(Long id) {
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getSurname() {
    return surname;
}
public void setSurname(String surname) {
    this.surname = surname;
}
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
 }
}           

【问题讨论】:

  • 人没有被映射..也许它应该是人? docs.jboss.org/hibernate/orm/3.3/reference/en/html/…
  • 在问题中添加了数据,看看吧!
  • 在第一种情况下,您可以调用“createSQLQuery”,因为它对我来说就像一个原生 sql 查询。
  • MySQLInnoDBDialect 只用于 MySQL 数据库,如果你有 Postgres,你应该改变它。
  • ^以上请查看@Adi 回答中的 cmets

标签: java sql hibernate jakarta-ee


【解决方案1】:

您是否为 Person 类提供了注解 @Entity ?

HQL 不同于 SQL。我认为您的查询有问题:

String SQL_QUERY ="选择 person.ID 作为 ID,person.NAME 作为 NAME,person.SURNAME 作为 SURNAME,person.ADDRESS 作为 ADDRESS From person";

尝试类似: HQL:从 Person 中选择 person.id、person.name、person.surname、person.address 作为人员

表名总是大写,匹配你的类名。 对于列名,这些必须与您的实例变量匹配。

更新(使用 Unitils 进行 Hibernate 映射测试):

import org.junit.Test;
import org.junit.runner.RunWith;
import org.unitils.UnitilsJUnit4TestClassRunner;
import org.unitils.orm.hibernate.HibernateUnitils;
import org.unitils.spring.annotation.SpringApplicationContext;

/**
 * Unitils mapping test class.
 * 
 */
@SpringApplicationContext({ "spring.xml" })
@RunWith(UnitilsJUnit4TestClassRunner.class)
public class HibernateMappingTest {

    @Test
    public void testMappingToDatabase() {
        HibernateUnitils.assertMappingWithDatabaseConsistent();
    }

}

【讨论】:

  • 我试图在没有注释的情况下这样做。由于我遵循的示例没有提及对它们的任何引用
  • @kclaes 他/她在方法 2 中所做的。
  • @kclaes,该问题已解决,但现在我收到有关序列的错误:错误仍然存​​在:缺少序列或表:hibernate_sequence 原因:org.hibernate.HibernateException:缺少序列或表: hibernate_sequence at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1354) –
  • @KodeSeeker 也许你必须改变你的 hibernate.hbm2ddl.auto 属性来更新:true更新truetrue
  • @kclaes,我通过创建名为“hibernate_sequence”的序列来创建 ID 来修复该错误,但现在我收到以下错误:org.hibernate.exception.SQLGrammarException:无法执行查询在 org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92) 引起:org.postgresql.util.PSQLException:错误:列 p.id 不存在位置:8。知道为什么会发生这种情况吗?
【解决方案2】:

缺少映射类的名称和别名。您的查询应该是,

Select person.ID as ID,person.NAME as NAME ,person.SURNAME AS SURNAME,person.ADDRESS  as ADDRESS From Person as person

注意“From Person”中的大写“P”。我假设方法 1 和方法 2 中的代码库是相同的。在方法 2 中,类名是“Person”而不是“person”,除非您打算执行本机 sql。在这种情况下,您应该调用 session.createSQLQuery 并尝试是否能够直接在 db 上执行相同的查询。

从方法 2 异常跟踪,您的映射是错误的。验证映射是否存在表和列名是否正确。

【讨论】:

  • :尝试了您的方法并得到以下错误(我假设您建议的查询是针对方法 1):初始 SessionFactory 创建失败。org.hibernate.HibernateException:缺少序列或表:hibernate_sequence 原因: org.hibernate.HibernateException: Missing sequence or table: hibernate_sequence.. 我应该在哪里创建这个序列?
  • @Adi- 这样做并得到以下错误:线程“main”中的异常 org.hibernate.exception.SQLGrammarException:无法执行 JDBC 批量更新所使用的:java.sql.BatchUpdateException:批处理条目0 插入人(姓名、姓氏、地址、ID)值('Barak'、'Obhama'、'White House'、'1')被中止。调用 getNextException 查看原因。好像我在兜圈子:s
【解决方案3】:

试试这个:

person.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
  <class name="com.sample.Person" table="Person">
      <id name="id" column="ID">
        <generator class="native" />
    </id>
    <property name="name">
        <column name="NAME" length="16" not-null="false" />
    </property>

    <property name="surname">
        <column name="SURNAME" length="16" not-null="false" />
    </property>

    <property name="address">
        <column name="ADDRESS" length="16" not-null="false" />
    </property>
</class>
</hibernate-mapping>

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
      ...your database configurations and mapping file...

</session-factory>
</hibernate-configuration>

HibernateUtil.java

public class HibernateUtil {

        private static final SessionFactory sessionFactory;

        static {
            try {
                // Create the SessionFactory from hibernate.cfg.xml
                // ------ --- -------------- ---- -----------------
                sessionFactory = new Configuration().configure()
                        .buildSessionFactory();
            } catch (Throwable ex) {
                // Make sure you log the exception, as it might be swallowed
                // ---- ---- --- --- --- ---------- -- -- ----- -- ---------
                System.err.println("Initial SessionFactory creation failed." + ex);
                throw new ExceptionInInitializerError(ex);
            }
        }

        /**
         * Get the configured session factory
         * 
         * @return session factory
         */
        public static SessionFactory getSessionFactory() {
            return sessionFactory;
        }
    }

一个例子:

public class PersonExample{
    public static void main(String[] args) {
        Session session = null;
        try {
            SessionFactory sessionFactory = new Configuration().configure()
                    .buildSessionFactory();
            session = sessionFactory.openSession();
            System.out.println("Starting select");
            List<Person> persons= session.createSQLQuery("select {p.*} from Person p").addEntity("p", Person.class).list();
            for (Iterator<Person> it = persons.iterator(); it.hasNext();) {
            Person stObject = it.next();
               System.out.println("ID: " + stObject.getId());
               System.out.println("Surname: " + stObject.getSurname());
               System.out.println("Name: " + stObject.getName());
               System.out.println("Address: " + stObject.getAddress());
            }
            System.out.println("Finished select");
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        } finally {
            // Actual contact insertion will happen at this step
            session.flush();
            session.close();
        }

    }
}

【讨论】:

  • 嘿,谢谢你的例子:但在尝试这个时我得到:org.hibernate.exception.SQLGrammarException: could not execute query at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)原因:org.postgresql.util.PSQLException:错误:列 p.id 不存在位置:8。知道为什么会发生这种情况吗?
  • 是的,我在 Person 类中确实有一个字段 id 和一个列
  • 这是使用 CREATE TABLE person 的表的脚本("ID" bigint NOT NULL DEFAULT nextval('hibernate_sequence'::regclass),"name" 字符不同,姓氏字符不同,地址字符不同, 约束 person_pkey PRIMARY KEY ("ID") ) WITH (OIDS=FALSE);将表人所有者更改为 postgres;至于自动增量,我认为 postgresql 不提供,所以我让 pkey 引用一个序列。
  • 在 Person.hbm.xml 中进行更改以及更正的方法 1 会导致以下错误:线程“main”java.lang.IllegalArgumentException 中的异常:要遍历的节点不能为空!在 org.hibernate.hql.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:63)
  • 我应该然后将数据库中的序列从“hibernate_sequence”重命名为“person_id_seq”吗?编辑:尝试过,并替换了 Person.hbm.xml 中的 id 片段并面临与以前相同的错误!
猜你喜欢
  • 2021-04-11
  • 1970-01-01
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
相关资源
最近更新 更多