0

i am useing a @ManagedProperty in JSF 2.0 but i am getting a below problem.

Entity Class

@Entity(name="UserDetail")
@Table(name="in_user")
@SessionScoped
public class UserDetail implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    private Integer no;
    private String userName;
    private String password;


    public Integer getNo() {
        return no;
    }
    public void setNo(Integer no) {
        this.no = no;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }


}

Controller

@ManagedBean(name="authenticator")
@RequestScoped
public class Authenticator implements Serializable {

    private static final long serialVersionUID = 1L;

    @ManagedProperty(value = "#{userDetail}")
    private UserDetail userDetail;

        // Some Code......
}

.XHTML

<p:panel header="Application Login" toggleable="true" toggleOrientation="horizontal" style="width:400px">
                <p:panelGrid columns="2" columnClasses="0">
                    <h:outputLabel value="User Name " />
                    <h:inputText value="#{authenticator.userDetail.userName}" />

                    <h:outputLabel value="Password " />
                    <h:inputSecret value="#{authenticator.userDetail.password}" />

                    <p:commandButton value="Login" action="#{authenticator.authenticate}"></p:commandButton>
                    <p:commandButton value="Log Out" action="#{authenticator.logOut}" />
                </p:panelGrid>
            </p:panel>

when i execute the application, i am facing below problem..

Mar 29, 2013 7:26:56 PM com.sun.faces.lifecycle.ProcessValidationsPhase execute
WARNING: /login.xhtml @21,66 value="#{authenticator.userDetail.userName}": Target Unreachable, 'userDetail' returned null
javax.el.PropertyNotFoundException: /login.xhtml @21,66 value="#{authenticator.userDetail.userName}": Target Unreachable, 'userDetail' returned null
    at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:95)
    at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030)
    at javax.faces.component.UIInput.validate(UIInput.java:960)
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
    at javax.faces.component.UIInput.processValidators(UIInput.java:698)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
    at org.primefaces.component.panel.Panel.processValidators(Panel.java:297)
    at javax.faces.component.UIForm.processValidators(UIForm.java:253)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
    at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172)
    at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

i don't know where is the problem.

if i replace.

@ManagedProperty(value = "#{userDetail}")
    private UserDetail userDetail;

with

private UserDetail userDetail = new UserDetail();

then it's work fine. but i want to use @ManagedProperty. please help me.

Jimit Tank
  • 1,379
  • 5
  • 17
  • 25
  • What package did you import `@SessionScoped` from in `UserDetail`? – kolossus Mar 29 '13 at 14:17
  • @kolossus - i used import javax.faces.bean.SessionScoped; – Jimit Tank Mar 29 '13 at 14:20
  • You do have getter and setter for the injected bean, right? And you do know that mixing entity layer and presentation layer is a good example of bad design. – skuntsel Mar 29 '13 at 14:26
  • Don't know how I missed it but `UserDetail` is not an `@ManagedBean`. It won't be found otherwise. Currently, it's scoped but not managed – kolossus Mar 29 '13 at 14:27
  • @skuntsel, I think in this particular case it's fair use of *MVC*, where `UserDetail` is the textbook definition of *M* – kolossus Mar 29 '13 at 14:29
  • @kolossus yes it's true UserDetail is a entity, it's not a ManageBean. – Jimit Tank Mar 29 '13 at 14:32
  • @skuntsel yes i have created a getter and setter for UserDetail, can i use ManagedProperty for entity.. because here i need a instance of a entity class. – Jimit Tank Mar 29 '13 at 14:34
  • To begin with, you should never use a JPA Entity (or Hibernate or whatever other you use) with your JSF/CDI managed beans. One serves as Model and the other as model for the Controller in MVC. Refer to [What components are MVC in JSF MVC framework?](http://stackoverflow.com/q/5104094/1065197) – Luiggi Mendoza Mar 29 '13 at 14:37
  • @LuiggiMendoza ok i got your point, i think i shoul't be use this way. – Jimit Tank Mar 29 '13 at 14:44
  • @kolossus I don't think that this is a *good* separation of concerns, though it will of course work. I insist that such design is bad because of (1) essentially different layering, (2) not coherent lifecycles and (3) strong temptation to insert action methods, managed bean fields and placeholders, validators/converters, etc. which is obviously wrong. On the other hand this approach will potentially cause harder to spot concurrency database problems once again because of wrong code assembly. – skuntsel Mar 29 '13 at 14:52
  • In the end, you should end up with that entity during authorization process, when you get one from your data provider class, and that detached entity will be set in your session scoped managed bean. – skuntsel Mar 29 '13 at 14:55
  • @skuntsel thank you for you importent reply but just forget about the ManagedProperty, and please check this link and check blusC ans. http://stackoverflow.com/questions/6793351/difference-between-a-managed-bean-and-a-session-bean i think i used same way in .xhtml. – Jimit Tank Mar 29 '13 at 15:08
  • @skuntsel while you're right regarding separation of concerns, OP's current implementation is basically a dumb DTO, and if it stays as is, I don't see a problem. – kolossus Mar 29 '13 at 15:13
  • @JimitTank, add the `@ManagedBean` annotation and try again. At this point however, your bean is no longer a DTO, but a presentation component. – kolossus Mar 29 '13 at 15:14
  • The `UserDetail` class should have never had `@SessionScoped` to begin with... This is a design problem which have repercussions in long term discussions and programming issues like this one. – Luiggi Mendoza Mar 29 '13 at 15:25
  • @kolossus I don't see that OP uses DTO, but I do see him use a fullworthy JPA entity (which can not necessarily be in detached state). If you let it be managed by JSF, could you explain how would OP be able to interact with details of multiple users? Or, say, if a user tries to relogin with a wrong login-password pair, wouldn't he end up with null bean? These are the problems that arise solely on the premises of a wrong approach. – skuntsel Mar 29 '13 at 18:32
  • @skuntsel I did say that it's poor separation of concerns, but without qualifying that class as a managed bean, the class is a textbook [DTO](http://en.wikipedia.org/wiki/Data_transfer_object). I'm not defending the long-term issues (yes there will be many) As is, this is a DTO. :) – kolossus Mar 29 '13 at 18:50
  • 1
    @kolossus Agreed, and let's put an end to this conversation :) – skuntsel Mar 29 '13 at 18:54
  • 1
    @skuntsel lol. Agreed. – kolossus Mar 29 '13 at 18:55
  • `@ManagedProperty(value = "#{userDetail}")` when you use this did you try to use `@PostConstruct` as your bean is in request scoped? – SRy Mar 29 '13 at 20:56

