The naive solution for non-JSF developers would be to simply initialize the
variables inside the getter to resolve the
nullvalue in the attributes.
This is:
public List getListeAnnees() { listeAnnees = getAnneeMetier().getAllAnnees(); return listeAnnees;}public AnneeMetier getAnneeMetier() { if (anneeMetier == null) { anneeMetier = new AnneeMetierImpl(); } return anneeMetier;}But this may generate lot of overhead from server in case
AnneeMetier#getAllAnnees()retrieves the data from database. This is
explained here: Why JSF calls getters multipletimes
To solve this, you do two things:
- Define the right scope of your bean.
- Initialize the necessary data for work using
@PostConstruct
annotated method.
And this would result in:
- Defining the scope as
@ViewScoped
(explained in the link above). - Initializing
listeAnnees
in@PostConstruct
method. - Remove any business logic from getters/setters
So the pre would look like this:
@ManagedBean@ViewScopedpublic class AnneeBean { private AnneeMetier anneeMetier; private List<Annee> listeAnnees; @PostConstruct public void init() { anneeMetier = new AnneeMetierImpl(); listeAnnees = anneeMetier.getAllAnnees(); } public List getListeAnnees() { return listeAnnees; } public void setListeAnnees(List listeAnnees) { this.listeAnnees = listeAnnees; } public AnneeMetier getAnneeMetier() { return anneeMetier; } public void setAnneeMetier(AnneeMetier anneeMetier) { this.anneeMetier = anneeMetier; }}BUT since you’re trying to integrate JSF with Spring, you have to take
into account that Spring has not yet full support of JSF 2
@ViewScoped
annotation. For this case, you
have/need to implement it yourself. There are plenty examples on the net about
this, and looks that the most popular is from
Cagatay’s. In this way, you’ll be able to gain power
from both sides. And your bean will look like this:
@Component@Scope("view")public class AnneeBean { @Autowired private AnneeMetier anneeMetier; private List<Annee> listeAnnees; @PostConstruct public void init() { listeAnnees = anneeMetier.getAllAnnees(); } public List getListeAnnees() { return listeAnnees; } public void setListeAnnees(List listeAnnees) { this.listeAnnees = listeAnnees; }}Since you’re learning Spring, the best bet would be to enable component scan
and use annotations to configure your spring beans. Do the following:
- Remove any bean configuration in applicationContext.xml.
- Add this configuration to enable bean scan annotations:
<!-- These will enable component scan by annotation configuration rather than XML configuration. One per package --> <context:component-scan base-package="dao" /> <context:component-scan base-package="model.services" />
Or if all your classes are inside one root package.
<!-- Assuming there's a root package for your packages like this<context:component-scan base-package="com.myproject.dao" /><context:component-scan base-package="com.myproject.model.services" />--><context:component-scan base-package="com.myproject" />
- Start configuring your Spring managed beans by annotations:
@Repository public class AnneeHibernateDao implements AnneeDao{ //... } @Service public class AnneeMetierImpl implements AnneeMetier{ @Autowired private AnneeDao anneeDao; //... }Compile your project and run it.



