JSF multiple calls to getter causing service timeout - spring

I am using JSF and spring . I have a spring managed bean in session scope. I am getting a quite big list from a service call . I am calling the service and getting the list In the getter which is bind to the jsf view. when I run the app the getter is called multiple times.
so before the list is returned it is invoked again and it times out.
The list is dynamic I need to get fresh list on page load and every minute the list is refreshed using richfaces a4j poll . The list has to be retrived everytime from database.
If I change the bean to request scope and move the service call to the constructor the performance is worse.
can anyone suggest a better archetecture to do this ?

JSF managed bean getters should absolutely not call services. They should just return the managed bean property. This property should be already prepared by a (post)constructor or (action)listener method. Those methods will be invoked exactly one time. Getters will be invoked multiple times as JSF needs to access the value.
You need to rewrite your code as such that the first-time job is done in the (post)constructor of the managed bean and that the <a4j:poll> invokes a listener method which refreshes the list and that the getter does absolutely nothing else than just returning the property.
Here's a basic kickoff example using the standard Java EE 6 artifacts. I don't do Spring, but you should be able to supplant this with Spring artifacts.
#ManagedBean
#SessionScoped
public class Bean {
private List<Entity> entities;
#EJB
private EntityService service;
#PostConstruct
public void load() {
entities = service.list();
}
public List<Entity> getEntities() {
return entities;
}
}
with
<a4j:poll action="#{bean.load}" interval="60000" render="someTableId" />
See also:
Why JSF calls getters multiple times
Unrelated to the concrete problem: if you have a rather large DB table (>1000 rows) then copying the entire DB table into Java's memory is a pretty bad idea. Implement pagination/filtering.

Related

how spring singleton scope for DAO class works internally