2 Answers2

0

@SessionScoped has no effect without adding @ManagedBean . Also it wouldn't make sense because JSF will create an empty UserDetails bean.

Seems like you need to add a service there which pulls details from UserDetails Entity.

@RequestScoped
public class Authenticator implements Serializable {

    private static final long serialVersionUID = 1L;

    @ManagedProperty(value = "#{userService}")
    private UserService userService;

    public UserDetail getUser(long id){
        return  userService.getUser(id);
    }
}

If you are not using Spring then you can make your service application scoped ,

@ManagedBean
@ApplicationScoped
public  class UserService {

          public UserDetail getUser(long id){
                    return  em.createQuery("Select UserDetail .... where id ...");
          }    
}

Your service can be like below if you are using Spring,

     @Service
     public class UserService {            
          public UserDetail getUser(long id){
                    return  em.createQuery("Select UserDetail .... where id ...");
          }    
}

If you are using spring then you would need to add Spring EL resolver to resolve your spring service

<faces-config>
  <application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
  </application>
</faces-config>
Avinash Singh
  • 2,564
  • 1
  • 14
  • 20
  • I downvoted your answer because of the following ideas. 1. OP never stated he used Spring, nor did he add the spring tag to his question. Moreover, Spring-jSF integration requires more configuration parameters than you mentioned. 2. IMHO it was an eagle-eye spotting of @kolossus that revealed the answer, though OP's approach needs thourough rethinking, to ny taste. – skuntsel Mar 29 '13 at 18:23
  • @skuntsel I never mentioned that OP is using a Spring , I said if you were using Spring you could implement that way otherwise the second approach already mentioned in the answer . What other configuration ar required for Spring-JSF integration if you are integrating Spring services in JSF? – Avinash Singh Mar 29 '13 at 18:26
  • You need to register two listener classes in web.xml to make Spring work. Regarding EL resolver you were right. But advising OP to use Spring in context of this question is the same as advising him to use, say, Struts, or raw servlet :) This is not what he was looking for. – skuntsel Mar 29 '13 at 19:04
  • @skuntsel Those listener classes are required to make Spring work with a web project and not JSF-Spring integration to work . Your comment about more configuration required for Sprnig-JSF integration is incorrect . I am not advising OP to use anything , I am merely suggesting how he can implement a service with or without Spring because at this point his service doesn't exist. – Avinash Singh Mar 29 '13 at 19:10
  • JSF is used as a part of a web application, so if OP were to use Spring as a middle tier, he would *need* to add those two listeners to make Spring part, and as a consequence, the general integration project, work, so your response is not logical :) Moreover, OP might be completely unaware of Spring, so mentioning that is as vital as mentioning the EL resolver for JSF. – skuntsel Mar 29 '13 at 19:58
  • Next, what you talk of resembles more a `Repository` class in Spring terms, or DAO in general terms, but not a service (that should be `@Transactional` in Spring). Finally, what you suggest as a return value for OP is a `Query` object, but definitely not an entity, so at the very least you must have added one more call to that. Also, your JPQL query could tempt OP to concatenate strings. – skuntsel Mar 29 '13 at 19:59
  • @skuntsel What I provided was a code snippet . Obviously you missed the point of my post. – Avinash Singh Mar 29 '13 at 22:49
0

As i can answer backed up only by my personal experience and if u still didn't resolved your problem after trying all answers u got in this post, i recommand u to go to Project--->clean if you are using Eclipse(i don't know for other IDEs). Actually, i had exactly the same problem and could resolve it only by this solution and still don't know the reason for which it happen.

Bardelman
  • 1,934
  • 6
  • 31
  • 60