在 Java SE 中拥有 CDI 和 JPA 的最简单方法是啥?
Posted
技术标签:
【中文标题】在 Java SE 中拥有 CDI 和 JPA 的最简单方法是啥?【英文标题】:What is the easiest way to have CDI and JPA in Java SE?在 Java SE 中拥有 CDI 和 JPA 的最简单方法是什么? 【发布时间】:2014-01-23 00:44:51 【问题描述】:我想在 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 ManagerEntityManagerFactory emf = Persistence.createEntityManagerFactory("mgr");
EntityManager em = emf.createEntityManager();
但没有注入那么方便。
如果有这方面的教程就好了。无论如何,感谢您的帮助!
【问题讨论】:
您使用的是什么 CDI 容器?什么版本?最常见的模式是在实例化 EMF 后为实体管理器使用生产者。 【参考方案1】:首先,EJB 是 Java EE 的一部分,因此您不能在 Java SE 中使用它们。但是,CDI 可以在 Java SE 环境中使用,我的示例将向您展示如何将它与 Weld 一起使用,但还有其他实现 - 请注意,CDI 只是规范,而 Weld 是该规范的实现之一。
要使用 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>
然后你需要在你的main方法中启动容器,所以做这样的事情
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 documentation on using CDI in Java SE。
【讨论】:
您的解决方案有效。你现在能告诉我,我是否必须在 EntityManager 和/或 EntityManagerFactory 上的某个地方打电话close()
?
最简单的是 disposer 方法,这将在 EntityManager 的范围到期后自动关闭 - 请参阅我的编辑。
为什么要使用@EntityManager 限定符?
对不起,根据文档,你似乎不需要限定符,试试看
docs.jboss.org/cdi/spec/1.1/…【参考方案2】:
Peter 的回答似乎有效,但 Maven 依赖项已过时(请参阅 this bug)
<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>
【讨论】:
以上是关于在 Java SE 中拥有 CDI 和 JPA 的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
CDI + JPA 多个 @OneToMany - LAZY/EAGER - LazyInitializationException 或无法实例化多个包