简体   繁体   中英

seam action method executed twice?

I'm currently working on a seam project and have a problem.

I just created a new page (an xhtml called MyPage.xhtml). In xhtml my code you can find a command button and aa:repeater to display my data:

<!-- input fields that are filters for my table shown below -->
<h:commandButton value="View details" action="/MyPage.xhtml"/>

<rich:panel rendered=#{myAction.showDetails}>
    <a:repeat value="#{myAction.findRecords()}" var="record">
        <!-- Some of my code to display a table, nothing fancy -->
    </a:repeat>
</rich:panel>

in my action I have this:

@DataModel
private List<MyEntity> records = new ArrayList<MyEntity>();

public List<MyEntity> findRecords() {
    //Do some query
    Query query = entityManager.createNamedQuery("myEntityQuery");
    records = query.getResultList();
    return records;
}

This is how the page works:

  1. my input boxes and command button are shown, not the rich:panel as my showDetails boolean is false.
  2. When the showDetails boolean is set to true the panel is shown and the iterate calls my action method findRecords(). So far so good!
  3. But when I click my action button again the action method findRecords() is executed twice. And here's my problem...

Why should it be executed twice? How can I limit it to once? Now it costs us a lot of performance..!

Kr,

Dirk

Most probably the method is executed during view reconstruction (Restore view phase) and during rendering again (Render response phase).

Try to cache whether the method has been executed already or execute it only when clicking the button and provide a simple getter to deliver the data.

As a general note you should do costly operations like database queries only when needed (cache results) or during the invoke application phase (generally using action or actionListener )

i Would do something like this instead and use the Scopes to store the data. if you use a function like that in repeat it will access the method for each row in the repeat.

<h:commandButton value="View details" action="/MyPage.xhtml"/>

<rich:panel rendered=#{myAction.showDetails}>
    <a:repeat value="#{records}" var="record">
        <!-- Some of my code to display a table, nothing fancy -->
    </a:repeat>
</rich:panel>



@Out
private List<MyEntity> records = new ArrayList<MyEntity>();

@Factory(value="records")
public void findRecords() {
   //Do some query
   Query query = entityManager.createNamedQuery("myEntityQuery");
   records = query.getResultList();
}

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