cancel
Showing results for 
Search instead for 
Did you mean: 

HCP CDI and statefullness of @stateless beans

Former Member
0 Kudos

Hi all,

i probably miss something, but i am curios anyhow.

I have a webfilter which uses CDI to inject some beans. All of those beans are stateless. To my understanding that would mean they are request scoped but they seems to be session scoped.

According to "the internet" it depends on the container. Could maybe someone shed some light on how stateless beans are handled in HCP? and is there a way to make them request scoped? I tried but did only produce dumps

regards

Mathias

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Mathias!

I think you are misunderstanding what @Stateless means. From the EJB spec we can read:

"Stateless session beans are session beans whose instances have no conversational state..... Because all instances of a stateless session bean are equivalent, the container can choose to delegate a client-invoked method to any available instance. This means, for example, that the container may delegate the requests from the same client within the same transaction to different instances, and that the container may interleave requests from multiple transactions to the same instance. "


This means that the EJB container is NOT required to create a new instance on each request. Also it means that you must NOT store any state-full data in the instance variables, because it is not guaranteed that the next business method call will be executed on the same instance. You can use a @PostConstruct method to reset all residual state of teh bean, but still - DO NOT USE instance fields to store STATE in a stateless bean.

Former Member
0 Kudos

Hi Svetlin,

thank you very much for that clarification, you are totally right I completely misunderstood the concept of an stateless bean. So in my case(where i need to store data) i should use statefull beans and set the scope accordingly.

Again, thanks this space in SCN is proving more and more helpful and the speed of replies is astonishing

have a nice weekend

Answers (2)

Answers (2)

Former Member
0 Kudos

Hi guys,

sorry i need to open this up again i seriously tried to understand what is going on, tried to read the specs, googled and failed.

If you clone the above mentioned repo there is an other test case.

the "statelessbean.class" is annotated @statefull and behaving like expected.

now i do a bean lookup via beanmanager and get a reference of that Bean which does work well.

But what makes me really wonder: while the injected bean in the servlet is counting up as it should be, the reference acquired via beanmanger always starts from 0, so i guess that every time a new instance is created.

When i annotate the bean with sessionscoped everything is working fine, but only with statefull, the result is at least to me unexpected.

Could one of you verify if that behavior is correct and maybe enlighten me as well, after that i promise i won't ask a CDI question for the rest of the month

Regards

Mathias

Former Member
0 Kudos

Hi!

From the spec we can read that "Every invocation of the get() operation of the Context object for the @Dependent scope with a CreationalContext returns a new instance of the given bean." (There was a better explanation somewhere in the spec but I lost it and couldn't find it later, so might want to look it up for more details). This means that every time you look up a @Dependant scoped object a new instance will be created.

So, what is @Dependant - If you do not explicitly provide CDI scope for your beans, the default one (@Dependent) will be used. This means that the bean life cycle will be bound to the life cycle of the bean in which it is injected (maybe even the very instance will be injected and will not be proxied, but I have to check that).

So in your demo project, the bean is injected *once* when the servlet is created and hence each request to it goes to the same bean instance, (In fact this might be quite dangerous/not what you wanted as a developer because the servlet instance might be alive as long the application is alive and thus effectively creating an "application scoped" bean, although it is not a true @ApplicationScoped one. You can verify that by refreshing the web page of your application using multiple browser - they will all increment the very same instance!!!) while you create a new instance on each getReference() invocation.

So as a rule of thumb you should remember, that you should always define the CDI scope of @Stateful beans and be careful when injecting them into components with no scope like servlets.

PS: Chapter 5. Scopes and contexts :

An instance of a dependent bean is never shared between different clients or different injection points. It is strictly a dependent object of some other object. It is instantiated when the object it belongs to is created, and destroyed when the object it belongs to is destroyed.

....

Beans with scope @Dependent don’t need a proxy object. The client holds a direct reference to its instance.

Kind regards,

Svetlin

Former Member
0 Kudos

Thank you very much!

lazar_kirchev
Explorer
0 Kudos

Hi Mathias,

Could you explain in more details what is your scenario and probably give some sample application to reproduce?

Regards,

Lazar

Former Member
0 Kudos

Hi Lazar,

i createed a little test project. please clone mathiasmaerker/test-cdi-stateless · GitHub

when you call http://localhost:8080/test-cdi-stateless you will get the value 1, any further subsequent call to http://localhost:8080/test-cdi-stateless/test

will increment the counter, that is confusing for me, because i thought stateless does mean request scoped but the behavior indicates statefullness.

Thanks for your help.

Regards Mathias

Former Member
0 Kudos

funny side question: Why is CDI working at all? i forgot to insert a beans.xml?

lazar_kirchev
Explorer
0 Kudos

Hi Mathias,

In the server the CDI is enabled by default, that is why it searches for beans even without the beans.xml.

Regards,

Lazar

Former Member
0 Kudos

nevertheless i found a situation where it is absolutly neccesary to provide a beans.xml. I tried to use a producer with an Injectionpoint and without beans xml. i always got an

UnsatisfiedResolutionException.