【问题标题】:Retrieving entities in JPQL, EclipseLink and MySQL在 JPQL、EclipseLink 和 MySQL 中检索实体
【发布时间】:2013-12-06 15:40:47
【问题描述】:

我在 MySQL 创建的名为 Books 的数据库中保留了一些 Book 实体。 这是我的 persistence.xml:

<persistence-unit name="mysqltest" transaction-type="RESOURCE_LOCAL">

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

<!-- list all classes -->
<class>it.mysql.beginner.User</class>
<class>it.mysql.beginner.Book</class>
<class>it.mysql.beginner.Kind</class>

<properties>
  <!-- some properties needed by persistence provider:
    - driver
    - db url
    - db user name
    - db user password -->
  <property name="javax.persistence.target-database" value="MySQL"/>
  <property name="javax.persistence.logging.level" value="INFO"/>
  <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
  <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/Books"/>
  <property name="javax.persistence.jdbc.user" value="lory"/>
  <property name="javax.persistence.jdbc.password" value="brookhaven12#"/>
  <property name="eclipselink.ddl-generation.output-mode" value="database" />

  <property name="eclipselink.ddl-generation" value="create-tables" />

  </properties>

</persistence-unit>

这是一个通用的 jpaDAO

public abstract class jpaDAO<E> {

protected Class<E> entityClass;

@PersistenceContext(unitName = "mysqltest")
protected EntityManager em;

@SuppressWarnings("unchecked")
public jpaDAO() {
    ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
    this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[0];
}

public List<E> findAll() {
    TypedQuery<E> q = em.createQuery("SELECT h FROM " + entityClass.getSimpleName() + " h", entityClass);
    return q.getResultList();
}
...

这是一个 BookDAO:

public class BookDAO extends jpaDAO<Book> {

public List<Book> findByAuthor(String author) {

    List<Book> bookList;

    TypedQuery<Book> query = em.createQuery("SELECT b FROM Book b WHERE b.author = author", entityClass);

            query.setParameter("author", author);

            bookList = query.getResultList();

    return bookList;

}
}

在我执行的主程序中:

List<Book> allBooks;
BookDAO bookDAO = new BookDAO();

allBooks = bookDAO.findByAuthor("Stephen King");

然后是 bookDao.findAll() 和 bookDao.findByAuthor("author") 但我明白了 NullPointerException 所以我想列表 allBooks 是空的。 不明白……数据库里有书,怎么查不到?

【问题讨论】:

  • 你到底为什么要捕获 NullPointerException? NullPointerException 是一个错误。抓住它会隐藏错误,而不是解决它。不要捕获 NullPointerException。永远不要从返回集合的方法中返回 null。并修复您的查询和方法:它不使用作者参数。
  • 我已经写了你所说的更正但是,即使我没有捕捉到异常,这也是我从控制台读到的:
  • it.mysql.beginner.dao.BookDAO.findByAuthor(BookDAO.java:20) 在 it.mysql.beginner.Main.main(Main) 的线程“main”中出现异常 java.lang.NullPointerException .java:138)
  • 执行此操作时似乎收到此 NullPointerException:
  • TypedQuery query = em.createQuery("SELECT b FROM Book b WHERE b.author = author", entityClass);

标签: java mysql jdbc eclipselink jpql


【解决方案1】:

你打电话给new BookDAO()。但是无论是 BookDAO 构造函数,还是超类构造函数,都没有初始化 em 字段。所以它是空的。所以当你在em 上调用一个方法时,你会得到一个 NullPointerException。

EntityManager 应该由容器注入(您没有指定是在 EJB/CDI 容器中运行,还是使用 Spring)。但这只有在您从容器中获取 BookDAO 实例时才有可能。如果你自己实例化它,容器对这个对象一无所知,因此不能注入这个对象的任何字段。

因此,您的 BookDAO 应该被注入到它的调用者中(它本身应该被容器实例化)。

如果不知道调用者是什么以及您在哪个环境中运行,就不可能提供更多详细信息。

【讨论】:

  • 我正在尝试使用 Spring...我应该使用 @Autowired bookDAO 吗?我对所有这些事情真的很陌生,我有很多困惑......
  • 是的,您应该使用 Autowired BookDAO。必须注入的所有东西都必须来自 Spring 容器。
  • 我得到同样的错误...我真的很恐慌,你能帮我写一些代码吗?
  • 不,我不会。呆在帕尼不会有帮助。花一些时间阅读 Spring 文档并掌握依赖注入的概念。这很关键。
  • 目前我已经通过明确添加缺少的内容来解决问题:
猜你喜欢
  • 2012-11-17
  • 1970-01-01
  • 2017-09-20
  • 2023-03-20
  • 2020-04-24
  • 2017-01-19
  • 2016-07-26
  • 2018-10-25
  • 2020-07-31
相关资源
最近更新 更多