TransactionRequiredException: нет EntityManager с фактической транзакцией, доступной для текущего потока - не может надежно обработать вызов 'слияния' - PullRequest
0 голосов
/ 06 февраля 2020

У нас есть несколько старых весенних приложений, где у нас есть небольшие аннотации весенней загрузки. У меня есть сценарий, в котором я хочу выполнить слияние с использованием EntityManager, но это вызывает «javax.persistence.TransactionRequiredException: нет EntityManager с реальной транзакцией, доступной для текущего потока - не может надежно обработать исключение« вызов слияния »вызова. Я пробовал решения, доступные в других статьях, такие как использование аннотаций javax.persistent @Trasactional на уровне метода upload (), но ничего не получалось. Это классы, которые я использую -

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;
}

Класс реализации ConfigLoader, в котором используется слияние из entityManager-

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); 
        }
    }
}

И, наконец, основной класс, в который я вызываю метод upload () реализации ConfigLoader -

public class ConfigThread implements Runnable {

    @Override
    public void run() {

        ConfigUploader configLoader = new MyConfigLoader(id,path);
        configLoader.upload(); // calling upload() method here

    }
}

1 Ответ

0 голосов
/ 07 февраля 2020

К сожалению, ваш класс не является пружинным компонентом, поэтому @Transactional здесь нельзя использовать. Вы можете попробовать что-то вроде этого:

EntityManager entityManager = ApplicationContextProvider.getApplicationContext().getBean(EntityManager.class);
entityManager.getTransaction().begin();
entityManager.merge(...);
entityManager.getTransaction().commit();
...