【问题标题】:hibernate: how to select all rows in a tablehibernate:如何选择表中的所有行
【发布时间】:2015-10-13 13:04:27
【问题描述】:

我尝试用 Hibernate 做类似Select * from LogEntry 的事情。 插入工作正常:

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

[...]
protected EntityManager manager;

protected final String tableName = "LogEntry";

public DatabaseImpl(DB_TYPE db) {
    this.db = db;
    if (entityManagerFactory != null && entityManagerFactory.isOpen()) {
        entityManagerFactory.close();
    }
    entityManagerFactory = Persistence.createEntityManagerFactory(db.getPersUnit());
    manager = entityManagerFactory.createEntityManager();
}
public void insert(LogEntry entry) {

    manager.getTransaction().begin();
    manager.persist(entry);
    manager.getTransaction().commit();
}

但是当我尝试使用这种方法获取插入的值时: 公共 LogEntryList getAll() {

    manager.getTransaction().begin();

    Query query = manager.createNativeQuery("SELECT * FROM " + tableName + ";");
    ArrayList<LogEntry> entries = (ArrayList<LogEntry>) query.getResultList();
    manager.getTransaction().commit();

    return new LogEntryList(entries);
}

我总是得到异常: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to de.motza.entities.LogEntry

我知道问题在于将查询结果转换为对象,但我找不到任何地方如何正确转换对象,或如何从表中获取多行。

有人有什么建议吗? 如果需要,我可以发布我的 persistence.xml 和更多代码

【问题讨论】:

  • 你用的是哪个版本的hibernate?
  • 试试这个 Query query = manager.createNativeQuery("SELECT * FROM " + tableName + ";", LogEntry.class); List 条目 = query.getResultList();
  • 休眠 entityManager 4.3.8.Final
  • 请查看下面给出的答案。

标签: java mysql sql hibernate postgresql


【解决方案1】:

如果你使用 Spring HibernateDaoSupport,你可以使用这些方法从数据库中加载实体:

a) 按 ID 的单个实体

@Override
public DeleteProcessNotification getDeleteProcessNotificationById(Long id) {
    return this.getHibernateTemplate().load(DeleteProcessNotification.class, id);
}

b) 所有实体

@Override
public List<DeleteProcessNotification> getDeleteProcessNotificationsInQueue() {
    return this.getHibernateTemplate().loadAll(DeleteProcessNotification.class);
}

c) 具有 HQL 查询的实体

@Override
public List<DeleteProcessNotification> getPrioritizedDeleteProcessNotifications() {
    return (List<DeleteProcessNotification>) this.getHibernateTemplate().find(
            "FROM DeleteProcessNotification dpn \n" +
                    "WHERE dpn.priority = 'HIGH'");
}

HibernateDaoSupport 文档:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/orm/hibernate5/support/HibernateDaoSupport.html

【讨论】:

    【解决方案2】:

    因为你使用了nativeQuery所以你需要使用setResultTransormer方法来传递结果。

    Query query = manager.createNativeQuery("SELECT * FROM " + tableName + ";");
    query.setResultTransformer(Transformers.aliasToBean(LogEntry.class))
    ArrayList<LogEntry> entries = (ArrayList<LogEntry>) query.getResultList();
    

    【讨论】:

    • 你从哪里得到 Transformers.aliasToBean() 来自?
    【解决方案3】:
    List<String> list = null;
    
    TypedQuery<String> query = sessionfactory.openSession().createQuery("from yourTableName");
    
    list = query.getResultList();
    

    yourTableName 可以是你的@Entity

    【讨论】:

      【解决方案4】:

      你可以使用 session.createCriteria(MyEntity.class).list(); 例如。

      参考:Retrieving all rows of a table without HQL?

      【讨论】:

      • SharedSessionContract 类型的方法 createCriteria(Class) 现已弃用。
      【解决方案5】:

      据我所知,getResultList() 为您提供了一个列表...不是通用列表。所以如果你想得到一个通用列表,你必须使用

      TypedQuery<Person> 
      

      插入

      Query
      

      这是我得到信息的链接。

      Cast to something the result of Query.getResultList()?

      我对 Hibernate 了解不多。我希望这能帮到您。

      【讨论】:

        【解决方案6】:

        对于初学者,您应该尝试利用 HQL,即 Hibernate 查询语言。在上面给出的示例中,您正在尝试执行本机 SQL 查询。您获得ClassCastException 的原因是本机查询绕过了框架并返回原始Objects 而不是您想要的类型。

        尝试将此代码用于您的SELECT *

        String hql = "from LogEntry";
        Session session = entityManagerFactory.openSession();
        Query query = session.createQuery(hql);
        List<LogEntry> logEntries = query.list();      // no ClassCastException here
        

        【讨论】:

        • 虽然不完全是用户想要的,但这无疑是有益的信息。这是给我的。谢谢你的回答@Tim Biegeleisen :)
        【解决方案7】:

        “问题”是,您正在发送一个本机查询,该查询将返回一个 Object[] 数组,每个数组都有一个值。您不需要调用原生查询,而是休眠查询,例如......

        manager.createQuery("SELECT l FROM LogEntry");

        例如,请参阅this answer

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-12
          • 1970-01-01
          • 1970-01-01
          • 2013-10-16
          • 1970-01-01
          • 2017-08-29
          • 1970-01-01
          相关资源
          最近更新 更多