when will JSF #PostConstruct be called again? - spring

I'm making an application with spring+primefaces
I created a init function in managed bean to load some useful data (the bean is #ViewScope)
#PostConstruct
public void init(){
log.debug("initing....");
currentUser = UserUtil.getCurrentUser(this.userManager);
loadData();
}
later in view I have some tags to hide columns like this:
<p:column rendered="#{dataManagedBean.currentUser.manager}"> // to test if the current user is a manager role
...
...
</p:column>
the problem is when I login with a normal user, then even logout and login with manager user, the column I want to show is not showing, because the init() method is not calling again therefore the "currentUser" remains the oldone (normal suer)
UPDATE
the problem maybe I mixed Spring DI and JSF managed beans, there is more detail
in javabean layer: I used #Entity annotation for hibernate
in dao layer: I use #Repository("DataDao") to inject the daos (from
spring)
in manager layer: I use use many spring annotations to inject like
#Service("DataManager") #Authowire #Qualifier etc
in view layer, since I have been using spring to inject, thats why I
use #Component("DataManagedBean") and #ViewScope
I have been 2 weeks with the application, and everything worked as expected. untill I found today #PostConstruct is actually never call again, the view is never destroy :S (or it's intented to work like this, a singleton...)
Can someone kindly explain me where I did wrong?

After an intensive reading about JSF scopes, specially thanks to #M. Deinum's comments and Mr #BalusC's excelent article explaining about the JSF communication topic. I understand why the user object survived event after logout/relogin.
My mistake is combining Spring DI (by using #Component annotation) and JSF annotation (by using #ViewScoped), then the #ViewScoped annotation is ignored and default spring scope is used, which is by default a singleton...

Related

No existing transaction found for transaction marked with propagation 'mandatory'

This is somewhat weird behavior. I moved from Spring MVC to Spring Boot Configuration. This has caused the #Transactional method to throw the above error. Not sure why would switching from MVC to boot mvc do that. Anyone having nay idea about this?
I don't have specific code snippet as this is application wide and was working fine till I had Spring MVC. Now I moved to Spring Boot (Dependency upg. Filters moved etc.)
Flow for the methods having #Transactional is:
Action is called
If contains execute() which calls a Save method with #Transactional from a class which is implementation of an interface.
This class have another Dao method having #Transactional.
Thanks

Spring Rest Controller - business validations & resolving id

We are designing rest api for our existing application using spring+jpa.
want to validate the input/request payload prior to persisting. Have found #PrePersist listener method and hope we can validate entity business validations(unique etc) and id's can be resolved in prior to persist, however had few issues
EntityManager is not auto wired: trying to autowire entity manager in super Entity class like below so that entityManger object can be used in all subclasses
#PersistenceContext
protected EntityManager entityManager;
Understood that since the entity is not spring managed bean, entity manager object is not autowired.
After setting entiy object manually (as a workaround for point 1), while trying to resolve ids based on user provided values in PrePersist callback method resulted is getting same method called recursively.
any suggestion/way to implement business validation and resolving ids based on values from jason payload for rest api would greatly appreciate.
Thanks
Have implemented AOP aspect to validate the rest resources prior to persisting which is working pretty good as expected.

Ajax calls are not working when bean is changes to #Scope("request") with PrimeFaces

I am new to Spring/JSF.
I have a controller which is annotated by #Component which have a #Autowired class UserClass which has,
#Scope(value=org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE)
I need to create a new UserClass instance for each new request so my controller is annotated with #Scope("request") which works perfectly(Creating new instance for each request) with this annotation.
But it broke the ajax calls in <p:dataTable> selection, commondLink, <f:setPropertyActionListener...
NOTE : if I change the #Scope("request") to #ViewScoped the ajax works but my UserClass becomes singleton and all the data is shared between the threads.
I googled and got to know we need to either use JSF annotations or Spring but here I am using only Spring annotations.
And I found this, PrimeFaces doesn't work when bean scope is request but couldn't understand.
A component library like Primefaces heavily relies in a stateful model, which means using at least the view scope in your managed beans. If you use the request scope you'll be recreating the managed bean for every single request, including ajax requests, which I guess it isn't what you want (not the way to go with JSF, at least).
Your best is to use a custom Spring Scope in order to emulate the JSF view scope. I like this approach from the PF team (a bit old post, but still you can tune it for newer Spring versions) or this one, which is more elaborated.

Issue in understanding the Spring Bean Scopes Vs Spring web flow Session Scopes

We Know the Spring Framework gives
singleton,
prototype,
request,
session,
global_session
bean Scopes.
Also we know that Spring web flow gives flowScope,viewScope,requestScope,flashScope,conversationScope.
So If i mentioned one Component, say Student, as #Component #Scope=singleton in a spring MVC project. For each request, will it create a new Student Object or Spring container will create only once?
You are confusing yourself with objects and beans.
For each request, will it create a new Student Object or Spring container will create only once?
The functioning of Spring is purely using beans. When you declare a something like a #Component, it's just an annotation that tells Spring that the part you've declared as a component is either Model or View or Controller i.e. a component of MVC. When you say something like #Scope=singleton, it tells Spring that only a single object instance can access the bean.
Let me make it more clear. Say you and I are objects and a strawberry candy is a bean. So if you have the candy. I cannot take it from you. Meaning only one of us can have that candy. It's the same thing with singleton scope.
Hope I made things simpler.. :)

How to inject a JSF bean into a spring bean

I'm working on a legacy JSF application which we are slowly porting over to Spring MVC. We are using Spring Security to control login information. After logging the user in, the JSF pages globally instantiate a session scoped bean that is used everywhere. I'd like to change the application so that we can go to a page that was developed with Spring MVC first.
One approach I tried was to convert the bean into a spring bean and have it injected into JSF, but unfortunately that turned out to require a lot of changes to the bean to make it possible. One possible hack I thought of is to add a special redirecting JSF page to initialize the JSF beans before sending the user to the Spring MVC page. That seems like quite a bit of a hack though so I'm looking for another solution.
Is there some other way that I can force the session scoped bean to be initialized before I go to my Spring pages so that I can just pull the bean out of session?
If you are using Spring MVC, you can make your "bean" a Model Attribute, then have it auto-loaded into session using a combination of annotations on the Controller, handler methods, and a method that creates an instance of your bean. Your controller would look something like this:
#Controller
#SessionAttributes({"myBean"})
#RequestMapping("/myPath")
public class MyController {
#RequestMapping("/myPath2")
public String myHandler(#ModelAttribute("myBean") MyBean myBean) {
// ...do stuff, return view
}
#ModelAttribute("myBean")
MyBean createMyBean() {
// Create and init an instance
return new MyBean();
}
}
You will get a MyBean magically created for you whenever there isn't one, and any time you update the Model (or ModelAndView) with "myBean", it will also get magically added to the Session.

Resources