2011-10-02 20 views
0

我試圖在JBoss7中運行由maven archetype groupId生成的簡單JEE6應用程序:org.fluttercode.knappsack,artifactID:jee6-sandbox-archetype。 (通過這個turial去了,對不起,德語)通過@ConversationScoped方法提供EntityManager

但是,調用的歡迎JSF的時候,我得到了以下錯誤消息:

org.jboss.weld.exceptions.IllegalProductException: WELD-000053 Producers 
    cannot declare passivating scope and return a non-serializable class: 
    [method] @Produces @DataRepository @ConversationScoped 
    public org.rap.jee6project.bean.DataRepositoryProducer.getEntityManager() 
org.jboss.weld.bean.AbstractProducerBean.checkReturnValue(AbstractProducerBean.java:264) 
org.jboss.weld.bean.AbstractProducerBean.create(AbstractProducerBean.java:362) 
org.jboss.weld.context.AbstractContext.get(AbstractContext.java:122) 

事實上,它應該返回一個EntityManager的DataRepositoyProducer類實例,被定義爲如下注釋:

@Stateless 
public class DataRepositoryProducer { 


private EntityManager entityManager; 

@Produces @DataRepository @ConversationScoped 
public EntityManager getEntityManager() { 
    return entityManager; 
} 

@PersistenceContext 
public void setEntityManager(EntityManager entityManager) { 
    this.entityManager = entityManager; 
} 

} 

如果我使用@RequestScoped,應用程序按照承諾運行。我想知道爲什麼其他人通過本教程沒有遇到這個問題?以及如何正確地修復它(使用@RequestScoped意味着豆爲每個用戶請求重新創建,對吧?,我預計效率不高)

官方JEE6教程說:「使用會話,應用程序或會話範圍必須是可序列化的,但使用請求範圍的bean不必是可序列化的「」。然而,這似乎並不是問題,因爲服務器不是關於不可序列化的bean,而是生產者bean的產品。

+0

使得DataRepositoryProducer一個狀態bean和註釋全班同學爲@ConversationScoped時,它的工作原理。不知道我是否應該對這個解決方案感到滿意。 也許,生產者的概念並不是容器提供的對象(如EntityManager)的最佳實踐。 – rainer198

回答

1

應該..

@Stateful 
@ConversationScoped 
public class ProducerCreator implements Serializable{ 
    @PersistenceConText 
    private EntityManager entityManager; 
    .... 
} 

,如果你想使用相同的實體上下文中每個會話的應該是

@PersistenceContex(type = PersistenceContextType.EXTENDED) 

最後,如果你想擁有的服務層,應創建有狀態並注入對話bean

+0

謝謝,這就像我在我的評論中提到的解決方案。我想知道是否應該使用生產者來獲取EntityManager實例,因爲要記住有狀態的EJB會影響可伸縮性。爲什麼不以JEE5方式注入它,直接使用@PersistenceContext而不是使用專用的生產者bean。 – rainer198

+0

默認情況下EntityManager是事務範圍。我認爲,將entityManager更改爲對話作用域是沒有意義的。讓我們看看Seam持久化模塊http://www.seamframework.org/Seam3/PersistenceModule,如果你真的想製作EntityManager。 – Udonake

1

我在jboss7上運行演示程序時遇到了同樣的問題。

只需在getEntityManager()中刪除@ConversationScoped就可以讓我部署它。

即使有一些缺陷:

javax.servlet.ServletException: javax.faces.component.StateHolderSaver cannot be cast to [Ljava.lang.Object;  
javax.faces.webapp.FacesServlet.service(FacesServlet.java:606) 
org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) 

我不知道到底,如果是相關的,但我猜是這樣。

1

記住:EntityManager不是序列化的,所以它不能被儲存在ConversationScope

相關問題