简体   繁体   中英

ManagedProperty is not available

I have two ManagedBeans (SessionHandler and OrderHandler). Both are session scoped.

SessionHandler:

@ManagedBean(name="session")
@SessionScoped
public class SessionHandler {

    private Account account;

    public String login() {
        try {
            // ... login method ...

            return("bookinglist.xhtml?faces-redirect=true");
        }
        catch (Exception e) {
            // ... exception handling ...
        }
    }

    // ... getter & setter ...
}

OrderHandler:

@ManagedBean(name="order")
@SessionScoped
public class OrderHandler {

    @ManagedProperty(value="#{session.account}")
    Account account; // getter and setter

    public OrderHandler() {
        this.createList();
    }

    private void createList() {
        // method creates an ArrayList of bookings
        // it uses this.account.getId() for a SQL statement
    }
}

In bookinglist.xhtml I want to display a welcome text and my list:

<p>Welcome, #{sessions.account.name}!</p>

<ui:repeat value="#{order.bookingList}" var="item">
    <!-- ... items ... --->
</ui:repeat>

The welcome text is displayed, but my list is empty because in my sql statement the accountID is null. A statement with accountID = 1 (as example) works. Later in the booking process I can use the accountID (without doing anything to redeclare or overwrite it).

I guess the problem is, that the property isn't available immediately after the login... But I don't know why. Can someone help me?

When using @ManagedProperty , one important fact to keep in mind of is that such property will be injected once after bean constructor is called. The reason is because JSF can only inject a property when the bean is fully constructed.

In effect, it means that, from your current code, account will be injected after createList() is called. If you debug OrderHandler , you will very likely see the following execution sequence:

// bean instantiation step
-> OrderHandler constructor called
   -> createList called

// bean property injection step
-> Account injected

To solve this, you need to call createList() after constructor is finished, and account is already injected. You can achieve that with a method with @PostConstruct annotation:

@PostConstruct
private void init() {
    // this will be called after constructor call, and property injection
    this.createList();
}

You can read more about @PostConstruct annotation here:

http://docs.oracle.com/javaee/7/api/javax/annotation/PostConstruct.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM