Reputation: 14003
We're having problems with duplicate @PostConstruct
calls on a base class hierarchy.
Here's the base class first:
public abstract class AbstractManager<T> implements Serializable
{
private List<T> entities;
@PostConstruct // when annotated with @PostConstruct this method is called even if overridden in sub class
public void init()
{
System.out.println( AbstractManager.class.getSimpleName() + " @PostConstruct on " + this.getClass().getSimpleName() + "!" );
}
protected abstract List<T> getDbEntities();
public List<T> getEntities()
{
if ( this.entities == null )
{
this.entities = this.getDbEntities();
}
return this.entities;
}
public void setEntities( List<T> entities )
{
this.entities = entities;
}
public void clearEntities()
{
this.entities = null;
}
}
Here's the concrete sub class (notice how init() is overridden to call super.init()):
@Named
@ViewScoped
public class PseudoEntityManager extends AbstractManager<PseudoEntity>
{
private static final long serialVersionUID = 1L;
@Override
@PostConstruct
public void init()
{
super.init();
}
...
}
When some (unshown) page is rendered, the pseudoEntityManager
bean is instantiated, however @PostConstruct
is called twice. This is the output:
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: New list of pseudo DB entities!
When commenting the overriding init()
method in the concrete sub class so that there's only one @PostConstruct
method from the super class, the following output is generated:
INFO: AbstractManager @PostConstruct on PseudoEntityManager!
INFO: New list of pseudo DB entities!
Q:
What's the correct behavior according to CDI specification now? (references anybody?)
I also found this mailing list conversation while researching:
In the conversation, some gurus tend to say "only the @PostConstruct method on the sub class should be called". If you read closely, there's a link to a Weld bug that's said to be resolved since Weld 1.1.5:
https://issues.jboss.org/browse/WELD-1225
Has this really been fixed? According to the output I get, it's not.
Environment: Weld 1.1.8 along with Seam 3 to get the CDI @ViewScoped working correctly (on GlassFish 3.1.2).
Upvotes: 0
Views: 3014
Reputation: 28
This is a Workaround answer.
With the Bug mentioned both @PostConstruct annotation are considered, and their logic code is executed.
to workaround this is possible to do as following:
As result you will have only executed the code marked @PostConstruct on your subclass:
@Specializes
@ViewAccessScoped
public class BaseBean extends SubBean {
@PostConstruct
public void postConstructExtension() {
LOGGER.info("POST CALLED ON SPECIALIZED CLASS" + this.getClass().getSimpleName());
}
@Override
public void postConstruct() {
LOGGER.info("OVERRIDDEN POST CALLED ON SPECIALIZED CLASS" + this.getClass().getSimpleName());
}
}
Upvotes: 1
Reputation: 11723
Yes, it's been fixed. Unfortunately, it's only fixed in the Weld 2.0 release line. Sometimes these bugs get back ported, but unfortunately I doubt this one will end up being resolved in the maintenance releases.
Upvotes: 1