I went through some blogs and spring docs about the Spring singleton scope along with almost all spring singleton and DAO related question in stackoverflow.
I still do not have clear understanding of how the same object is injected to all the class which depend on it. I have learnt that the DAO needs to be stateless.
If the following DAO (sample dao having instance variable mainly to clear confusion) class is defined with default singleton scope and the same object is injected everytime, then there might be scenarios where department is null and therefore it won't set anything for department value instead use whatever the previous object value was.
public class UserDAO{
int userId;
Spring userDepartment;
// getter setter methods for userId and userDepartment
public boolean addUserToUserDetailsTable(int uId,
String name, String address, String department){
// set userId
userId = uId;
if(department!=null)
userDepartment = department;
// write code to add user to user table
// TO DO
// save user department data
addUserToUserDepartmentTable(userId, userDepartment);
}
public void addUserToUserDepartmentTable(int uId,
String department){
/* Code to save department data */
}
}
So if instead of using DI, if I manually call the DAO using new operator this problem won't be there.
new UserDAO().addUserToUserDetailsTable(id, "abc", null);
the above confusion generates following questions
how is spring creating and injecting singelton beans, is it really one and only one object which gets injected to all calling classes. If this is true then how the previous object values from above DAO class is reset.
won't the instance variable hold their values here userId, userDepartment if the same object is called from multiple class ?? Does stateless means the class cannot have instance variable.
does spring internally uses new object() to inject the beans.
or it creates an object of DAO class and makes multiple clones of the object, which i think is not possible because the DAO class is not implementing clonnable.
Please help me clearing the above confusion.
how is spring creating and injecting singelton beans, is it really one and only one object which gets injected to all calling classes.
Yes, it's injecting a single instance, always the same, of the DAO class. That's the definition of singleton: a single instance is created.
If this is true then how the previous object values from above DAO class is reset.
It's not reset.
won't the instance variable hold their values here userId, userDepartment if the same object is called from multiple class ??
Yes, the unique instance will hold the userId and department, since these are fields of the instance. You might run into problems trying to read and write these values, though, since they constitute shared mutable state, which is accessed concurrently from multiple threads without any synchronization.
Does stateless means the class cannot have instance variable.
In the strict sense, yes. But a DAO doesn't need to be stateless. It needs to be thread-safe, since the same instance is accessed from multiple threads concurrently. The best way to achieve that is to avoid having any state (so no instance variable). But this is hard to achieve for a DAO, which normally needs to have access to an injected DataSource, of JdbcTemplate, or EntityManager, or whatever. Since, however, these instance variables are normally injected by Spring during startup, before the DAO starts being used by multiple threads, and never written to during the lifetime of the application, that is thread-safe. Your code, however, has state, and the state is modified during the lifetime of the application, which makes it not safe.
does spring internally uses new object() to inject the beans.
It depends how the DAO bean is declared. It can be declared using JavaConfig, using a #Bean method calling the constructor. Most of the time, reflection is used to call the constructor. So there is no new MyDAO() in the code anywhere, but the constructor is still called (only once since it's a singleton), because that's the only way to create an instance of an object from scratch.
or it creates an object of DAO class and makes multiple clones of the object, which i think is not possible because the DAO class is not implementing clonnable.
That wouldn't be a singleton if it did that.
Singleton scope beans in Spring means one instance per container and the bean has to be stateless or else you will run into issues in cases of multi-threaded scenarios.
how is spring creating and injecting singelton beans, is it really
one and only one object which gets injected to all calling classes.
Spring creates once instance at startup and passes the same reference to all the calling objects which has requested for the same via Dependency injection.
If this is true then how the previous object values from above DAO
class is reset.
If your bean is stateless there would be no value held by the object, as most of the variable would be method local and not tied to the Instance object (DAO class in this case). However in your case since you have member variable tied to a class
all the classes which acquire this DAO bean would see the same value set to the member variable and this data will be be corrupted and is not recommended.
won't the instance variable hold their values here userId,
userDepartment if the same object is called from multiple class ??
Does stateless means the class cannot have instance variable.
Yes this the exact definition of bean being stateless. As explained above.
does spring internally uses new object() to inject the beans. or it
creates an object of DAO class and makes multiple clones of the
object, which i think is not possible because the DAO class is not
implementing clonnable.
If you have not defined the bean scope, by default spring would assume it is Singleton. The understanding of singleton scope and singleton pattern is different. Spring mimics singleton pattern by providing only instance but this does not stop you from creating new instance (using say new operator).
Your Singleton is not stateless. Userid and Department define the 'state'.
Spring creates one instance using reflection 'newInstance' or a producer function in your configuration.
This one instance is then provided to all objects requesting the DAO.
Your considerations are all valid but not resolved by spring: Since your DAO has a state, it is not properly implemented and results are undefined.
Answer to question 1: It is not reset. Spring won't handle state for you!
Basically (Q2) you are on a dangerous path if you use instance variables in stateless beans. The instance vars need to be stateless themselves, like other DAO singletons.
UPDATE: I want to elaborate on this. The singleton can have a state, but the state is shared between all users of the DAO. This does not strictly require your DAO to be thread safe: If you do not use threads, there is no concurrent use - but the state of a singleton is a shared state: All users of the singleton have the same. If you have two functions like so:
#Component
public class A {
#Autowired
DaoObject singleton;
#Autowired
B another;
public void aFunctionA() {
singleton.userId = "Foo";
System.out.printf("UserId: %s%n", singleton.userId); // prints Foo
another.aFunctionB();
System.out.printf("UserId: %s%n", singleton.userId); // prints Serviceuser
}
}
#Service
public class B {
#Autowired
DaoObject singleton;
public void aFunctionB() {
singleton.userId = "Serviceuser";
}
}
The state of the singleton singleton is shared between all users of the class. If one class changes the state, all other users have to cope with that.
If you are using threads, this adds extra complexity on stateful singletons, as your modifications to state must be thread safe.
It is common practice to keep a singleton immutable after initialization.
On your 4th question: Spring will not clone a Singleton, as described above.

Spring: new() operator and autowired together

