spring - TransactionRequiredException:没有可用于当前线程的具有实际事务的 EntityManager - 无法可靠地处理“合并”调用
问题描述
我们有一些旧的 spring 应用程序,其中我们有一些 spring-boot 注释。我有一个场景,我想使用 EntityManager 执行合并,但这会引发“javax.persistence.TransactionRequiredException:没有 EntityManager 与当前线程的实际事务可用 - 无法可靠地处理‘合并’调用”异常。我已经尝试过其他帖子中可用的解决方案,例如在 upload() 方法级别上使用 javax.persistent @Trasactional 注释,但没有任何效果。这些是我正在使用的类 -
ApplicationContextProvider.java
@Service
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public static ApplicationContext getApplicationContext() {
return context;
}
@Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
context = ac;
}
}
MyConfigType.java
@Entity
@Table(name = "config_loaded_table")
public class MyConfigType {
@Id
private int id;
@Column(name = "file_name")
private String fileName;
// getters and setters
}
ConfigUploader.java(抽象类)——
public abstract class ConfigUploader {
public abstract String upload() throws Exception;
}
我正在使用来自 entityManager 的合并的 ConfigLoader 实现类-
public class MyConfigLoader extends ConfigUploader {
private int id;
private String path;
public MyConfigLoader(int id, String path) {
this.id= id;
this.path=path;
}
@Override
public String upload() throws Exception {
try {
MyConfigType myConfigType = new MyConfigType();
myConfigType.setFileName("employee.config");
// at this line I am getting exception.
int id = ApplicationContextProvider.getApplicationContext().getBean(EntityManager.class).merge(myConfigType).getId();
myConfigType.setId(id);
}catch (Exception e) {
// getting javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'merge' call
log.error(e);
}
}
}
最后,我调用 ConfigLoader 实现的 upload() 方法的主类 -
public class ConfigThread implements Runnable {
@Override
public void run() {
ConfigUploader configLoader = new MyConfigLoader(id,path);
configLoader.upload(); // calling upload() method here
}
}
解决方案
不幸的是,你的类不是spring组件,所以这里不能使用@Transactional。你可以尝试这样的事情:
EntityManager entityManager = ApplicationContextProvider.getApplicationContext().getBean(EntityManager.class);
entityManager.getTransaction().begin();
entityManager.merge(...);
entityManager.getTransaction().commit();
推荐阅读
- android - 使用 SHA1withRSA 算法进行签名验证的问题
- flutter - 使用不包含 Navigator 的上下文请求的 Navigator 操作的解决方案
- python - 使用 Facebook Graph API 进行私人回复
- rust - 是否可以即时应用货物修复
- html - 为什么顺风中的响应式网格不在物理设备上工作,而是在响应式设计模式下工作?
- angular - 设置角度 ngrx 时出错,动作参数不兼容
- android - 无法在 Android 中使用 EXIF 从图像媒体中提取位置(纬度、经度)坐标
- r - 向贝叶斯变化点图添加次要刻度线
- jquery - 添加每个按钮的 DOM 数据属性
- java - 发出ajax请求时刷新Wicket页面