简体   繁体   中英

Retrieving entities in JPQL, EclipseLink and MySQL

I've persisted some Book entities in a database called Books created by MySQL. This is my 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

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:

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. I don't understand...there are books stored in the database, why doesn't it get them?

You're calling new BookDAO() . But neither the BookDAO constructor, not the superclass constructor, initializes the em field. So it is null. So when you call a method on em , you get a 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). But that is only possible if you get a BookDAO instance from the container. 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).

It's impossible to give more details without knowing what the caller is, and in which environment you're running.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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