java 为什么不注入 EntityManager?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3862237/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:44:21  来源:igfitidea点击:

Why EntityManager is not injected?

javajpa

提问by yegor256

This is the class I'm trying to test:

这是我要测试的课程:

@Stateless
public class Finder {
  @PersistenceContext(unitName = "abc")
  EntityManager em;
  public String read(int i) {
    return this.em.find(Employee.class, i).getName();
  }
}

This is the unit test:

这是单元测试:

public class FinderTest {
  @Test public void testReadingWorks() {
    Finder f = new Finder();
    String name = f.find(1);
    assert(name.length() > 0);
  }
}

The problem is that EntityManager is not injected, and is NULLduring testing. What am I doing wrong?

问题是 EntityManager 没有注入,并且NULL在测试期间。我究竟做错了什么?

ps. Actually, I don't understand whoexactly is going to inject EntityManager. The unit test is started by JUnit, outside of any container... Maybe I have to inject emmanually in the test?

附:实际上,我不明白到底是谁要注入 EntityManager。单元测试由 JUnit 在任何容器之外启动......也许我必须em在测试中手动注入?

回答by J?rn Horstmann

Injection of EntityManagers only works in managed beans, since you are creating the Finder with newno container is involved. You could eithere create the EntityManager yourself using the EntityManagerFactory or use a embeddable Container like OpenEJB in your unit tests.

EntityManagers 的注入仅适用于托管 bean,因为您正在创建new不涉及容器的 Finder 。您可以使用 EntityManagerFactory 自己创建 EntityManager,也可以在单元测试中使用像OpenEJB这样的可嵌入容器。

回答by Pascal Thivent

Actually, I don't understand who exactly is going to inject EntityManager. The unit test is started by JUnit, outside of any container... Maybe I have to inject em manually in the test?

实际上,我不明白到底是谁要注入 EntityManager。单元测试由 JUnit 在任何容器之外启动......也许我必须在测试中手动注入 em?

Since your test is running out container, nobody is going to inject anything, you'll have to do it manually. This is IMHO not really a bad thing, and not hard.

由于您的测试正在耗尽容器,因此没有人会注入任何内容,您必须手动进行。恕我直言,这并不是一件坏事,也不难。

Out container

出柜

Here is a base class that you could extend to get an EntityManager:

这是一个基类,您可以扩展它以获得一个EntityManager

public abstract class JpaBaseRolledBackTestCase {
    protected static EntityManagerFactory emf;
    protected EntityManager em;

    @BeforeClass
    public static void createEntityManagerFactory() {
        emf = Persistence.createEntityManagerFactory("PetstorePu");
    }

    @AfterClass
    public static void closeEntityManagerFactory() {
        emf.close();
    }

    @Before
    public void beginTransaction() {
        em = emf.createEntityManager();
        em.getTransaction().begin();
    }

    @After
    public void rollbackTransaction() {

        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        if (em.isOpen()) {
            em.close();
        }
    }

}

In container using the EJBContainer API

在容器中使用 EJBContainer API

Another option would be to run your test in container, using the EJB 3.1 EJBContainerAPI to start an embedded container. See Arun's TOTD #128: EJBContainer.createEJBContainer: Embedded EJB using GlassFish v3(you'll need a bit more work to setup the datasource).

另一种选择是在容器中运行您的测试,使用 EJB 3.1 EJBContainerAPI 启动嵌入式容器。请参阅 Arun 的TOTD #128:EJBContainer.createEJBContainer:使用 GlassFish v3 的嵌入式 EJB(您需要做更多的工作来设置数据源)。

In container using Arquillian

在容器中使用 Arquillian

Or you could use Arquillian. Have a look at The perfect recipe for testing JPA 2: revisitedfor some ideas. I tested this approach this morning and find it VERY interesting for realintegration tests (but in container tests are typically slower and I won't use them for everything - but I'm starting to love Arquillian).

或者你可以使用Arquillian。看看测试 JPA 2 的完美方法:重新审视一些想法。我今天早上测试了这种方法,发现它对于真正的集成测试非常有趣(但在容器测试中通常较慢,我不会将它们用于所有事情 - 但我开始喜欢 Arquillian)。