Java 使Hibernate EntityManager处于可运行状态

Java 使Hibernate EntityManager处于可运行状态,java,hibernate,Java,Hibernate,我有一个bean,我在其中创建了一个新线程,具有Runnable: @Component public class MyBean { private final Task task = new Task(); @PersistenceContext EntityManager em; @PostConstruct public void init() { task.setEntityManager(em); new T

我有一个bean,我在其中创建了一个新线程,具有Runnable:

@Component
public class MyBean {

    private final Task task = new Task();

    @PersistenceContext
    EntityManager em;

    @PostConstruct
    public void init() {
        task.setEntityManager(em);
        new Thread(task).start();
    }

    public static class Task implements Runnable {

        @Setter
        private EntityManager em;

        @Override
        public void run() {
            while (true) {
                // working with EntityManager
                Thing t = em.findById(...); // Fetching a Thing from repo
                t.getSomethingList(); // LazyInit exception
                wait();
            }
        }
    }
}
使用init方法,使用EntityManager实例创建新线程。当我尝试从存储库加载某些内容时,会话会立即关闭,并且获取任何延迟字段会导致
无法延迟初始化角色集合:something,没有会话或会话被关闭
来自Hibernate的异常

我尝试了所有@Transactional注释,但没有效果。我需要实现类似OpenEntityManagerView的功能,但不同的是,它不在视图中

谢谢

编辑1:

  • 根据评论-我尝试使用
    em.getTransaction().begin()但这使得我
    不允许在共享EntityManager上创建事务-使用Spring事务或EJB CMT

  • skirsch建议我应该在其他bean上调用事务方法。这就是我实际做的——完全按照你的建议。我想让事情变得更简单,但我没有意识到其中的区别,所以我直接在类
    任务中演示了这个问题。总而言之,我完全按照斯基尔什的建议,但问题依然存在


  • 由于Spring没有管理您的
    可运行
    ,因此注释它将不会产生预期效果。因此,您要么需要在
    Runnable
    中使用带注释(和Spring管理的)bean,要么需要手动处理txn管理

    使用Spring事务管理 您定义了某种服务

    @Service
    public class MyService {
        @PersistenceContext
        EntityManager em;
    
        @Transactional
        public void doSomething() {
            Thing t = em.findById(...);
            t.getSomethingList();
        }
    }
    
    然后,您的bean将如下所示:

    @Component
    public class MyBean {
    
        private final Task task = new Task();
    
        @Autowired
        MyService service;
    
        @PostConstruct
        public void init() {
            task.setService(service);
            new Thread(task).start();
        }
    
        public static class Task implements Runnable {
    
            @Setter
            private MyService service;
    
            @Override
            public void run() {
                while (true) {
                    service.doSomething();
                    wait();
                }
            }
        }
    }
    
    手动事务管理 如果您设置了JPA资源本地事务,请执行以下操作:

    // working with EntityManager
    em.getTransaction().begin()
    try {
        Thing t = em.findById(...);
        t.getSomethingList();
    } finally {
        em.getTransaction().rollback()
    }
    wait();
    

    那么,您似乎既没有设置Spring txn管理,也没有设置JPA资源本地事务。您是如何设置整个持久性堆栈的?