Managed Property Inheritance

My problem is similar to the problem. I have a BaseBean that currently has only one property, which is annotated as @ManagedProperty .

However, when I access the recipient of this inherited managed property in the action method, commandbutton, it returns null. I debugged and confirmed that the basic bean constructor was called twice - once at the page load, and then at the click of a button, as already described in the mentioned link.

I followed the suggestions mentioned in the response to the selected article, as well as this , but to no avail.

Below is my code:

 public abstract class BaseBean { @ManagedProperty(value = "#{serviceLocator}") private IServiceLocator serviceLocator; public IServiceLocator getServiceLocator() { return serviceLocator; } public void setServiceLocator(IServiceLocator serviceLocator) { this.serviceLocator = serviceLocator; } } 

 @ManagedBean @ViewScoped public class RegistrationBean extends BaseBean implements Serializable { private static final long serialVersionUID = -6449858513581500971L; private String userID; private String password; private String firstName; private String lastName; private String email; private String addressLine1; private String addressLine2; private String city; private String state; private String pincode; private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationBean.class); /* getter / setters */ public String register() { String nextPage = null; try { RegistrationDetails userDetails = ModelBuilder.populateRegistrationData(this); int registrationID = getServiceLocator().getUserService().registerUser(userDetails); LOGGER.info("Registered user successfully. Registration ID - {}", registrationID); nextPage = "success"; } catch (RegistrationException e) { LOGGER.error(e.getMessage()); } return nextPage; } public void checkUserExists() { int regID = getServiceLocator().getUserService().findUser(getUserID()); if(regID > 0) { FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "User already exists !!", null); FacesContext.getCurrentInstance().addMessage(null, message); } } } 

Why the constructor will be called again on the submit form ???: /

The receiver returns null even in the checkUserExists() method, which is called via ajax in the userID field erosion event.

EDIT : Added code for ServiceLocator ..

 @ManagedBean @ApplicationScoped public class ServiceLocator implements IServiceLocator { private static final String USER_SERVICE = "userService"; private static final String MOVIE_SERVICE = "movieService"; @PostConstruct public void init() { final ServletContext sc = FacesUtils.getServletContext(); this.webAppContext = WebApplicationContextUtils.getRequiredWebApplicationContext(sc); this.userService = (IUserService) webAppContext.getBean(USER_SERVICE); this.movieService = (IMovieService) webAppContext.getBean(MOVIE_SERVICE); } private ApplicationContext webAppContext; private IUserService userService; private IMovieService movieService; @Override public IUserService getUserService() { return userService; } @Override public IMovieService getMovieService() { return movieService; } } 
+4
source share
2 answers

AFAIK, you are trying to mix two answers: one for @RequestScoped mbeans and the other for @ViewScoped mbeans. If you see the first link you posted, BalusC says you don't need to have @ManagedProperty in @ViewScoped mbeans, as shown in ViewParam vs @ManagedProperty (value = "# {} param.id)" .

If you cannot pass serviceLocator via the view parameter, you need to find another way to get this value (save / retrieve it from the session).

Also, check this information from BalusC, explaining why @ViewScoped mbean can be recreated for every request:

In a nutshell: @ViewScoped breaks when any UIComponent is bound to a bean using a binding attribute or when using JSTL or tags in a view. In both cases, the bean will behave as a request area. The first of them, in my opinion, is a rather serious mistake, the second is just an extra reason to get rid of all the JSTL material in Facelets.

This is due to the JSF 2.0 issue of 1492. Here's the relevance check: This is a chicken / egg problem with a partial saving of fortune. The view is performed to populate the view before applying the delta state, so we see the behavior that you described. At the moment, I do not see a clear way to resolve this use case. A workaround, if you must use scope bindings, will set javax.faces.PARTIAL_STATE_SAVING to false.

WITH


Based on your comments and changes, you can access @ApplicationScoped mbean using the code given here:

This will be the line:

 FacesContext.getCurrentInstance().getExternalContext() .getApplicationMap().get("serviceLocator"); 

You should use this code because, apparently, the @ViewScoped bean cannot accept the @ManagedProperty injection.

+1
source

The code for ServiceLocator not displayed, so there are a number of open-ended questions that can help determine the answer to your problem. I will comment or ask a question, and maybe something will cause "Aha!" for you:

  • Make sure ServiceLocator actually annotated with @ManagedBean .

  • Remember that you cannot enter a bean with a shorter scope (life cycle) than the target bean. In this case, if the ServiceLocator is, say, @RequestScoped , then it cannot be entered into your @ViewScoped bean.

  • can we assume that IServiceLocator is an interface implemented by some managed bean ServiceLocator ?

  • ServiceLocator smells like EJB; if so, use @EJB to enter the EJB.

0
source

Source: https://habr.com/ru/post/1443936/


All Articles