Forgive me the tone of the title. I just spent four days at work figuring out what was going wrong with our project, and I have had quite enough. We managed to fix it though, and I wanted to share the problem and the fix for those unfortunate enough to follow our tracks.
The problem. You want to add a seam-enabled web-app on top of a pure EJB3 model. The model can't have any seam in it; so no seam annotations in the code. Why ? Because we want to reuse the model in non-seam contexts. But we do want to take advantage of seam in the web-app. To me that sounds reasonable.
The idea. Enable the entity beans and session beans as seam components by defining them in a components.xml in the war. Define a seam entity manager in the conversation scope. Inject the seam entity manager wherever an EJB expects an entity manager which would otherwise get injected by @PersistenceContext. Inject other beans wherever an EJB expects something injected by @EJB. Simple enough right ?
The problem I wasted four days on. Constant exceptions related to "entityManager is closed". Tracing the cause of these took a long time, in part because it's hard to see what happens to the entity manager at run-time, in part because you also get secondary exceptions which hide the real problem (such as "entity not managed"). I also lost time to some side issues which muddied the waters (duplicate jar in the deployment); so I won't blame seam for all of the lost time.
The cause. Our sessions beans were stateless, yet they retained the same entity manager over the course of their lifetime. The first time that's ok; the entity manager is open and usable. The second time is less fun: the entity manager is now closed, and a new one was not injected. So when you try to use it: kablammo! Exception! See if you can figure out this fun stack trace, why don't ya!
A solution. Not sure if this is the best way to do it, but after four days I'm just happy it's working: make your beans stateful. Yeah, that's not quit ideal from an EJB point of view, but it's either that or redoing the front-end without seam.
Parting thoughts. For all the publicity about the flexibility of seam and how easy to use it is, I find it very strange that seemingly no one has tried to add seam on top of pure EJBs. Does everyone just give up and add annotations to the source code (seam top-to-bottom) ? If so, do they then have two versions of their EJBs lying around ? If not, what other solution is there ?
Feel free to make fun of my noob Seam skills, but if you do please give me a better solution. If not, I'll feel free to delete your comment. :-)