jpa - 具有应用程序管理的持久性上下文的Spring Boot

标签 jpa spring-boot transactions eclipselink

我正在尝试从EJB3 + JTA + JPA(EclipseLink)迁移应用程序。当前,由于在设计时数据库数量未知,因此该应用程序利用了应用程序管理的持久上下文。

应用程序管理的持久上下文允许我们控制如何创建EntityManager(例如,提供不同的数据源JNDI,以便在运行时为特定的DB创建适当的EntityManager)。

例如。

地图属性= new HashMap();

properties.put(PersistenceUnitProperties.TRANSACTION_TYPE,“ JTA”);

//数据源JNDI是通过配置完成的,无需事先了解数据库的数量
//当前,DB JNDI存储在外部文件中
//数据源由操作团队设置
properties.put(PersistenceUnitProperties.JTA_DATASOURCE,“数据源-jndi”);

properties.put(PersistenceUnitProperties.CACHE_SHARED_DEFAULT,“ false”);
properties.put(PersistenceUnitProperties.SESSION_NAME,“ xxx”);

//创建适当的EntityManager以连接到运行时决定的数据库

EntityManager em = Persistence.createEntityManagerFactory(“ PU1”,properties).createEntityManager();

//查询或更新数据库
持久性(实体);
em.createQuery(...)。executeUpdate();



当部署在具有适当TransactionAttribute(例如TransactionAttributeType.REQUIRED)的EJB容器(例如WebLogic)中时,该容器将负责事务的开始/结束/回滚。

现在,我正在尝试将此应用程序迁移到Spring Boot。
我遇到的问题是,即使我用@Transactional(propagation = Propagation.REQUIRED)注释了该方法,也没有任何事务开始。

Spring应用程序打包为可执行JAR文件,并与嵌入的Tomcat一起运行。

当我尝试执行这些更新API时,例如EntityManager.persist(..),EclipseLink总是抱怨:


javax.persistence.TransactionRequiredException:'当前没有事务处于活动状态'


下面的示例代码:


//用于数据持久性
@服务
类DynamicServiceImpl实现了DynamicService {

//尝试开始交易
@Transactional(传播=传播。必填)
公共无效saveData(DbJndi,EntityA){

//此返回false表示没有事务开始
TransactionSynchronizationManager.isActualTransactionActive();

//根据输入的DbJndi创建一个EntityManager以动态地
//确定要保存数据的数据库
EntityManager em = createEm(DbJndi);

//保存数据
em.persist(EntityA);
}
}

//服务周到
@RestController
RestController类{

@Autowired
DynamicService服务;

@RequestMapping(value =“ / saveRecord”,方法= RequestMethod.POST)
公共@ResponseBody字符串saveRecord(){
//保存数据
service.saveData(...)
}
}

//启动应用
@SpringBootApplication
类TestApp {

公共静态void main(String [] args){
SpringApplication.run(TestApp.class,args);
}
}

persistence.xml
-------------------------------------------



<属性>

<!-评论春天处理交易??? ->
<!-属性名称=“ eclipselink.target-server” value =“ WebLogic_10” /->




-------------------------------------------

application.properties(仅3行配置)
-------------------------------------------
spring.jta.enabled =真
spring.jta.log-dir = spring-test#交易日志目录。
spring.jta.transaction-manager-id =弹簧测试
-------------------------------------------



我的使用模式不符合大多数典型用例(例如,已知的数据库数量-Spring + JPA + multiple persistence units: Injecting EntityManager)。

有人可以给我建议如何解决这个问题吗?

有没有人遇到过这种情况,即在设计时不知道数据库?

谢谢。

最佳答案

您自己已经回答了很多问题:“当部署在具有适当TransactionAttribute(例如TransactionAttributeType.REQUIRED)的EJB容器(例如WebLogic)中时,该容器将负责事务的开始/结束/回滚”。

WebLogic符合Java Enterprise Edition规范,这也许是它以前能工作的原因,但是现在您正在使用Tomcat(以嵌入式模式),而现在不行。
因此,您根本无法做您想做的事情。
您的persistence.xml文件中的以下语句:

<persistence-unit name="PU1" transaction-type="JTA">

需要一个企业服务器(WebLogic,Glassfish,JBoss等)

使用Tomcat,您只能执行以下操作:

<persistence-unit name="PU1" transaction-type="RESOURCE_LOCAL">

您需要自己处理交易:

myEntityManager.getTransaction.begin();
... //Do your transaction stuff
myEntityManager.getTransaction().commit();

关于jpa - 具有应用程序管理的持久性上下文的Spring Boot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45034556/

相关文章:

java - @GenerateValue 注解中生成器属性的意义

JPA 事务回滚失败并调用无状态 bean

java - @ManyToMany 不是所有从数据库中获取的值

java - hbm2ddl 模式导出不会导致使用 Spring Security 创建实体

python - 在 Django 中开始的事务

c# - IsolationLevel.RepeatableRead 以防止重复

java - JPA中的继承策略

spring - 有没有办法在 Spring 属性值中转义 SpEL 字符 "#{"

java - Spring security - 更改/登录默认路径

java - ejb 是否在连接上提交?