简体   繁体   English

检索JPQL,EclipseLink和MySQL中的实体

[英]Retrieving entities in JPQL, EclipseLink and MySQL

I've persisted some Book entities in a database called Books created by MySQL. 我在一个名为Books的数据库中坚持使用一些Book实体。 This is my persistence.xml: 这是我的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>

this is a generic jpaDAO 这是一个通用的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();
}
...

and this is a BookDAO: 这是一本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;

}
}

In the main program I perform: 在我执行的主程序中:

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

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

and then both bookDao.findAll() and bookDao.findByAuthor("author") but I get NullPointerException so I imagine that the list allBooks is empty. 然后是bookDao.findAll()和bookDao.findByAuthor(“作者”)但我得到NullPointerException所以我想这个列表allBooks是空的。 I don't understand...there are books stored in the database, why doesn't it get them? 我不明白......数据库中存有书籍,为什么不能得到它们?

You're calling new BookDAO() . 你正在调用new BookDAO() But neither the BookDAO constructor, not the superclass constructor, initializes the em field. 但是BookDAO构造函数,而不是超类构造函数,都没有初始化em字段。 So it is null. 所以它是null。 So when you call a method on em , you get a NullPointerException. 因此,当您在em上调用方法时,会出现NullPointerException。

The EntityManager is supposed to be injected by the container (you've not specified if you ran inside an EJB/CDI container, or if you were using Spring). EntityManager应该由容器注入(如果你在EJB / CDI容器内部运行,或者如果你使用的是Spring,则没有指定)。 But that is only possible if you get a BookDAO instance from the container. 但是,只有从容器中获取BookDAO实例才有可能。 If you instanciate it yourself, the container doesn't know anything about this object, and thus can't inject any field of this object. 如果您自己实例化,容器对此对象一无所知,因此无法注入此对象的任何字段。

So, your BookDAO should be injected into its caller (which should itself be instanciated by the container). 因此,您的BookDAO应该注入其调用者(它本身应该由容器实例化)。

It's impossible to give more details without knowing what the caller is, and in which environment you're running. 如果不知道呼叫者是什么,以及你在哪个环境中运行,就不可能提供更多细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM