Какой самый простой способ иметь CDI и JPA в Java SE?

Я хотел бы иметь в Java SE

@Stateless
public class CarDAO {
    @Inject
    private EntityManager em;

    public Car findById(Long id) {
        return em.find(Car.class, id);
    }
}

@Singleton
public class Application {
    @Inject
    private CarDAO carDAO;

    public void run() {
        Car car = carDAO.findById(44);
        System.out.println(car);
    }
}

public class EntryPoint {
    public static void main(String[] args) {
        Application application = // missing code
        application.run();
    }
}

Что я должен сделать, чтобы достичь этого? Я использую базу данных postgres и maven в своем проекте.

Я уже читал что-то о Weld (но это выглядит только как CDI). Я не знаю, как добавить в Weld возможность внедрять Entity Manager. Я знаю, что могу получить Entity Manager с

EntityManagerFactory emf = Persistence.createEntityManagerFactory("mgr");
EntityManager em = emf.createEntityManager();

но это не так удобно, как инъекция.

Было бы замечательно, если бы было какое-либо руководство по этому поводу. В любом случае, спасибо за любую помощь!

2 ответа

Решение

Прежде всего, EJB-компоненты являются частью Java EE, поэтому их нельзя использовать в Java SE. Тем не менее, CDI можно использовать в среде Java SE, мой пример покажет вам, как использовать его с Weld, но есть и другие реализации - обратите внимание, что CDI - это просто спецификация, а Weld - одна из реализаций этой спецификации.

Для того, чтобы использовать сварку, нужно либо поставить weld-se-x.x.x-Final.jar на пути к классам или указать его зависимость в Maven, как

<dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se</artifactId>
    <version><!-- See https://mvnrepository.com/artifact/org.jboss.weld.se/weld-se for current version --></version>
</dependency>

Затем вам нужно запустить контейнер в вашем основном методе, так что сделайте что-то вроде этого

public static void main(String[] args) throws IOException {
    Weld weld = new Weld();
    WeldContainer container = weld.initialize();
    Application application = container.instance().select(Application.class).get();
    application.run();
    weld.shutdown();
}

Это должно помочь вам начать, тогда вы можете использовать CDI Producers для EntityManager инъецируемый

@Produces
@RequestScoped
public EntityManager createEntityManager() {
   return Persistence.createEntityManagerFactory("mgr").createEntityManager();
}

public void closeEM(@Disposes EntityManager manager) {
   manager.close();
}

См. Также документацию Weld по использованию CDI в Java SE.

Кажется, что ответ Питера работает, но зависимости Maven устарели (см. Эту ошибку)

<dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se-core</artifactId>
    <version>2.3.1.Final</version>
</dependency>
<dependency>
    <groupId>org.jboss.weld</groupId>
    <artifactId>weld-core</artifactId>
    <version>2.3.1.Final</version>
</dependency>
<dependency>
    <groupId>org.jboss</groupId>
    <artifactId>jandex</artifactId>
    <version>1.2.2.Final</version>
</dependency>
Другие вопросы по тегам