简体   繁体   中英

Elegant handling of attributes without a session bean

I'm working on an application using JSF 2.0 and Richfaces 4, that consists of many tables that display elements and of course, the usual View/Edit/Delete options. After some SO browsing and Google search I've decided to post a question because the answers I found did not solve my problem.

Right now, and going straight to the point, my application is having issues when handling certain attributes that are stored in request beans and, on certain points, are lost due to successive requests.

For example, when I want to edit an object, the object is sent (f:propertyActionListener) to a request bean that displays the data on a form, then it is discarded as that request ends. When saving, a new object is created and the attributes on the form are setted to it and the item gets saved instead of updated, since it has no id (JPA + Hibernate).

I've investigated many options and this is what I've did so far and the results:

f:param + h:link or h:commandLink: With @ManagedProperty the param is null, and I can't find it on the Context to look it up through JNDI.

f:setPropertyActionListener + h:commandLink + Request Bean: Works... but I'm losing some data. The form that displays the data has some conditionally rendered fields and I can't hold that info, so the form is messed if the validation phase finds invalid data.

f:viewParam + h:commandLink + View Scoped Bean: Weird stuff here. This one doesn't directly work because the bean seems to get discarded before rendering the form, because the form is rendered with no information since the bean is clean.

Using a session bean: Works like a charm, but I don't want to make a session bean for every form just because I'm still learning things about the JSF lifecycle, I want to do it the proper way.

If I want to keep the Request session approach, is there a way to store a parameter (either an object or a plain string) and obtain later on a request bean?.

Dunno if this helps but I'm using a master page through ui:insert and ui:define.

Use a view scoped bean. It should work. The problems which you describe there suggests that you're binding it to JSTL tags or id or binding attributes. You should not do that on a view scoped bean. See also @ViewScoped fails in tag handlers . Another possible cause is that you're using CDI's @Named to manage the bean instead of JSF's @ManagedBean . That would also explain why @ManagedProperty doesn't work in one of your attempts as it also requires the bean to be managed by JSF's @ManagedBean .

As to the master-detail page approach, use a <h:link> with <f:param> in the table page to create view/edit links in the master page.

Eg user/list.xhtml

<h:dataTable value="#{userList.users}" var="user">
    <h:column>#{user.id}</h:column>
    <h:column>#{user.name}</h:column>
    <h:column>
        <h:link value="Edit" outcome="edit">
            <f:param name="id" value="#{user.id}" />
        </h:link>
    </h:column>
</h:dataTable>

The bean can be just request scoped.

Then, in the defail page, which is in this case an edit page, use <f:viewParam> to convert, validate and set the id as User .

Eg user/edit.xhtml

<f:metadata>
    <f:viewParam name="id" value="#{userEdit.user}"
        converter="#{userConverter}" converterMessage="Bad request. Unknown user."
        required="true" requiredMessage="Bad request. Please use a link from within the system." />
</f:metadata>

<h:messages />
<h:link value="Back to all users" outcome="users" />

<h:form id="user" rendered="#{not empty userEdit.user}">
    <h:inputText value="#{userEdit.user.name}" required="true" />
    ...

    <h:commandButton value="Save" action="#{userEdit.save}">
        <f:ajax execute="@form" render="@form" />
    </h:commandButton>
</h:form>

Use a @ViewScoped bean to hold the data, service and action methods:

@ManagedBean
@ViewScoped
public class UserEdit {

    private User user;

    @EJB
    private UserService service;

    public String save() {
        service.save(user);
        return "users";
    }

    // Getter+setter.
}

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