JPA,EJB和JTA是一个独立的应用程序

时间:2014-02-07 13:42:09

标签: java-ee ejb jndi jta

我有我的j2ee应用程序,并且我设计了一个使用JPA在数据库中存储项目的EJB模块。在这个EJB包中,我有persistence.xml,它指的是通常由应用程序服务器提供的JTA数据源。

现在我必须构建另一个仅使用我的应用程序的EJB模块的应用程序。它是一个独立的应用程序,所以没有j2ee服务器。 我该怎么办?我需要一个EJB容器和一个JPA提供程序,我理解这一点,但我还需要在ejb jar中的persistence.xml中定义的jndi中提供数据源。我在我的ejb包中也使用了容器管理事务和依赖注入,我希望一切都像j2ee对应一样工作,而不需要修改ejb模块。

1 个答案:

答案 0 :(得分:1)

我使用独立应用程序中的JEE JPA模块进行测试,但想法是一样的。有一种方法EntityManagerFactory createEmf()可以创建EntityManagerFactory,如下所示:

public static EntityManagerFactory createEmf() {
    try {
        HashMap<String,String> cfg = new HashMap<String,String>();

        String connUrl = ...;
        String userName = ...;
        String password = ...;

        cfg.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        cfg.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");

        cfg.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
        cfg.put("hibernate.connection.username", userName);
        cfg.put("hibernate.connection.password", password);
        cfg.put("hibernate.connection.url", connUrl);
        // worked for Hibernate 4.0.1; doesn't work for 4.3:
        //cfg.put("javax.persistence.jtaDataSource", "");
        // works for 4.3:
        cfg.put("javax.persistence.jtaDataSource", null);
        cfg.put("hibernate.hbm2ddl.auto", "create");
        cfg.put("hibernate.show_sql", "true");
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("xxxxxPU",cfg);
        return emf;
    }
    catch(RuntimeException re) {
        throw re;
    }
    catch(Exception e) {
        throw new RuntimeException(e);
    }
}

核心是Persistence.createEntityManagerFactory(name,properties)方法。在persistence.xml中声明的属性覆盖补充值。

在实际实现中,我从proerties文件中读取了连接参数。所以不需要DataSource(希望只有一个连接,如果这是一个客户端应用程序,所以不需要池)。

然而,这种方式,你必须手动管理交易!解决方法是使用CDI或AOP拦截器将业务方法包装为事务。这需要一些努力,但可能会节省启动独立EJB容器的开销。