简体   繁体   English

Glassfish JPA:注入EntityManager时遇到问题

[英]Glassfish JPA: Problems injecting EntityManager

I am new to Java EE. 我是Java EE的新手。 I tried to get some first examples running (JPA). 我试图使一些第一个示例运行(JPA)。 I am using Glassfish v3. 我正在使用Glassfish v3。 The trouble is that I don't get the App Server injecting the EntityManager. 问题是我没有让App Server注入EntityManager。 Hear is one example http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_for which I extended with a JSP client. 听到的一个例子是http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_ ,为此我使用JSP客户端进行了扩展。

Entity: 实体:


package beans;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Book {

    @Id
    @GeneratedValue
    private Long id;
    private String title;
    private String subtitle;

    public Book() {
    }

    public Book(String title) {
        this.title = title;
    }
}

BookService Interface: BookService接口:


package beans;
import javax.ejb.Local;

@Local
public interface BookService {
    Book createOrUpdate(Book book);
    void remove(Book book);
    Book find(Object id);
}

BookServiceBean: BookServiceBean:


package beans;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class BookServiceBean implements BookService {

    @PersistenceContext
    private EntityManager em;

    public Book createOrUpdate(Book book) {
        return em.merge(book);
    }
    public void remove(Book book) {
        em.remove(em.merge(book));
    }
    public Book find(Object id) {
        return em.find(Book.class, id);
    }
}

persistence.xml: persistence.xml:

<persistence>
    <persistence-unit name="sample" transaction-type="JTA">
    <jta-data-source>jdbc/MarcelsDataSource</jta-data-source>
    <properties>
        <property name="eclipselink.ddl-generation" value="create-tables"/>
    </properties>
</persistence-unit>
</persistence>

index.jsp: index.jsp:

<%@ page import="beans.BookServiceBean" %>
<%@ page import="beans.Book" %>
<html>
<body>
<%
    BookServiceBean bs = new BookServiceBean();
    Book b = new Book("Superman");
    bs.createOrUpdate(b);
%>
</body>
</html>

If I run the example I get a java.lang.NullPointerException in the createOrUpdate() method so the entityManager is obviously not injected correctly. 如果运行示例,则会在createOrUpdate()方法中收到java.lang.NullPointerException,因此显然不会正确注入entityManager。 I tried to find a remedy for days now and some help would be highly appreciated. 我试图寻找一种补救方法已经有好几天了,我们将不胜感激。

Thanks 谢谢

Marcel 马塞尔

You get a NullPointerException because you are instantiating your BookService with a new() - which is basically wrong - and nothing gets injected in the EJB. 之所以会得到NullPointerException是因为您正在使用new()实例化BookService ,这基本上是错误的,并且没有任何东西注入到EJB中。 EJB are component that are managed by the container and should be obtained either via injection or with a lookup. EJB是由容器管理的组件,应该通过注入或查找来获取。

Here, while the JSP spec allows any code to be run in a scriplet, calling an EJB from a JSP is actually not really encouraged and JSPs don't support injection. 在这里,尽管JSP规范允许在代码片段中运行任何代码,但实际上并不鼓励从JSP调用EJB,并且JSP不支持注入。 In other words, you'll have to use a lookup: 换句话说,您将必须使用查找:

<%@ page import="beans.BookService" %>
<%@ page import="beans.Book" %>
<html>
<body>
<%
    BookService bs = (BookService) new InitialContext().lookup("java:module/BookServiceBean")
    Book b = new Book("Superman");
    bs.createOrUpdate(b);
%>
</body>
</html>

But you should call your EJB from a Servlet or a JSF Managed Bean (and your EJB could be injected in such components). 但是您应该从Servlet或JSF Managed Bean调用EJB(并且EJB可以注入到此类组件中)。

If you need some samples, have a look at the Java EE Code Samples & Apps . 如果需要一些示例,请查看Java EE代码示例和应用程序

Update: See How do I access a Local EJB component from a POJO? 更新:请参阅如何从POJO访问本地EJB组件? in the EJB FAQ for more details on JNDI (especially the new portable global JNDI names defined by the EJB 3.1 specification ). EJB FAQ中的有关JNDI(尤其是EJB 3.1规范定义的新的可移植全局JNDI名称)的更多详细信息。

Try: 尝试:

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

You are instantiating the service bean directly, when you really need to be having the container inject it (via @EJB). 当您确实需要容器(通过@EJB)注入它时,您将直接实例化服务bean。 This isn't supported in a JSP, though, so you'll have to switch to a servlet as well. 但是,JSP不支持此功能,因此您也必须切换到servlet。

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

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