EJB @PersistenceContext EntityManager Throws NullP

2019-03-06 02:32发布

I'm having a problem with injecting EntityManager by using @PersistenceContext. I try to inject EntityManager in EJB class with @PersistenceContext and I always get NullPointerException.

Here is EJB class:

@Stateless
public class BookEJB {

public BookEJB(){

}

@PersistenceContext(unitName = "BookWebStorePU")
private EntityManager em;

public Book createBook(Book book) throws Exception {
    System.out.println("EM: " + em);
    em.persist(book);
    return book;
}

public Book findBookByIsbn10(String isbn10){
    Book book = new Book();
    em.find(Book.class, isbn10);
    return book;
}
//Other methods here
}

Here's Persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="BookWebStorePU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<validation-mode>NONE</validation-mode>
<properties>
  <property name="javax.persistence.schema-generation.database.action" value="create"/>
  <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
  <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/BookWebStoreDB"/>
  <property name="javax.persistence.jdbc.user" value="bookwebstoreadmin"/>
  <property name="javax.persistence.jdbc.password" value="password"/>
  <!-- Let EclipseLink create database schemas automatically -->
  <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
  <property name="eclipselink.ddl-generation.output-mode" value="database"/>
</properties>

Here's my test file:

public class BookDaoTests {

private BookEJB bookDao;
private Book newBook;

@Before
public void init() {

    newBook = new Book();      
    newBook.setName("Flying Cow");
    newBook.setDescription("Super cool story about flying cow");
    newBook.setAuthor("Me");
    newBook.setIsbn10("0123456789");
    newBook.setIllustrations(true);
    newBook.setPublishYear(2013);
    newBook.setNumberOfPages(1567);
    newBook.setQuantity(58);

    bookDao = new BookEJB();

}

@Test
public void createBook() throws Exception{
    bookDao.createBook(newBook);
    Assert.assertEquals("Book was created!", bookDao.findBookByIsbn10("0123456789"), newBook);
}


}

So when I run that test file I get following error:

Testcase: createBook(com.mysite.bookstore.tests.BookDaoTests): Caused an ERROR
null
java.lang.NullPointerException
at com.mysite.bookwebstore.beans.BookEJB.createBook(BookEJB.java:27)
at com.mysite.bookstore.tests.BookDaoTests.createBook(BookDaoTests.java:46)

EM: null

I use following technologies:

  • Glassfish 4
  • JavaEE 7
  • JSF
  • EclipseLink 2.1
  • Java DB

I hope we can find some solution for this problem. I have been tackling now 3 days of this problem and searched and tested solutions from Google and from Stackoverflow but none of the solutions helped/worked. To make sure that the EntityManager was really null, I debugged test file and saw that indeed it gives null. So how can I solve this problem?

1条回答
放我归山
2楼-- · 2019-03-06 02:54

The EntityManager instance, is injected when the EJB is deployed in the Container. If you take a look at the lifecycle of enterprise bean, you will see clearly when dependency injection occurs. When the Container sees the @Persistencecontext annotation it will inject a container-managed EntityManager.

The problem is that the code executed in this test is not managed by the Container, therefore, no one inject the necessary dependencies.

bookDao = new BookEJB();

When you run the test, the BookEJB class is just a simple POJO, the @Stateless and @PersistenceContext annotations are simply ignored.

You have several alternatives in order to test your EJB, take a look at this link.

查看更多
登录 后发表回答