0

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 EntityManager 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.

rainer198
  • 3,195
  • 2
  • 27
  • 42
  • It works when making the DataRepositoryProducer a stateful bean and annotating the whole class as @ConversationScoped. Don't know if I should be happy with this solution. Maybe, the concept of a producer is not the best practice for container provided objects like EntityManager. – rainer198 Oct 03 '11 at 07:43

3 Answers3

1

Remember: EntityManager is not serializable, so it cannot be stored in ConversationScope

j0k
  • 22,600
  • 28
  • 79
  • 90
Sieracki
  • 11
  • 1
1

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

Udonake
  • 19
  • 1
  • Thanks, that's the like the solution I mentioned in my comment. I wonder whether I should use a Producer for getting an EntityManager instance anyway having in mind that a stateful EJB is hurting scalability. Why not injecting it in a JEE5 way, by using @PersistenceContext directly instead of using a dedicated producer bean. – rainer198 Oct 04 '11 at 20:40
  • By default EntityManager is transaction scoped. I think, it's not make sense to change entityManager to conversation scoped. Let's see Seam Persistence Module http://www.seamframework.org/Seam3/PersistenceModule, If you really want to produced EntityManager. – Udonake Oct 06 '11 at 07:47
1

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.

DTU
  • 13
  • 4