If I use Spring, which of these two methods is more correct.
Can I use the new() operator even if I use dipendency injection?.Can I mix both?
I would like to have some clarification on these concepts.
Thanks
First method:
#RequestMapping(method=RequestMethod.GET)
public String create(Model model){
model.addAttribute(new User());
return "index";
}
Second Method:
#Autowired
User user;
#RequestMapping(method=RequestMethod.GET)
public String create(Model model){
model.addAttribute(user);
return "index";
}
By using dependency injection does not mean that the use of new operator is automatically prohibited throughout your code. It's just different approaches applied to different requirements.
A web application in spring is composed of a number of collaborating beans that are instantiated by the framework and (unless overriding the default scope) are singletons. This means that they must not preserve any state since they are shared across all requests (threads). In other words if you autowire the User object (or any other model attribute), it is created on application context initialization and the same instance is given to any user request. This also means that if a request modifies the object, other requests will see the modification as well. Needless to say this is erroneous behavior in multithreaded applications because your User object (or other model attribute) belongs to the request, so it must have the very narrow scope of a method invocation, or session at most.
You can also have spring create beans with different scopes for you, but for a simple scenario of a model attribute initialization, the new operator is sufficient. See the following documentation if interested in bean scopes : Bean scopes
So in your use case, the second method is totally wrong.
But you can also delegate the creation of your model attributes to spring if they are used as command objects (i.e. if you want to bind request parameters to them). Just add it in the method signature (with or without the modelattribute annotation).
So you may also write the above code as
#RequestMapping(method=RequestMethod.GET)
public String create(#ModelAttribute User user){
return "index";
}
see also : Supported method argument types
If you want your beans to be "managed" by Spring (for e.g. to use with Dependency Injection or PropertySources or any other Spring-related functionality), then you do NOT create new objects on your own. You declare them (via XML or JavaConfig) and let Spring create and manage them.
If the beans don't need to be "managed" by Spring, you can create a new instance using new operator.
In your case, is this particular object - User - used anywhere else in code? Is it being injected into any other Spring bean? Or is any other Spring bean being injected in User? How about any other Spring-based functionality?
If the answer to all these questions is "No", then you can use the first method (create a new object and return it). As soon as the create() method execution is complete, the User object created there would go out of scope and will be marked for GC. The User object created in this method will eventually be GC-ed.
Things can be injected in two ways in a Spring MVC applications. And yes, you can you can mix injection and creation if doing right.
Components like the controller in your example are singletons managed by the application context. If you inject anything to them it is global, not per request or session! So a user is not the right thing to inject, a user directory can be. Be aware of this as you are writing a multithreaded application!
Request related things can be injected to the method like the used locale, the request, the user principal may be injected as parameters, see a full list at Spring MVC Documentation.
But if you create a model attribute you may use new() to create it from scratch. I will not be filled by spring but to be used by your view to display data created by the controller. When created in the request mapped method that is ok.

Accessing Spring #Transactional service from multiple threads

