When using CDI, it's tempting to be deceived by the convenience and annotation nature of the mechanism, but forget or ignore how it actually works. When things went wrong, strange behaviors occur, and I spent long time figuring out what went wrong. Here's my lessons learnt:
When doing this, make sure the observer is indeed "this". For example, when observer class is @Dependent scoped, when the event fires and an observer is needed, a new instance is created. Updating "this" is updating another object, which is not necessarily the desired object
For object OTHER THAN @Dependent scoped, a proxy is given to client, not the real object. When .equals() and .hashcode() will be used, (when bean will be put into collection) this is important. Best practice - "use business key"?
Also the actual bean will be constructed LATER, when it is actually used.
However when proxy is created, the bean constructor is invoked (because super() is invoked). Best practice is to leave constructor empty and do initialization in @PostConstruct method.
Not all class can be proxied - those without default public constructor, those has final method
- You need to be carful implementing equals() for normal scoped beans
Classes that implement equals by comparing fields directly in the equals() method may not work as expected, as the class will be inspecting the fields of the proxy, and not the bean instance.