使用時(shí)guice-persist,EntityManager是事務(wù)范圍的。如果我理解正確的話,這意味著EntityManager將為每筆交易創(chuàng)建一個(gè)新的。使用時(shí)guice-persist,建議使用JpaPersistModule,它提供了所有的綁定,并簡單地注入Provider<EntityManager>到某個(gè)類中,就像這樣:public class ProjectDAO {? private final Provider<EntityManager> entityManagerProvider;? @Inject? public ProjectDAO(Provider<EntityManager> entityManagerProvider) {? ? this.entityManagerProvider = entityManagerProvider;? }}?現(xiàn)在,我試過了,每個(gè)線程都有自己的EntityManager.?然而,它似乎并沒有被移除并重新設(shè)置,而是被重新用于后續(xù)事務(wù),即Hibernate的一級(jí)緩存沒有被清除。這是一個(gè)完整的示例,它從兩個(gè)不同的線程(順序地,而不是并行地)插入和刪除一些實(shí)體,這會(huì)導(dǎo)致一個(gè)線程具有陳舊的信息:項(xiàng)目(一個(gè)簡單的實(shí)體)? ?@NamedQueries({? ? ? ? @NamedQuery(name = "project.findAll", query = "from project"),? ? ? ? @NamedQuery(name = "project.deleteByProjectName", query = "delete from project p where p.name = :project_name")? ? }? ? )? ? @Entity(name = "project")? ? public class Project {? ? ? ? @Id? ? ? ? @GeneratedValue? ? ? ? private Long id;? ? ? ? @Column(name="name")? ? ? ? private String name;? ? ? ? // ... getters/setters? ? }項(xiàng)目DAO? ? public class ProjectDAO {? ? ? private final Provider<EntityManager> entityManagerProvider;? ? ? @Inject? ? ? public ProjectDAO(Provider<EntityManager> entityManagerProvider) {? ? ? ? this.entityManagerProvider = entityManagerProvider;? ? ? }? ? ? public void insert(Project project) {? ? ? ? entityManagerProvider.get().persist(project);? ? ? }? ? ? public List<Project> findAll() {? ? ? ? return entityManagerProvider.get()? ? ? ? ? ? .createNamedQuery("project.findAll", Project.class)? ? ? ? ? ? .getResultList();? ? ? }
1 回答

江戶川亂折騰
TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超5個(gè)贊
上面的代碼有兩個(gè)問題:
1)下面一行
System.out.println("TEST: " +"EntityManager: " + projectService.getEntityManager().hashCode());
被添加用于調(diào)試目的。ProjectService.getEntityManager()
但是,調(diào)用 的方法ProjectDAO.getEntityManager()
又調(diào)用entityManagerProvider.get()
,沒有用 注釋@Transactional
。這會(huì)導(dǎo)致EntityManager
每個(gè)線程設(shè)置一次并且永遠(yuǎn)不會(huì)取消設(shè)置,即使@Transactional
稍后調(diào)用 ProjectService 中具有注釋的其他方法也是如此。只需添加此注釋即可解決問題。
2)在一個(gè)線程中,名稱為“project1”的實(shí)體被刪除
//---- projectService.delete("project1"); //----
然而,在另一個(gè)線程中,驗(yàn)證了另一個(gè)實(shí)體的存在
// project3, which was deleted in Thread 2 is still visible in this EntityManager Project project = projectService.findById(3L); System.out.println("Project still exists " + project);
一開始就沒有刪除。實(shí)體被一個(gè)接一個(gè)地添加 - project1、project2、project3... 并分別為它們分配 ID 1、2、3...。所以代碼應(yīng)該是
// project1, which was deleted in Thread 2 is still visible in this EntityManager Project project = projectService.findById(1L); System.out.println("Project still exists " + project);
添加回答
舉報(bào)
0/150
提交
取消