I'm reading EJB3 in Action and I'm wondering how to use stateful beans from a web client like a servlet or JSP. I know that I can't inject it into an instance variable of the servlet,but I would just like to confirm the validity of the following :
Could I not just inject the stateful bean into a local variable of the doPost method?Aren't the local variables of the servlet thread-safe?
And I have another question regarding datasources and connections.I see in the EJB3 in Action examples they open and close java.sql.Connections with the @PostConstruct and @PreDestroy methods respectively...Isn't this very wasteful???Considering that every single bean in the pool has it's own connection?Or am I missing something here?
It all depends of the type of the bean, if you have got stateful bean you shouldn't use DI, but if the beans are stateless you can use it and don't worry about thread safe.
And now your second question. Again it depends of the bean type. If the bean is stateless there will be just a few (probably, but it ofcourse depends on the configuration) beans in the pool, and all the 'users' will use them - these few beans . When they will be created (@PostConstruct) - the data connections will be open, and thanks to this, everybody will use it. Stateless beans are not created very othen. It would be very bad if you would open connection in the business method - then, every request would open the connection - this would be inefficient.
Also I am having a strange issue with glassfish.I have a web project and an EJB 3 project inside the same EAR.I can't seem to access my bean via the Local interface.Only the remote interface.I have also tried using ejb-local-ref in the xml but this didn't help.Either way I get the following stack trace:
[#|2009-12-13T19:33:50.875+0200|SEVERE|sun-appserver9.1|javax.enterprise.system.tools.deployment|_ThreadID=43;_ThreadName=Thread-2957;_RequestID=4716fad7-35a5-4e30-8387-c8c12bdce3c2;|Exception occured in J2EEC Phasejava.lang.RuntimeException: Cannot resolve reference Unresolved Ejb-Ref servlets.TestEJBServlet/hiyaTwo@jndi: @null@ejb.HelloBeanLocal@Session@null
com.sun.enterprise.deployment.backend.IASDeploymentException: Error loading deployment descriptors for module [WebLocal] -- Cannot resolve reference Unresolved Ejb-Ref servlets.TestEJBServlet/hiyaTwo@jndi: @null@ejb.HelloBeanLocal@Session@null
Caused by: java.lang.RuntimeException: Cannot resolve reference Unresolved Ejb-Ref servlets.TestEJBServlet/hiyaTwo@jndi: @null@ejb.HelloBeanLocal@Session@null
... 10 more
And my code looks like this:
It's strange because it won't even deploy if I try inject the Local interface.As soon as I comment out the Local injection it runs fine though.Can anyone tell me where I'm going wrong?
P.S Injecting session beans is one of the most stressful things at the beginning of EJB learning. Really.
If I right-click the EAR and select Properties->Build->Packaging I can see both the web project and the ejb-project.It says "Location in archive: /".ie. both are located in the root of the EAR
Although there is a missing project there(one that I deleted before)I'm still very new to Netbeans...
PS. I think the most stressful thing is figuring out what the attributes on the annotations do(ie. beanName,mappedName,beanInterface,name)I tried multiple combinations today but the only way I could get the stuff working is by not using any of the attributes...Also the JMS/messaging chapters in EJB 3 in Action are baffling me,gonna do transactions first and then come back to them.
Anyway, I agree with you, beans attributes (name, mappedName etc.) are quite stupid :P. It's really hard to find anywhere good information about how to use them properly (from A to Z). Here is a webpage which can be quite useful while you are learning about it: https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html#SessionBeanGlobalJNDINameAssignment
I just checked the specs and it defines 'local access' as a client running in the same container as the bean...
Use of a session bean’s local interface(s) entails the collocation of the local client and the session. The
local client of an enterprise bean must be collocated in the same container as the bean. The local client
view is not location-independent.
But then in another section it states in the same JVM....That explains it....
So then why doesn't my local interface work!!I only have one instance of Glassfish..!Do you think my Glassfish has it's webserver and ejb container running on different JVM's on my machine??