java Glassfish JPA:注入 EntityManager 的问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2359139/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Glassfish JPA: Problems injecting EntityManager
提问by Marcel Menz
I am new to Java EE. I tried to get some first examples running (JPA). I am using Glassfish v3. The trouble is that I don't get the App Server injecting the EntityManager. Hear is one example http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_forwhich I extended with a JSP client.
我是 Java EE 的新手。我试图让一些第一个例子运行(JPA)。我正在使用 Glassfish v3。问题是我没有让应用服务器注入 EntityManager。听到一个例子http://www.adam-bien.com/roller/abien/entry/ejb_3_persistence_jpa_for,我用一个 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:
图书服务接口:
package beans;
import javax.ejb.Local;
@Local
public interface BookService {
Book createOrUpdate(Book book);
void remove(Book book);
Book find(Object id);
}
BookServiceBean:
图书服务Bean:
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:
持久性.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:
索引.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. I tried to find a remedy for days now and some help would be highly appreciated.
如果我运行这个例子,我会在 createOrUpdate() 方法中得到一个 java.lang.NullPointerException ,所以 entityManager 显然没有正确注入。几天来我一直试图找到一种补救措施,我们将不胜感激。
Thanks
谢谢
Marcel
马塞尔
回答by Pascal Thivent
You get a NullPointerExceptionbecause you are instantiating your BookServicewith a new()- which is basically wrong - and nothing gets injected in the EJB. EJB are component that are managed by the container and should be obtained either via injection or with a lookup.
你得到 a 是NullPointerException因为你BookService用 a实例化你的new()- 这基本上是错误的 - 并且没有任何东西被注入到 EJB 中。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. In other words, you'll have to use a lookup:
在这里,虽然 JSP 规范允许在脚本中运行任何代码,但实际上并不鼓励从 JSP 调用 EJB,并且 JSP 不支持注入。换句话说,您必须使用查找:
<%@ 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?in the EJB FAQ for more details on JNDI (especially the new portable global JNDI names defined by the EJB 3.1 specification).
更新:请参阅如何从 POJO 访问本地 EJB 组件?有关 JNDI(尤其是由 EJB 3.1 规范定义的新的可移植全局 JNDI 名称)的更多详细信息,请参阅 EJB 常见问题解答。
回答by Enno Shioji
Try:
尝试:
@PersistenceContext(unitName = "sample")
private EntityManager em;
回答by jsight
You are instantiating the service bean directly, when you really need to be having the container inject it (via @EJB). This isn't supported in a JSP, though, so you'll have to switch to a servlet as well.
当您确实需要让容器注入它时(通过@EJB),您将直接实例化服务 bean。但是,这在 JSP 中不受支持,因此您也必须切换到 servlet。

