【问题标题】:PersistenceContext in multithreading [duplicate]多线程中的 PersistenceContext [重复]
【发布时间】:2023-03-19 11:13:01
【问题描述】:

由于某种原因,EntityManager 没有被注入到我想在后台继续运行的单独线程中。其他类可以毫无问题地访问实体管理器,但它们不是在单独的线程中运行。

我在这里做错了什么?

@Stateful
public class DatabaseManager extends Thread{
    @PersistenceContext(unitName="imas-unit")
    private EntityManager em;


    private int timeBetweenRefresh;

    public void run(){
        loadProperties();
        retrieveDBContent();
        long timerTicks = System.currentTimeMillis();
        while(running){
            if(System.currentTimeMillis() > timerTicks + timeBetweenRefresh){
                timerTicks = System.currentTimeMillis();
                deleteAllRecords();
                retrieveDBContent();
            }
            Thread.sleep(1000);
        }
    }

    private void deleteAllRecords(){
        //Deletes all the records
    }

    private void loadProperties(){
        //Loads properties for methods
    }

    private void retrieveDBContent(){
        List<Cel> celList = methodThatGetsCells();
        System.out.println("Saving to database");
        for(Cel cell : celList){
            try{
                em.persist(cell); //Null pointer here
                em.flush();
            }
                catch(Exception e){
                    System.out.println(e.getMessage());
                    e.printStackTrace();
                }
            }
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            System.out.println("Retrieval failed. Please check error log for further information.");
            e1.printStackTrace();
        }
    }

}

如果需要,我可以发布更多信息。

【问题讨论】:

    标签: multithreading jpa jakarta-ee persistence entitymanager


    【解决方案1】:

    我觉得你的想法有点不对。当容器认为它已经完成时,它会取出你的 Stateless bean - 它不知道你从一个线程中分离出来。

    我会考虑使用@Schedule 注释,也许还有@Singleton。看起来您正在定期进行一些数据库维护,并且您可能不希望多个 bean 这样做。所以更像是:

    @Singleton
    public class DatabaseManager {
        @PersistenceContext(unitName="imas-unit")
        private EntityManager em;
    
        ...
    
        @Schedule(minute = "*", persistent = false)
        private void yourMaintenanceMethod() {
        ...
    

    在本例中,方法“yourMaintenanceMethod”将每分钟运行一次。您可以输入一个 seconds 字段来运行,例如,每 15 秒或您需要的任何时间。

    我过去曾成功地将这种模式用于类似类型的事情 - 它基本上让容器执行线程并最终简化您的代码。

    【讨论】:

    • 不知道。好吧,这让事情变得容易了 10 倍。
    猜你喜欢
    • 2012-06-19
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    • 2011-04-13
    • 2013-02-02
    • 1970-01-01
    相关资源
    最近更新 更多