3

I have a JSF-managed session-scopped bean. It is also a spring component so that I can inject some fields:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.springframework.stereotype.Component;

@ManagedBean
@SessionScoped
@Component
public class EpgBean {...}

The problem is that the session is shared between users! If a user does some stuff and another user from another computer connects, he sees the SessionScoped data of the other user.

Is it due to the spring @Component which would force the bean to be a singleton? What is a correct approach to this matter?

kgautron
  • 7,915
  • 9
  • 39
  • 60
  • 2
    I don't use Spring, but you should theoretically get rid of those unused JSF managed bean annotations (as that would only confuse you; they are not been used at all if you use another framework to manage the beans) and add a Spring specific scope annotation, something like `@Scope("session")` or so (it indeed defaults to "application" scope, like as that JSF defaults to "none" scope when no JSF specific scope annotation is declared). – BalusC Jul 06 '12 at 12:18

2 Answers2

6

I solved the problem using spring scope annotation @Scope("session") instead of JSF @SessionScopped. I guess that since spring is configured as FacesEl resolver, it is spring scope that matters, while JSF scope is ignored.

kgautron
  • 7,915
  • 9
  • 39
  • 60
2

The approach I use is to keep the managed beans inside JSF container, and inject the Spring beans into them via EL on a managed property. See related question.

To do that, set up SpringBeanFacesELResolver in faces-config.xml, so JSF EL can resolve Spring beans:

<application>
    ...
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    ...
</application>

After that, you can inject Spring beans in your @ManagedBean annotated beans like this:

@ManagedBean
@ViewScoped
public class SomeMB {
    // this will inject Spring bean with id someSpringService
    @ManagedProperty("#{someSpringService}")
    private SomeSpringService someSpringService;

    // getter and setter for managed-property
    public void setSomeSpringService(SomeSpringService s){
        this.someSpringService = s;
    }
    public SomeSpringService getSomeSpringService(){
        return this.someSpringService;
    }
}

There may be better approachs than this, but this is what I've been using lately.

Community
  • 1
  • 1
Elias Dorneles
  • 22,556
  • 11
  • 85
  • 107
  • Thanks, I did not think about using the ManagedProperty. However I believe my original approach (declaring as spring component) is better, because you don't have to explicitly write the names of the injected beans through EL, as you can autowire them. – kgautron Jul 06 '12 at 12:19