You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JakartaEE容器管理EntityManager结合HSQLDB:如何编程式配置JTA数据源?

编程式声明JTA数据源适配容器管理EntityManager

在Jakarta EE环境中,完全可以通过编程式方式注册JTA数据源,不用依赖厂商特定的XML配置。以下是两种实用方案:

方案1:用Jakarta EE标准注解@DataSourceDefinition(推荐)

这是最简洁的方式,直接通过注解让容器自动注册数据源并绑定到JNDI。

操作步骤:

  1. 创建一个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 {
    // 无需编写代码,注解会触发数据源注册
}
  1. 更新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。

示例代码:

  1. 编写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);
        }
    }
}
  1. 在项目的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 11:55:20