簡體   English   中英

為什么 hibernate 持久性上下文在事務之外不可用?

[英]Why is the hibernate Persistence Context not available outside of a transaction?

Vlad 關於如何修復 MultipleBagsException 的示例將是我們的起點: 如何修復 MultipleBagsException - Vlad Mihalcea

在其中它執行 2 個后續 HQL 查詢以加載 2 個延遲加載的關系(包)。

當試圖在我們的項目中應用它時,我注意到它只有在 2 個查詢在一個事務中時才有效。 所以我們必須創建一個事務來讓它工作,然后很快回滾所說的事務。
例子:

utx.begin();
List<Post> posts = entityManager.createQuery("""
    select distinct p
    from Post p
    left join fetch p.comments
    where p.id between :minId and :maxId""", Post.class)
.setParameter("minId", 1L)
.setParameter("maxId", 50L)
.setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
.getResultList();
 
posts = entityManager.createQuery("""
    select distinct p
    from Post p
    left join fetch p.tags t
    where p in :posts""", Post.class)
.setParameter("posts", posts)
.setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
.getResultList();
utx.rollback();

作為參考,這是部署到 Wildfly 20 的 JavaEE 項目(不是 Spring)。持久化單元在 persistence.xml 中定義為

<persistence-unit name="some-p-unit-name">
    <jta-data-source>java:/jdbc/someDB</jta-data-source>
</persistence-unit>  

EntityManager 是這樣定義的:

    @PersistenceContext(type = PersistenceContextType.EXTENDED, unitName = "some-p-unit-name")
private EntityManager em;

@Produces
@RequestScoped
@SomeResource // this is an annotation to differentiate it from another entity manager that can also be injectable
public EntityManager getEm() {
    return em;
}

那么為什么我們需要啟動一個事務才能啟用 PersistenceContext,即使我們將它設置為使用 EXTENDED 上下文?

感謝@Smutje 引導我找到正確的答案。 在我們的案例中,解決方案是使用 @Stateful 注釋定義 EntityManager 的 class,根據文檔,PersistenceContext 僅適用於容器管理場景中的有狀態 EJB。

下面的示例代碼。 請注意有狀態注釋以及持久性上下文類型 = EXTENDED。

@Stateful
public class Resources {
    @PersistenceContext(type = PersistenceContextType.EXTENDED, unitName = "some-p-unit-name")
    private EntityManager em;

    @Produces
    @RequestScoped
    public EntityManager getEm() {
        return em;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM