0

I have made a web application. In my first version I used one @ManagedBean with @SessionScoped annotation. But after I put some features to the web application I had too much methods in my managed bean. So I shared the Bean in six Beans with a @SessionScope. The problem is, if I used the first managed bean call LoginBean. I have no problems. But after I changed on the next page called SampleForDB. For this page I used the SampleBean. In this manged bean (SampleBean) the values of the classes I set in the loginBean are null.

How can I made it to use the values in all @MangedBean classes?

@ManagedBean
@SessionScoped
public class Example{

   private TestClass test = new TestClass();

   public next(){
      test.setmyVar(5);
   }
}


@ManagedBean
@SessionScoped
public class Example2{
   int testInt;
   private TestClass test = new TestClass();

   public after(){
      int testInt = test.getmyVar(); // I get null
   }
}


public class TestClass{
   private int myVar;

   public void setMyVar(int var){
      this.myVar = var;
   }

   public int getMyVar(){
      return myVar;
   }
}

This is an example for my Problem. My variable myVar is empty when I want to get it work in another Managed Bean.

senyor
  • 332
  • 4
  • 9
marius0114
  • 145
  • 4
  • 18

2 Answers2

0

You probably don't need to use so many managed beans. Just use one managed bean and include other classes in it. One managed bean per JSF page.

As you provided the code for you question: the problem is that you have two different instances of your TestClass. So when you set value in first instance it doesn't set in the second. That's why you get null there. What you should do is to share the same object instance between different managed beans. It can be done different ways:

  • Put your TestClass in session context in first managed bean and retrieve it from context in the second managed bean.
  • Apply singleton pattern and get the same instance with .getInstance() method.
  • When you created the instance of TestClass in the first managed bean, set the same value for the second managed bean from the first one.
  • Use dependency injection mechanism in your application (CDI or Spring).
  • Mark your TestClass as @ManagedBean with @SessionScoped or @ApplicationScoped and then use in other of your beans by injecting it as managed property @ManagedProperty("#{testClass}") TestClass testClass; Instead of @ManagedProperty you can directly use method FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get("testClass"); to retrieve your application scoped managed bean (for session scoped bean use .getSessionMap(). method instead). If you wish so you can additionally initialize TestClass with @PostConstruct annotation.
senyor
  • 332
  • 4
  • 9
  • Thank you. But i used one managed Bean per JSF page. If i klick on the Button to navigate on the next page with another manged Bean i lost the value in my classes. Like String, List, etc. The Button i used a defined in the specific mangaged Bean from the page. – marius0114 Feb 28 '14 at 06:53
  • i used the `@MangedProperty` to share the MangedBean e.g. the methods. This works fine!. My new Prolbem is to share the class. You write i must use the session context. Can i use a Syntax like `@MangedProperty` für my TestClass to get the variable in the secon managed bean? – marius0114 Feb 28 '14 at 16:10
  • I solved the problem when i save the values in my mangedBean. And get the mangedBean the `@MangedProperty`. But it must be a better solution. – marius0114 Feb 28 '14 at 16:25
  • The TestClass is my view-Klass. Is it okay to set the `@MangedBean` with `@SessionScoped` in this class? – marius0114 Feb 28 '14 at 16:42
  • It depends on how you implement your logic. If it is `@ViewScoped` then don't use `@ManagedProperty` and use method invocation from FacesContext as I proposed in answer. – senyor Feb 28 '14 at 16:45
  • Thank you. So i used `FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("testClass");` to get the instance of my Testclass. I write this the Exmample 2. correct? – marius0114 Feb 28 '14 at 18:15
  • i write this in my managed bean were i want the data from the TestClass. i set the data in another managed bean `private Object myMap = new Object(); setMyMap(FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("TestClass")); System.out.println("Das habe ich ausgelesen : "+ getMyMap()); //ist null` – marius0114 Feb 28 '14 at 18:30
  • Be careful with the names in context - usually it should start with lowercase letter "testClass" in you case. – senyor Feb 28 '14 at 18:45
  • Have you annotated your TestClass with `@ManagedBean` and `@SessionScoped` annotations? – senyor Feb 28 '14 at 18:59
  • No, because the TestClass has only Values and the Getter and Setter-Methods. I thniked only the Manged Beans are annotated, not the view-classes. I'm wrong? – marius0114 Feb 28 '14 at 19:28
  • Managed beans are used as dependency injection mechanism - you could use CDI of Java or Spring Beans instead. So first you need a bean to initialize and then inject it into another bean. – senyor Feb 28 '14 at 19:30
  • Thank you. I have choose `@MangedBean` for testing. And with `@MangedBean` it works. Wich Annotation did i need for the TestClass? Have you a link or referenz as example for CDI of Java? – marius0114 Feb 28 '14 at 20:17
  • Try Oracle [tutorial](http://docs.oracle.com/javaee/7/tutorial/doc/cdi-basic.htm). – senyor Feb 28 '14 at 20:57
0

There's no SampleBean or LoginBean in your code sample, but your problem is caused by the new operator in any case.

Using new to get @ManagedBean instances tells JSF "hey, I don't need to manage those objects". Each time JSF constructs a new java object from Example2 it'll also create a new TestClass instance. To access your existing bean, use something like this:

@ManagedBean @SessionScoped
public class LoginBean implements Serializable {
    private String userLogin;

    public void doLogin() { /* assign userLogin */ }
}

@ManagedBean @SessionScoped
public class SampleBean implements Serializable {
    @ManagedProperty("#{loginBean.userLogin}")
    private String login;
    private String greeting;

    public void sayHello() {
        greeting = "Hello " + login;
    }
}

You typically don't want a full bean injected somewhere, concentrate on the attributes you really need to get the job done.

Recommended reading:

JavaEE tutorial

How to choose the right bean scope?

Community
  • 1
  • 1
mabi
  • 5,279
  • 2
  • 43
  • 78
  • Thank you. Can i injected the same bean in two diffrent sampleBeans. And wehn i did this. Can i have the same value. My problem ist: i have a database instanz from mongoDB. Like private DB db. in one Bean-Class. And i need this in all other MangedBean. But when in write @MangedProperty("#{loginBean.DB}"). I have the db instanz in the first manage bean, but in the second i have null. – marius0114 Feb 28 '14 at 13:23
  • @marius0114 a database resource should not be shared with a `@ManagedBean` anyway. Those are used for storing values and actions you need in your frontend code. Providing resources (such as a database connection) is the job of your container and/or EJBs. I suggest writing a new question if you're still stuck after reading the tutorial link I posted. – mabi Feb 28 '14 at 13:36
  • i fixed the problem. But now i have a nother problem. I open the the @MangedBean a function in nother class and want to use the @MangedProperty("#{loginBean.DB}"). But if variable is null. How can i use a @MangedProperty if i go to the class with a mehtod request. The Class is called CollectionBean. And i get the class in my Login Bean with the code `private CollectionBean collection = new CollectionBean();` . ilso edit the Getter and Setter Methods in the LoginBean for the CollectionBean. – marius0114 Feb 28 '14 at 14:14
  • Okay. If i dont share the database resouce with the frontend i must share the function from my managedbean with the frontend. Right? Can i made the @MangedProperty in my abstract class and extend this my other managed beans? – marius0114 Feb 28 '14 at 14:21