JakartaEE容器管理EntityManager结合HSQLDB:如何编程式配置JTA数据源?
编程式声明JTA数据源适配容器管理EntityManager
在Jakarta EE环境中,完全可以通过编程式方式注册JTA数据源,不用依赖厂商特定的XML配置。以下是两种实用方案:
方案1:用Jakarta EE标准注解@DataSourceDefinition(推荐)
这是最简洁的方式,直接通过注解让容器自动注册数据源并绑定到JNDI。
操作步骤:
- 创建一个CDI配置类,添加
@DataSourceDefinition注解:
import jakarta.annotation.sql.DataSourceDefinition; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @DataSourceDefinition( name = "java:app/jdbc/testDB", // JNDI名称,要和persistence.xml里的配置对应 className = "org.hsqldb.jdbc.JDBCDataSource", // HSQLDB的数据源实现类 url = "jdbc:hsqldb:mem:testdb;DB_CLOSE_DELAY=-1", user = "sa", password = "", transactional = true // 明确标记为JTA数据源 ) public class DataSourceConfig { // 无需编写代码,注解会触发数据源注册 }
- 更新
persistence.xml的jta-data-source值,匹配上面的JNDI名称:
<persistence-unit name="test" transaction-type="JTA"> <jta-data-source>java:app/jdbc/testDB</jta-data-source> <class>demo.Jakarta.user.UserEntity</class> <properties> <!-- 可以移除JDBC相关配置项,因为数据源已经通过注解配置完毕 --> <property name="jakarta.persistence.schema-generation.database.action" value="create"/> </properties> </persistence-unit>
方案2:CDI扩展手动注册数据源(适配复杂场景)
如果需要自定义数据源的初始化逻辑,可以通过CDI扩展在应用启动时手动绑定数据源到JNDI。
示例代码:
- 编写CDI扩展类:
import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import org.hsqldb.jdbc.JDBCDataSource; public class DataSourceExtension implements Extension { public void registerDataSource(@Observes BeforeBeanDiscovery event) { JDBCDataSource dataSource = new JDBCDataSource(); dataSource.setUrl("jdbc:hsqldb:mem:testdb;DB_CLOSE_DELAY=-1"); dataSource.setUser("sa"); dataSource.setPassword(""); try { Context ctx = new InitialContext(); // 将数据源绑定到指定JNDI名称 ctx.bind("java:app/jdbc/testDB", dataSource); } catch (NamingException e) { throw new RuntimeException("注册JTA数据源失败", e); } } }
- 在项目的
META-INF/services/jakarta.enterprise.inject.spi.Extension文件中添加扩展类的全限定名:
com.yourpackage.DataSourceExtension
后续使用说明
配置完成后,就可以直接在仓储类中使用容器管理的EntityManager了:
import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import jakarta.transaction.Transactional; @Transactional public class UserRepository { @PersistenceContext(unitName = "test") private EntityManager em; // 业务方法无需手动处理事务 public void save(UserEntity user) { em.persist(user); } }
内容的提问来源于stack exchange,提问作者Turtle
相关产品推荐
相关产品推荐

