2 Replies Latest reply: Aug 23, 2012 10:39 PM by Iván Pazmiño RSS

Inject from producer into JSF page

Iván Pazmiño Novice

Hello,

 

I'm trying to get a reference to an entity inside my backing bean filled with the info loaded into the JSF page.

Originally, this was working just fine with a @Model, but then my entity was not yet an entity.

 

@Model
public class User implements Serializable { }

@Request
@ManagedBean(name = "registration")
public class RegistrationBackingBean  {

  @Inject private User user;

  public String register() {
    registrar.register(user);
    return "/admin/dashboard?faces-redirect=true";
  }

}

 

registration.xhtml

...
<h:inputText id="name" value="#{user.name}" />
...
<h:commandButton id="register" value="#{labels.actionRegister}" action="#{registration.register}" />

 

But now user needs to be a @Entity and to be persisted. I just annotated it accordingly and had the errors related to making the same bean a @Model and a @Entity and ended up in this post. So, now User is an @Entity only.

 

As suggested in the post, I produced the User in a producer field but this caused the instance to be empty when the register() method in the backing bean was called.

 

@Request
@ManagedBean(name = "registration")
public class RegistrationBackingBean  {

  @Produces @Named private User user = new User(); 

  public String register() {
    registrar.register(user); // the reference doesn't have any of the valued entered in the JSF page
    return "/admin/dashboard?faces-redirect=true";
  }

}

 

I suppose this is because the JSF page is not getting the reference from this producer. To make this evident I moved the producer to amethod and had the produced instance named newUser and, as expected, the target was unreachable. The producer method was quelified so it would be distinguished from the entity.

 

@Entity
public class User implements Serializable { }

public class UserFactory {

    @Produces
    @RequestScoped
    @Named("newUser")
    @NewUser
    public User getUser() {
        return new User();
    }

}

@ManagedBean(name = "registration")
public class RegistrationBackingBean extends BaseBackingBean {

    private Object password;

    @Inject
    @NewUser
    private User user;

}

 

registration.xhtml

 

<h:inputText id="name" value="#{newUser.name}" />

 

WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (http--127.0.0.1-8080-1) /registration.xhtml @16,25 value="#{newUser.name}": Target Unreachable, identifier 'newUser' resolved to null: 
javax.el.PropertyNotFoundException: /registration.xhtml @16,25 value="#{newUser.name}": Target Unreachable, identifier 'newUser' resolved to null

 

How do I get the JSF page to reach the newUser produced at UserFactory?

  • 1. Re: Inject from producer into JSF page
    Martin Kouba Master

    First of all I would avoid mixing CDI and JSF2 beans. Whenever you have CDI (JSR 299) available use it instead... simply replace JSF2 @ManagedBean with CDI @Model qualifier.

     

    Also JSF2 managed beans do not support producers - that't why the producer field on RegistrationBackingBean did not work.

     

    However UserFactory is a regular CDI bean and thus the producer should theoretically work... Let's write some test for this.

     

    The simplest solution for your use-case would be to place user property and corresponding getter on RegistrationBackingBean so that you could use:

    <h:inputText id="name" value="#{registration.user.name}" />

    No further injection needed. If you require some initialization, use @PostConstruct callback. Otherwise you could also create a simple wrapper for credentials used on longin page...

  • 2. Re: Inject from producer into JSF page
    Iván Pazmiño Novice

    The two first lines where key. Now the factory is gone and the User is produced in a field inside the backing bean which drove to removing the NewUser qualifier.

    All this was possible by changing @ManagedBean with @Named (the scope was actually in a base class).

     

    Thank you very much.