What is the easiest way to have CDI and JPA in Java SE?

感情迁移 提交于 2020-01-09 09:38:07

问题


I would like to have in 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();
    }
}

What I have to do to achieve that? I'm using postgres database, and maven in my project.

I was already reading something about Weld (but it looks only like CDI). I don't know how to add to Weld possibilty to inject Entity Manager. I know that I can obtain Entity Manager with

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

but it's not so convenient as injecting.

It would be great if there is any tutorial about that. Anyway, thanks for any help!


回答1:


First of all, EJBs are part of Java EE, therefore you cannot use them in Java SE. However, CDI can be used in Java SE environment, my example will show you how to use it with Weld but there are also other implementations - note that CDI is just specification and Weld is one of the implementations of that specification.

In order to use Weld, you need to either put weld-se-x.x.x-Final.jar on the classpath or specify its dependency in Maven like

<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>

Then you need to startup the container in your main method, so do something like this

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

This should get you started, then you can use CDI Producers to make your EntityManager injectable

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

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

See also Weld documentation on using CDI in Java SE.




回答2:


Peter's answer seems to work, but the Maven dependencies are outdated (see 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>


来源:https://stackoverflow.com/questions/20935977/what-is-the-easiest-way-to-have-cdi-and-jpa-in-java-se

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!