[英]Keeping Hibernate EntityManager within a Runnable
我有一個我在其中使用Runnable創建新線程的bean:
@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的實例創建新的線程。 當我嘗試從存儲庫中加載某些內容時,該會話會立即關閉,並且獲取任何惰性字段都會導致failed to lazily initialize a collection of role: Something, no session or session was closed
懶惰failed to lazily initialize a collection of role: Something, no session or session was closed
Hibernate failed to lazily initialize a collection of role: Something, no session or session was closed
。
我嘗試了所有@Transactional批注,但沒有任何效果。 我需要實現類似OpenEntityManagerInView的功能,但是區別在於它不在視圖之內。
謝謝
EDIT1:
根據評論-我嘗試使用em.getTransaction().begin();
但這讓我Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT
。
skirsch建議我應該在其他bean上調用Transactional方法。 那就是我實際上所做的-完全按照您的建議。 我想簡化事情,沒有意識到區別,所以我直接在Task
類中演示了該問題。 因此,總而言之,我完全按照skirsch的建議進行操作,但是問題仍然存在。
由於Spring不管理您的Runnable
,因此對其進行注釋將不會達到預期的效果。 因此,您需要在Runnable
使用帶注釋(且受Spring管理)的Bean,或者需要手動進行txn管理。
您定義某種服務
@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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.