0

I have two ManagedBeans.

Concerning my problem, they do the following:

First:

@ManagedBean public class Provider { private Event<ProvideEvent> event; private static boolean handling = false; public provide(@Observes ConsumeEvent consume){ if(!handling){ //provide some stuff event.fire(new ProvideEvent(ProvidedStuff stuff); } } } 

Second:

@ManagedBean @SessionScoped public class Consumer { private Event<ConsumeEvent> event; @PostConstruct public void initialize(){ event.fire(new ConsumeEvent()); } private static boolean handling = false; public consume(@Observes ProvideEvent providedStuff){ if(!handling){ //use the provided stuff } } } 

This happens, when the website is called: 1. Consumer is instantiated. 2. Consumer fires the event. 3. Provider is instantiated. 4. provide() is called. 5. A NEW CONSUMER IS INSTANTIATED 6. consume() is called.

As you can see, I had to use a boolean "handling" to keep the application from looping infinitly.

Why is the container not using the instantiated SessionScoped ManagedBean? I thought SessionScoped ManagedBeans are like Singleton for the Session? I guess I could work around this by: A: Using static variables for the changed properties. B: Implementing the Observer-Pattern manually.

But there has to be an easier way here!?

1 Answer 1

1

I believe the problem could be that you fire the event in the @PostConstruct method of your Customer.

From the javadocs:

This method MUST be invoked before the class is put into service.

As far as I understand, that results in a race condition. The Provider is probably firing the second event earlier than your Customer instance finishes executing initialize() and the container puts it into service. Hence, it won't receive the event. I'm too inexperienced with Java EE to give good advice how to prevent that race condition though. I would probably work around it with an ugly SynchronousQueue as a meeting point.

Additional info: the default with @Observes is to create a new instance of the event receiver if none exists (is in service). That's why another customer is created. Use @Observes(notifyObserver = Reception.IF_EXISTS) to only notify existing instances that are in service.

I thought SessionScoped ManagedBeans are like Singleton for the Session?

No, it just defines the lifetime of the object(s). It doesn't really enforce session-singleton behavior. The container would probably prefer the existing instance though, if it was in service at the time the second event is fired.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your help, I solved it now by implementing the Observer-Pattern by myself. But I will try if your approach works and get back to you.
I finally found time to reproduce the problem ;) You were right, it does create problems firing events from the @PostConstruct method. Thanks again for your help.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.