I would like to know if the following is considered safe.
Usual Spring service class that accesses a bunch of DAOS / hibernate entities:
#Transactional
public class MyService {
...
public SomeObject readStuffFromDB(String key) {
...
//return some records from the DB via hibernate entity etc
}
A class in the application that has the service wired in:
public class ServiceHolder {
private MyService myService;
private SomeOtherObject multiThreadedMethod() {
...
//calls myService.readStuffFromDB() and uses the results
//to return something useful
}
multiThreadedMethod will be called from multiple threadpool threads. I would like to know if the multiThreadedMethod is safe in its calls to myService.
It is NOT making any modifications to the DB - only reading.
What happens if two threads call myService.readStuffFromDB() at exactly the same time? Will a concurrent modification exception be thrown from somewhere?
I've been running it with no issues but I'm not 100% sure it will always work.
Yes you will call the same object in the same time as long as your service bean is defined as singleton (which is default and proper), but you should not rely on local variables in you services. So the methods should be written that way they can work independently (you don't need a mutual exclusion here). If you called db and tried do any operations nothing would happen because every thread would receive a new instance of entity manager. If you modified db in the same time and any type of db exception was thrown you would get a rollback exception which is perfectly fine.
entityManager.persist() will do more or less entityManager.getEntityManagerAssignedToCurrentThread().persist()
It is a proxy not real object. So you are safe :)

How does business logic class calls methods inside a managed bean?

I have some business logic code that renders some facesMessages on the facelet based on its output, so i made a method in the facelet managed bean like this method:
public void renderFacesMessages(String summary, String detail) {
FacesMessage message = new FacesMessage(summary, detail);
FacesContext.getCurrentInstance().addMessage(null, message);
}
and the business logic class will pass arguments to this method according to the message that's needed, the question is what is the right approach for business logic to call this method on the managed bean?
It is all about the Layering Concept...
I presume you have a ManagedBean which has a method that will delegate the business logic to a seperate Business Class/Module.
If this is the case,I would tell you ,NEVER have any Faces Methods on the Business Side...
Instead have the Business Results wrapped in a Class and return back to Managed Bean.This Result Class will encompass the Results,Meta information about the Result like,Errors,Exceptions.So now your managed Bean can use the renderFacesMessage method
Even if you had not followed the above presumption:My Suggestion
Never have JSF Faces Logic inside Business Components.It will be a bad Idea.
Don't let the business logic call a JSF backing bean.
Instead let the backing bean call the business logic (eg an EJB bean or a transactional CDI bean in Java EE 7), then depending on the result of this call (exception, return value, etc) generate Faces messages and/or redirect to a new page etc.
As the businesslogic will be stateless (I guess/hope so), I would say that you should let the managed bean which called your businesslogic handle the error message display, by catching an exception e.g.
On the other hand, you can pass the managed bean to the businesslogic (or better, just an interface of the managed bean), so the businesslogic can callback the managed bean. But i would prefer the first approach.

Difference between Stateless and Stateful session bean

I knew stateful beans maintain conversational session between different instance method call,but stateless will not.My question,assume I have a stateless bean implementation like below
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import com.tata.ejb3.data.HelloEJBInterface;
#Stateless
public class ValueEJB implements ValueEJBInterface{
private int value;
#Override
public int getValue() {
return this.value;
}
#Override
public void setValue(int value) {
this.value = value;
}
}
I have my bean client(A servlet) which initiates bean invocation as below
#EJB(mappedName="E/ValueEJB /remote")
ValueEJBInterface value;
....
value.setValue(250);
System.out.println(value.getValue());//This statement prints the value 250
....
According to my understanding as my bean is stateless bean it should not displayed with value 250.
private int value; is an instant variable,if one stateless method set its value , the value will be expired on method exit.But here, I am able to get the value '250' even via my second method call. Is it a violation of stateless concept? Am I lacking something?
Difference between Stateful v Stateless bean behavior when calling different methods.
STATEFUL: When calling different methods on a Stateful Bean, different bean instances are created.
((MyStatefulBeanRemote) ctx.lookup("ejb/MyStatefulBean")).doingStatefulThing();
((MyStatefulBeanRemote) ctx.lookup("ejb/MyStatefulBean")).doingNothingStatefulThing();
***Output: Note the creation of separate objects.***
INFO: Calling doingStatefulThing...com.myeclipseide.ejb3.stateful.**MyStatefulBean#2fe395**
INFO: Calling doingNothingStatefulThing...com.myeclipseide.ejb3.stateful.**MyStatefulBean#81cfcb**
STATELESS: When calling different methods on a Stateless Bean, the beans are pooled, hence no new instances of the bean are created.
((MyStatelessBeanRemote) ctx.lookup("ejb/MyStatelessBean")).doSomething();
((MyStatelessBeanRemote) ctx.lookup("ejb/MyStatelessBean")).doNothing();
***Output: Note the reuse of he bean object.***
INFO: Doing something ...com.myeclipseide.ejb3.stateless.**MyBean#213b61**
INFO: Doing Nothing ...com.myeclipseide.ejb3.stateless.**MyBean#213b61**
Interesting question and basically you are totally right. I did some research and the general advice is to: "Expect your bean to forget everything after each method call ..." (page 81). Furthermore, according to that resource, the algorithm responsible for maintaining the state of Stateless Session Beans is container / vendor specific. So the container may choose to destroy, recreate or clear the instance after method execution.
You could create a multi threaded test and see how it behaves with multpile clients.
There is no violation of any concept. Its because the same instance of bean is picked by the container from the pool to serve other request.
Stateless beans are pooled & therefore they have performance benefit over statefull beans, also their main purpose is processing without holding any state.
Sensitive or user specific data shouldn't be stored in instance variables of stateless beans. They should be used extensively to process data without any consideration of state.
Can refer here for their life-cycle events handled by the container.

Resources