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?
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.
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.