将实体管理器注入无状态Bean中的问题 [英] Problems in injecting entity manager into stateless bean

查看:69
本文介绍了将实体管理器注入无状态Bean中的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个EJB3-app,其中使用无状态bean.似乎EntityManager没有正确注入到我的bean中.

I am developing an EJB3-app, where I use stateless beans. It seems like the EntityManager is not injected properly into my bean.

这是无状态bean的代码:

Here is code for the stateless 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的实例时,出现以下异常:

When I try to create an instance of FirmEJB I get the following exception:

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);
}

推荐答案

您正在Java SE环境中使用Java EE功能. 那行不通.

You're using Java EE features in Java SE environment. That won't work.

负责依赖性注入的Java EE容器,因此PersisteneContextPersistenceUnit仅在Java EE容器环境(例如Glassfish或JBoss)中才有意义.

The Java EE container responsible for dependency injection, so the PersisteneContext and PersistenceUnit make any sense only in the Java EE container environment (like Glassfish or 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实例.在您的情况下,注释毫无意义.

you're defining dependency injection through annotations and at the same time you create the instances of EMF and EM by yourself. The annotations are meaningless in your case.

此外:

  • persistence.xml中,您要定义使用RESOURCE_LOCAL事务类型,同时要定义<jta-data-source>元素(这意味着您将使用JTA事务),
  • 我假设您正在使用EclipseLink,所以<exclude-unlisted-classes>false</exclude-unlisted-classes>可以正常工作.请注意,这不是便携式解决方案-为了确保在Java SE环境中您的实体对JPA提供者可见,您应该使用<class>元素定义它们.
  • in persistence.xml you're defining to use RESOURCE_LOCAL transaction type and at the same time you're defining <jta-data-source> element (which means that you'll be using JTA transactions),
  • I assume that you're using EclipseLink so the <exclude-unlisted-classes>false</exclude-unlisted-classes> is working. Beware that this is not a portable solution - in order to be sure that in Java SE environment your entities will be visible to the JPA provider, you should define them using <class> element.

最后但并非最不重要的一点是,如果您正在这样的Java SE环境中执行代码并且不启动任何嵌入式EJB容器,则不需要@Stateless,因为您的类没有任何EJB自然.注释为@Stateless@Stateful的POJO通过在EJB容器中执行来获得EJB性质.在这种情况下,它就像普通的Java类一样.

And last but not least, if you're executing your code in Java SE environment like this and don't start any Embedded EJB container than @Stateless is not needed because your class doesn't have any EJB nature. POJO annotated as a @Stateless or @Stateful gains EJB nature by being executed in EJB container. In this case, it acts like a plain Java class.

当心-即使您使用嵌入式EJB容器,显示的代码也将实例化EJB.您不能将new FirmEJB()与EJB一起使用.容器应负责为您提供EJB实例.
这就是抽象的全部要点-您依赖抽象而不是创作.

Beware - even if you'd use Embedded EJB container the code you've shown will not instantiate an EJB. You cannot use new FirmEJB() with EJBs. The container should be responsible for providing you an instance of the EJB.
That's the whole point of the abstraction - you depend upon abstraction rather than creation.

您可能会对OpenJPA JPA概念 OpenEJB文档.

You might be interested in further reading like OpenJPA JPA Concepts or OpenEJB Documentation.

这篇关于将实体管理器注入无状态Bean中的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