I have Enterprise Java Bean which is Statefull and it holds current user instance
I want to get this instance from few different baking beans (SessionScoped managed beans) but when Im using:
#EJB
UserSessionBean usb;
(...)
usb.getUser();
I am getting null pointer exceptions in the ManagedBean (seems that every managedbean is getting new instance of UserSessionBean EJB. Why is that? I thought one instance of that bean would be shared among all Beans for that session...
if UserSessionBean is the implementation class or interface?
I think you should use the interface to create an instance of your EJB.
also take a look at #statefull and #singlton annotations.
Related
I am new to spring and not able to understand when to instantiate the class with new operator and when by using spring container.
example i found a code
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
EmployeeDao dao=(EmployeeDao)ctx.getBean("edao");
int status=dao.saveEmployee(new Employee(102,"Amit",35000));
System.out.println(status);
int status=dao.updateEmployee(new Employee(102,"Sonoo",15000));
System.out.println(status);
Employee e=new Employee();
e.setId(102);
int status=dao.deleteEmployee(e);
System.out.println(status);
}
}
i am using jdbc template. i have a doubt why we have new to instatiate employee class instead we should have used (Employee)ctx.getBean("employee"). using new operator would create dependency?
Pls help
From ProSpring book,
"Of the applications that we have built using Spring,
the only objects that are consistently not managed by Spring are domain objects. (Even though in Spring
it’s possible to have Spring manage domain objects by applying the #Component annotation to the classes
and assigning them with prototype scope, most of the time we will choose to manage domain objects
within the application.) The reason for this is that, practically, Spring does not need to be involved with
domain objects. Generally, you create many instances of your domain objects using the new() operator
and perform processing either in the service or data access layer. Although Spring also supports the
injection of new instance of domain objects every time it was requested (by using the bean scope
prototype), generally developers will not adopt this approach since typically domain objects do not take
advantage of Dependency Injection, because they generally have few dependencies outside of the DOM
itself, and they don’t require much configuration."
So, yes you could create beans of type Employee but then they wil have to be defined as prototype as be default all beans in spring are singletons. because there can be many employees and their objects, you obviously cannot have Employee as a singleton. but your concentration as to the utilization of spring features should be much more than managing domain objects.
The Spring IOC container is at the core of the Spring Framework. The container will create the objects, wire them together, configure them, and manage their complete lifecycle from creation till destruction.The IoC container gets informations/metadata either from XML or by Java annotations, or by Java code.
Yeah you can create Employee bean in your spring context xml file and make sure scope is prototype as
<bean id="employee" class="com.mycompany.Employee" scope="prototype"/>
so that on every request of Employee bean, you will get a new object Employee.
There are other scopes of beans
singleton : This scopes the bean definition to a single instance per Spring IoC container (default).
request : On every HTTP request a new bean will created and delivered.
prototype : on every request(api request) a new bean will be created.
session : This scope a bean definition to an HTTP session.
Note : It is not recomemded to create beans for database model class.because your persistent layer will take care of it.
Questions about ejb session bean behavior when used as injected bean instances.
I'm not 100% sure how this works. I guess it from practice and from reading documents on the subject.
I want to know how #EJB annotation is processed by container in detail.
Session bean have interfaces, impl class, deployment descriptor. We package them in ejb jar.
What is putted in global JNDI by container? Static references to
business interfaces ?
How and when global JNDI is read from ?
When component JNDI ENC is populated with ejb reference ?
Is this reference in JNDI ENC (java:comp/env/beanB) is reference to
session bean component interface, session bean instance proxy or
session bean instance ? Is there difference for SLSB and SFSB ?
With #EJB annotation on field does every new ejb session bean
instance get new instance of injected ejb in the annotated field or
all ejb instances share the same injected ejb session bean instance
?
Does ejb injection by lookup (on session context) provide always new
injected ejb instance, example: calling ctx.lookup(ejbReference) in
loop ?
In EJB 3.0, the JNDI names are vendor-specific (if available at all; in theory, a container could support EJB references only), but vendors typically return an EJB reference/proxy. In EJB 3.1, the specification requires the EJB container to make specific java:global, java:app, and java:module names available, and the object returned from these lookups must be an EJB reference/proxy.
The global JNDI is accessed when you perform a JNDI lookup. The container might access the global JNDI names in other cases (e.g., when resolving #EJB(lookup="java:app/...")).
It's undefined when the container populates java:, but the contents must be available before lifecycle callback or business methods are invoked on the component instance.
#EJB/<ejb-ref>/<ejb-local-ref> ensure lookups always return an EJB reference/proxy and never an actual bean instance. The proxy ensures that all container services are performed (security, transaction, remoting, etc.) before invoking an actual bean instance. For SLSB, an arbitrary bean instance will be invoked, and the same or different actual instance might be invoked depending on the thread, concurrency, timing, vendor-specific configuration, etc. For SFSB, a bean instance with a specific identity will be invoked; you are likely to get the same bean instance, but you might not if the EJB container has passivated the actual bean instance, but reactivation should result in an instance with equivalent state. For singleton session bean in EJB 3.1, you are guaranteed the singleton bean instance will be invoked.
It's undefined whether you get the same proxy instance. For SLSB and singleton beans, injection or lookup could return a single proxy that delegates to the actual bean instance as mentioned above. For SFSB, the proxy is basically required to be a separate instance per injection or lookup since the proxy must store some state with the identity so it can invoke the specific actual bean instance.
It's undefined what the container does, but injection is typically implemented by containers using Context.lookup followed by Field.set (or Method.invoke for setter method injection). Regardless, the instance handling is as described above.
Well, i need use #Schedule (EJB) to put a task in crontab. I know that CDI dont have this (unhappy), just EJB. All my beans are CDI-Managed, so i have some doubts to include EJB inside this project, i hope that you can help me:
1) I'll create a new bean to use #Schedule, but i dont know if this bean should use #Singleton (EJB) or #Named + #RequestScoped (CDI). My ideia is that:
#Singleton
public class RoboFtp implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Inject
private VideoBOImpl videoBO;
#Schedule(...)
public void coletarVideo(){
//do something each 3 seconds
}
}
Note that i have a CDI Bean inside a EJB Bean, this is possible ? This above bean is correct ?
2) How can i add the ejb to my pom.xml ?
3) If i add EJB to my project can have any conflicts ? Because my project is already in production.
To dispel your worries:
1) CDI Bean inside a EJB Bean, this is possible ?
CDI && EJB works pretty well together. In fact CDI will detect EJB beans and turn them into CDI beans as well. So if you create, say #Stateful bean, it will be picked up as CDI bean as well. That means you will be able to perform any CDI-related magic there while still having EJB features.
As for choice of annotation, #Singleton sounds reasonable; or probably #Stateful?. #RequestScoped would only live during request and die afterwards hence killing your periodic task. Choose scope based on nature of your task (one bean vs many/ short lived vs permanent/ ..). Just make sure you make it an EJB bean and CDI will follow.
2) How can i add the ejb to my pom.xml ?
Assuming you have Maven project, add a dependency on EJB api, the implementation will be provided by your Java EE application server.
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb-api</artifactId>
<version>${desiredVersion}</version>
</dependency>
3) If i add EJB to my project can have any conflicts ?
Too general question I am afraid; I do not know your project. But I'll go ahead and say "no". At least as far as CDI and EJB goes, you should be able to deal with it.
I was wondering... Let's say that I have two stateless beans in ejb 3.1:
#Stateless
Class1
#EJB MyUniqueInstanceBean uniqueBean1;
2.
#Stateless
Class2
#EJB MyUniqueInstanceBean uniqueBean2;
Are uniqueBean1 and uniqueBean2 guaranteed to be unique instances of MyUniqueInstanceBean?
If MyUniqueInstanceBean is Stateless it is not in your hands are calls to uniquebean1 and uniquebean2 actually calls to same instance. In EJB 3.1 specification this is told with following words:
Because all instances of a stateless session bean are equivalent,
the container can choose to delegate a client-invoked method to any
available instance. This means, for example, that the container may
delegate the requests from the same client within the same transaction
to different instances, and that the container may interleave requests
from multiple transactions to the same instance.
If MyUniqueInstanceBean is Stateful, it is guaranteed that uniquebean1 and uniquebean2 do not refer to same instance. Again from specification:
A session bean instance’s life starts when a client obtains a
reference to a stateful session bean instance through dependency
injection or JNDI lookup, or when the client invokes a create method on the session bean’s home interface. This causes
the container to invoke newInstance on the session bean class to
create a new session bean instance.
If you are using Singleton, then both refer to same instance, because there is only one instance:
A Singleton session bean is a session bean component that is
instantiated once per application. In cases where the container is
distributed over many virtual machines, each application will have one
bean instance of the Singleton for each JVM.
Is it enough to convert a POJO like Util class to an EJB session bean by putting an annotation (#Stateless or #Stateful) and using injected EntityManager in it?
Yes, #Stateless in enough. Your bean will then become an EJB bean.
The only other requirement is that you can't create such a bean with new. You have to inject it using #EJB in another managed bean (JSF managed bean, Servlet, etc). Or if you aren't yet in any kind of managed bean, you can bootstrap a bean using a JNDI lookup.
Also, EJBs indeed greatly reduce the boilerplate code of starting and committing transactions when working with JPA.
Well It is enough but still few things need to be taken Care,
1) Mark your Entity manager and other new variables to Transient if POJO is used to persist some object.
2) It is better not to do so, as If u need to make it as EJB better to Create Some New Class for it as it is suggested way to not to create complexity.