Providing EntityManager by an @ConversationScoped method
I tried to run the simple JEE6 application generated by maven archetype groupId: org.fluttercode.knappsack , artifactID: jee6-sandbox-archetype in JBoss7. (went through this turial, sorry, in German)
However, when calling the welcome JSF, I get the following error message:
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)
Indeed, the DataRepositoyProducer class which is supposed to return an EntityMana开发者_Go百科ger instance, is defined an annotated as follws:
@Stateless
public class DataRepositoryProducer {
private EntityManager entityManager;
@Produces @DataRepository @ConversationScoped
public EntityManager getEntityManager() {
return entityManager;
}
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}
If I use @RequestScoped, the application runs as promised. I wonder why other people who went through this tutorial didn't experience this problem? And how to fix it properly (using @RequestScoped means that the bean is recreated for each user request, right?, which I expect to be not very efficient)
The official JEE6 Tutorial says: "Beans that use session, application, or conversation scope must be serializable, but beans that use request scope do not have to be serializable" . However, that does not seem to be the problem here, since the server is not comlaining about the bean not serializable but the product of the producer bean.
It should be..
@Stateful
@ConversationScoped
public class ProducerCreator implements Serializable{
@PersistenceConText
private EntityManager entityManager;
....
}
and if you want to use the same entity context in of each conversation it should be
@PersistenceContex(type = PersistenceContextType.EXTENDED)
finally, If you want to have service layer, should create stateful and inject to conversation bean
I had same problem running the demo on a jboss7.
Just remove @ConversationScoped at getEntityManager() did the trick to me to let it deploy.
Even though there are some flaws:
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)
I don't know exactly, if it is related, but I guess so.
Remember: EntityManager
is not serializable, so it cannot be stored in ConversationScope
精彩评论