Display datatables values from databse using spring injection in a ManagedBean - spring

Got this design issue with JSF + Spring :-
I got a datatable on a page to be loaded showing user details, which is to be fetched form Database.
So my jsf page has :
<p:dataTable id="userTable" var="user" value="#{userBean.users}" rowKey="#{user.userID}"
selection="#{userBean.selectedUser}" paginator="true" rows="10" >
Managed bean has:
private List<UserDetails> users; // getters and setters
Now my managed bean needs a spring injection of the helper class to fetch the users from DB.
#ManagedProperty(value="#{userBO}")
private UserBO userBO;
The problem is , spring injection happens when the object is completely instantiated. So I cannot place my userBO.getUsersFromDataBase() in the constructor and assign it to my users
I just can't figure out how to fetch users from DB,using spring injection in my managedBean. Spring needs the instantiation of the ManagedBean to be complete so that it can inject the helper class, but the jsf page requests the database values much before the ManagedBean is completely instantiated. Kinda stuck :/

I am not familiar with spring, however in standard JSF you can use the #PostConstruct annotation on a method that will be invoked after construction and after dependency injection, e.g.:
#PostConstruct
public void init() {
userBO.getUsersFromDataBase()
}

Related

Best way to provide validation to spring mvc & hibernate projects

I'm new to spring & hibernate, please suggest a best way to provide validation to spring mvc & hibernate projects. I tried hibernate validator but i don't know how to use it when there is relationship(like #OneToOne) between entity objects. If there is any examples, please provide the link.
Your #OneToOne relationship is not clear enough. Could you please give a concrete scenario?
In Spring MVC you have three types of validations:
JSR-303 bean validation (hibernate validator)
Custom validation
Spring validation
JSR-303 works great for simple validations on single fields. You have standard annotations like (#Max, #Min, #NULL, #Pattern, etc.). It does not seem enough for you in this case.
Custom validation is used in a more complex scenario. For instance, what if we need to validate that the newly added product ID is not the same as any of the existing product IDs?
Spring validation represents cross-field validation.
For instance, it's used when we want to compare two or more fields to see if
their values can be considered as valid when combined.
you can use spring validation method.
using valid annotion in controller classes infront of modelattribute annotaion.
then you can use validaions in the model class.
below is an example for controller and bean classes.
this is a many to one configuration inside a bean class:
#ManyToOne(targetEntity = UserType.class)
#JoinColumn(name = "user_type", referencedColumnName = "id")
#NotNull
private UserType userTypeTb;
this is a method inside controller class with valid and modelattribute annotaion:
public ModelAndView home(#Valid #ModelAttribute("user") User user, BindingResult result,
HttpServletRequest request) {
//
//
}

inject spring bean in JSF component

I have a composite component with a component class:
#FacesComponent("myComponent") // not really necessary I think because I have declared it in faces-config.xml
public class UserHelpPopOver extends UINamingContainer {
#Autowired
private MyBean myTemplate;
// omitted code
}
How can I get Spring to auto inject this bean? :) It is null when I debug it all the time.
UI components are not eligible for dependency injection.
You've there a design problem. You shouldn't reference a managed bean (the controller) in UI component (the view) yourself. The enduser should do it by itself. E.g.
<my:customComponent template="#{myBean}" />
Wrap if necessary in a tagfile to keep it DRY.

Injecting a bean to use in Controllers throughout the application

I'm using spring mvc 3.1.x and jets3t.
I have a DataAccessObject that i instantiate as a Singleton bean..
I managed to get it working through extending the applicationcontextloader class and adding it to the web.xml
EDIT:
I changed my method, I tried inject and autowired but it's not suitable for my needs.
What I've done was to implement ApplicationContextAware and set it up as a bean, in the code I use it as follows:
ApplicationContext ctx = BannerApplicationContext.getApplicationContext();
BannerGenericDAO bdao = (BannerGenericDAO) ctx.getBean("dao");
I'm new to Spring and in general the servlet world..
Questions are:
what's the best way of doing this? Is this considered a "best-practice"?
How do you inject an object, keeping other method fields that are not supplied by autowiring?
How do you get an object to be used throughout the entire application?
Thanks!!
You could use annotations in your controller.
#Controller
public class MyController{
#Autowired // or #Inject, which is more JEEish (JSR330).
private SomeDao daoService;
}
Given "SomeDao" is the type of your singleton DAO, of course.

JSF multiple calls to getter causing service timeout

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.

a question about the design Validation using JSF framework

In software design sort of way, what is best: checking unique input (e.g username) in the DB using a JSF Validator, or using the Controller (managed-bean).
Apparently, in JSF framework, I can't use #EJB in the Validator, so in case I use the Validator for the checks, then I would have to connect to the DB in another way (jdbc connection or something).
In case I check this one in the Controller, I would have to put some logic that is not necessary a part of the process (for example: createUser method).
So, what is the best way according to the JSF framework?
Apparently, in JSF framework, I can't use #EJB in the Validator, so in case I use the Validator for the checks, then I would have to connect to the DB in another way (jdbc connection or something).
That's right. A common workaround for this is to declare and use the validator as a #ManagedBean.
E.g.
#ManagedBean
#RequestScoped // Can be #ApplicationScoped if it does not hold any state.
public class UsernameValidator implements Validator {
#EJB
private UserService userService;
// ...
}
with
<h:inputText validator="#{usernameValidator.validate}" />
or
<h:inputText>
<f:validator binding="#{usernameValidator}" />
</h:inputText>

Resources