The naive solution for non-JSF developers would be to simply initialize the variables inside the getter to resolve the null
value 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 caseAnneeMetier#getAllAnnees()
retrieves the data from database. This is explained here: Why JSF calls getters multipletimes
To solve this, you do two things:
And this would result in:
So the code would look like this:
@ManagedBean
@ViewScoped
public 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;
}
}
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 fromCagatay’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:
<!--
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" />
@Repository
public class AnneeHibernateDao implements AnneeDao{
//...
}
@Service
public class AnneeMetierImpl implements AnneeMetier{
@Autowired
private AnneeDao anneeDao;
//...
}
Compile your project and run it.