我正在开发一个EJB3-app,我使用无状态bean。似乎EntityManager
没有正确地注入我的bean。
以下是无状态bean的代码:
@Stateless
@LocalBean
public class FirmEJB {
@PersistenceContext(unitName = "Fr14_07_Nezdolij_lab3PU")
private EntityManager em;
@PersistenceUnit(unitName="Fr14_07_Nezdolij_lab3PU")
private EntityManagerFactory emf;
public FirmEJB() {
emf = Persistence.createEntityManagerFactory("Fr14_07_Nezdolij_lab3PU");
em = emf.createEntityManager();
}
public EntityManager getEm() {
return em;
}
public void setEm(EntityManager em) {
this.em = em;
}
public Employee createEmployee(Employee e){
em.persist(e);
return e;
}
public Project createProject(Project p){
em.persist(p);
return p;
}
public Customer createProject(Customer c){
em.persist(c);
return c;
}
public Department createProject(Department d){
em.persist(d);
return d;
}
public ProjectManager createProjectManager(ProjectManager prjman){
em.persist(prjman);
return prjman;
}
}
当我尝试创建FirmEJB I
的实例时,会遇到以下异常:
Exception in thread "main" java.lang.NullPointerException
at sttls.FirmEJB.createEmployee(FirmEJB.java:42)
at entity.Main.main(Main.java:33)
的persistence.xml :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="Fr14_07_Nezdolij_lab3PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/fir</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.jdbc.url" value="jdbc:derby://localhost:1527/firmDB;create=true"/>
<property name="eclipselink.jdbc.user" value="admin"/>
<property name="eclipselink.jdbc.password" value="admin"/>
</properties>
</persistence-unit>
</persistence>
客户代码:
public static void main(String[] args) throws ClassNotFoundException, Exception {
Employee emp1 = new Employee("Alan", "Smith");
FirmEJB firmejb = new FirmEJB();
firmejb.createEmployee(emp1);
}
答案 0 :(得分:2)
您正在Java SE环境中使用Java EE功能。 那不行。
负责依赖注入的Java EE容器,因此PersisteneContext
和PersistenceUnit
仅在Java EE容器环境中有意义(如Glassfish或JBoss)。
如果你定义这样的东西:
@PersistenceContext(unitName = "Fr14_07_Nezdolij_lab3PU")
private EntityManager em;
@PersistenceUnit(unitName="Fr14_07_Nezdolij_lab3PU")
private EntityManagerFactory emf;
public FirmEJB() {
emf = Persistence.createEntityManagerFactory("Fr14_07_Nezdolij_lab3PU");
em = emf.createEntityManager();
}
您通过注释定义依赖注入,同时自己创建EMF和EM实例。在您的情况下,注释无意义。
此外:
persistence.xml
中您定义使用RESOURCE_LOCAL
交易类型,同时您定义<jta-data-source>
元素(这意味着您将使用JTA交易), <exclude-unlisted-classes>false</exclude-unlisted-classes>
正在运行。请注意,这不是一个可移植的解决方案 - 为了确保在Java SE环境中您的实体对JPA提供程序可见,您应该使用<class>
元素定义它们。最后但并非最不重要的是,如果您在Java SE环境中执行代码并且不需要启动任何嵌入式EJB容器而不需要@Stateless
,因为您的类没有任何EJB性质。通过在EJB容器中执行,POJO注释为@Stateless
或@Stateful
获得EJB性质。在这种情况下,它就像一个普通的Java类。
注意 - 即使您使用嵌入式EJB容器,您显示的代码不实例化EJB。您不能将new FirmEJB()
与EJB一起使用。容器应该负责为您提供EJB的实例
这就是抽象的全部要点 - 你依赖于抽象而不是创造。
您可能有兴趣进一步阅读OpenJPA JPA Concepts或OpenEJB Documentation。
答案 1 :(得分:0)
你需要改变transaction-type="RESOURCE_LOCAL" to transaction-type="JTA"