3

I'm curious about how to get JSF to only load certain business logic on page load and not run this code when I click a button (ActionEvent) or execute an AjaxBehaviorEvent.

My bean is in @RequestScoped, using JSF 2.1 and Primefaces.

Because the ActionEvent and AjaxBehaviorEvent are called afterwards I don't know how to tell the Bean in @PostConstruct that it is called because of the events.

Is it because of the bean placed in wrong scope?

Arian
  • 3,183
  • 5
  • 30
  • 58
  • Inject a ViewScoped bean which has the @PostConstruct code into your RequestScoped bean. There could be a better way. So wait... – Johny T Koshy Apr 09 '13 at 12:20
  • I got serious problems with ViewScoped. It always needs a serialized class which I find anoying ;) - additionally it causes sligth problems with 'java.sql' – Arian Apr 09 '13 at 12:22

2 Answers2

7

Only execute code on page load GET request

Just check in (post)constructor if FacesContext#isPostback() returns false.

@PostConstruct
public void init() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}

In the upcoming JSF 2.2 you can by the way use the new <f:viewAction> for this instead.

<f:viewAction action="#{bean.init}" onPostback="false" />

Is it because of the bean placed in wrong scope?

Depends on the concrete functional requirements. See also How to choose the right bean scope?


I got serious problems with ViewScoped. It always needs a serialized class which I find anoying ;) - additionally it causes sligth problems with 'java.sql'

This indicates a problem with your own code design rather than with the view scope. JDBC code doesn't belong in a JSF managed bean. JDBC resources like Connection, etc should never, never be declared as instance variables.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you for your detailed answer. I'll read into that however this will take some time now. Therefor I got another question now: Should I use JDBC with try-finally block inside the bean, or a separate class and call it from the bean (would this make any difference?)? Or is it better to switch to JPA or something similar? – Arian Apr 09 '13 at 12:38
  • First step would be to stop declaring JDBC resources as instance variables. That they're not serializable should already have been a sufficient hint that you did things the wrong way. What you do thereafter is up to you. Keep reusability, testability and maintainability in mind. Carefully read the linked post and all of its links. – BalusC Apr 09 '13 at 12:40
1

A RequestScoped bean is re-created on each request sent from client to server, that's why the logic in @PostConstruct is executed everytime you click a button, i think you should use a ViewScoped bean instead, which is created on each page load.

You can find a good tutorial about this subject written by BalusC on this link: http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#ManagedBeanScopes

Ozan Tabak
  • 662
  • 3
  • 9